aliaset
Version:
twind monorepo
56 lines (46 loc) • 1.59 kB
text/typescript
/* eslint-env node */
import type { DocumentContext, DocumentInitialProps } from 'next/document'
import { createElement, Fragment } from 'react'
import Document from 'next/document'
import { extract } from '@twind/core'
export default install
function install(): typeof Document
function install<Component extends typeof Document = typeof Document>(
DocumentComponent: Component,
): Component
function install<Component extends typeof Document = typeof Document>(
BaseComponent: Component = Document as Component,
): Component {
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
return class TwindDocument extends BaseComponent {
static getInitialProps(
ctx: DocumentContext & {
defaultGetInitialProps: (
ctx: DocumentContext,
options?: { nonce?: string },
) => Promise<DocumentInitialProps>
},
) {
const defaultGetInitialProps = ctx.defaultGetInitialProps.bind(ctx)
ctx.defaultGetInitialProps = async (ctx, options: { nonce?: string } = {}) => {
const props = await defaultGetInitialProps(ctx, options)
const { html, css } = extract(props.html)
const styles = createElement(
Fragment,
null,
createElement('style', {
'data-twind': '',
nonce: options.nonce,
dangerouslySetInnerHTML: {
__html: css,
},
}),
props.styles,
)
return { ...props, html, styles }
}
return BaseComponent.getInitialProps(ctx)
}
}
}