|
1 | | -/* |
2 | | -This custom document is needed to workaround this bug in antd + nextjs: |
3 | | -
|
4 | | - https://github.com/ant-design/ant-design/issues/38767 |
5 | | -
|
6 | | -The actual fix -- i.e., this entire file -- comes from |
7 | | -
|
8 | | - https://github.com/ant-design/ant-design/issues/38767#issuecomment-1350362026 |
9 | | -
|
10 | | -which is for a different bug in antd + nextjs, but it happens to fix |
11 | | -the same problem, and fortunately also works with the older nextjs 12.x, which |
12 | | -we are currently stuck with. |
13 | | -
|
14 | | -See also the discussion at https://github.com/ant-design/ant-design/issues/39891 |
15 | | -*/ |
16 | | - |
| 1 | +// pages/_document.tsx |
17 | 2 | import type { DocumentContext, DocumentInitialProps } from "next/document"; |
18 | 3 | import Document, { Head, Html, Main, NextScript } from "next/document"; |
19 | | - |
20 | 4 | import { createCache, extractStyle, StyleProvider } from "@ant-design/cssinjs"; |
21 | | - |
22 | 5 | import { Locale } from "@cocalc/util/i18n"; |
23 | | - |
24 | 6 | import { query2locale } from "locales/misc"; |
25 | 7 |
|
26 | | -export default class MyDocument extends Document { |
27 | | - static async getInitialProps(ctx: DocumentContext): Promise< |
28 | | - DocumentInitialProps & { |
29 | | - locale: Locale; |
30 | | - } |
31 | | - > { |
| 8 | +export default class MyDocument extends Document<{ locale: Locale }> { |
| 9 | + static async getInitialProps( |
| 10 | + ctx: DocumentContext, |
| 11 | + ): Promise<DocumentInitialProps & { locale: Locale }> { |
32 | 12 | const locale = query2locale(ctx.query); |
33 | | - |
34 | 13 | const cache = createCache(); |
35 | 14 | const originalRenderPage = ctx.renderPage; |
36 | 15 |
|
37 | | - // The IntlProvider is only for english and all components with translations in the frontend |
38 | 16 | ctx.renderPage = () => |
39 | 17 | originalRenderPage({ |
40 | | - enhanceApp: (App) => (props) => |
41 | | - ( |
42 | | - <StyleProvider cache={cache}> |
43 | | - <App {...props} {...{ locale }} /> |
44 | | - </StyleProvider> |
45 | | - ), |
| 18 | + enhanceApp: (App: any) => (props: any) => ( |
| 19 | + <StyleProvider cache={cache} hashPriority="high"> |
| 20 | + <App {...props} locale={locale} /> |
| 21 | + </StyleProvider> |
| 22 | + ), |
46 | 23 | }); |
47 | 24 |
|
48 | 25 | const initialProps = await Document.getInitialProps(ctx); |
49 | 26 |
|
| 27 | + // inline critical AntD CSS as real <style> tags (no script hack) |
| 28 | + const css = extractStyle(cache, { plain: true, types: ["style", "token"] }); |
| 29 | + |
50 | 30 | return { |
51 | 31 | ...initialProps, |
52 | 32 | locale, |
53 | 33 | styles: ( |
54 | 34 | <> |
55 | 35 | {initialProps.styles} |
56 | | - {/* This is hack, `extractStyle` does not currently support returning JSX or related data. */} |
57 | | - <script |
58 | | - dangerouslySetInnerHTML={{ |
59 | | - __html: `</script>${extractStyle(cache)}<script>`, |
60 | | - }} |
| 36 | + <style |
| 37 | + // keep it obvious for debugging |
| 38 | + data-antd="cssinjs-ssr" |
| 39 | + // extractStyle returns complete <style> tags; that’s OK here |
| 40 | + // If you prefer only the CSS text, you can parse it, but this works well in practice. |
| 41 | + dangerouslySetInnerHTML={{ __html: css }} |
61 | 42 | /> |
62 | 43 | </> |
63 | 44 | ), |
64 | 45 | }; |
65 | 46 | } |
66 | 47 |
|
67 | | - // TODO: this "lang={...}" is only working for the very first page that's being loaded |
68 | | - // next's dynamic page updates to not have an impact on this. So, to really fix this, we |
69 | | - // probably have to get rid of this _document customization and update to version 15 properly. |
70 | 48 | render() { |
71 | 49 | return ( |
72 | 50 | <Html lang={this.props.locale}> |
|
0 commit comments