-
Notifications
You must be signed in to change notification settings - Fork 17
/
document.ts
66 lines (52 loc) · 1.85 KB
/
document.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
/* eslint-env node */
// ^^^^ This comment is need to prevent browser bundles of this file
import type { DocumentContext } from 'next/document'
import Document from 'next/document'
import * as React from 'react'
import type { Configuration } from 'twind/server'
import { setup, asyncVirtualSheet, hash, getStyleTagProperties } from 'twind/server'
export type Constructor<T = object, S = object> = (new (...input: any[]) => T) & S
export default function withTwindDocument<
P = {},
Base extends Constructor<Document<P>, typeof Document> = typeof Document,
>(config?: Configuration, BaseDocument?: Base): Base
export default function withTwindDocument<
P = {},
Base extends Constructor<Document<P>, typeof Document> = typeof Document,
>(BaseDocument?: Base): Base
export default function withTwindDocument<
P = {},
Base extends Constructor<Document<P>, typeof Document> = typeof Document,
>(configOrBase?: Configuration | Base, BaseDocument?: Base): Base {
if (typeof configOrBase == 'function') {
BaseDocument = configOrBase
configOrBase = {}
}
const sheet = asyncVirtualSheet()
setup({ ...configOrBase, sheet })
// @ts-ignore
return class extends (BaseDocument || Document) {
static getInitialProps(ctx: DocumentContext) {
sheet.reset()
const originalRenderPage = ctx.renderPage
ctx.renderPage = async (options) => {
const { html, head = [] } = await originalRenderPage(options)
const { id, textContent } = getStyleTagProperties(sheet)
return {
html,
head: [
...head,
React.createElement('style', {
id: '__' + hash(textContent),
key: id,
dangerouslySetInnerHTML: {
__html: textContent,
},
}),
],
}
}
return super.getInitialProps(ctx)
}
}
}