-
Notifications
You must be signed in to change notification settings - Fork 4
/
_document.tsx
116 lines (101 loc) · 3.21 KB
/
_document.tsx
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
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
import { ServerStyleSheets } from '@material-ui/core/styles';
import { compose } from 'compose-middleware';
import { IncomingMessage, ServerResponse } from 'http';
import nextI18NextMiddleware from 'next-i18next-serverless/dist/commonjs/middlewares/next-i18next-middleware';
import NextDocument, { DocumentContext, DocumentInitialProps, Head, Html, Main, NextScript } from 'next/document';
import React from 'react';
import { PathnameToLanguage, pathnameToLanguage } from '../docs/src/modules/utils/helpers';
import { Logger } from '../docs/src/modules/utils/logging';
import { NextI18NextInstance } from '../i18n';
const wrapI18n = (req: IncomingMessage, res: ServerResponse) => {
const middleware = compose(nextI18NextMiddleware(NextI18NextInstance));
const done = () => {
Logger.log('done');
};
middleware(req, res, _next => {
return done();
});
};
export const middleware = async ({ req, res }: DocumentContext) => {
await wrapI18n(req, res);
};
/* eslint-disable class-methods-use-this */
class MillipedeDocument extends NextDocument {
render() {
return (
<Html lang='en'>
<Head>
<meta charSet='utf-8' />
{/* Use minimum-scale=1 to enable GPU rasterization */}
<meta
name='viewport'
content='minimum-scale=1, initial-scale=1, width=device-width, shrink-to-fit=no'
/>
<link
rel='stylesheet'
href='https://fonts.googleapis.com/css?family=Roboto:300,400,500,700&display=swap'
/>
<link
rel='stylesheet'
href='https://fonts.googleapis.com/icon?family=Material+Icons'
/>
</Head>
<body>
<Main />
<NextScript />
</body>
</Html>
);
}
}
type InitialProps = PathnameToLanguage & DocumentInitialProps;
MillipedeDocument.getInitialProps = async (
ctx: DocumentContext
): Promise<InitialProps> => {
// Resolution order
//
// On the server:
// 1. app.getInitialProps
// 2. page.getInitialProps
// 3. document.getInitialProps
// 4. app.render
// 5. page.render
// 6. document.render
//
// On the server with error:
// 1. document.getInitialProps
// 2. app.render
// 3. page.render
// 4. document.render
//
// On the client
// 1. app.getInitialProps
// 2. page.getInitialProps
// 3. app.render
// 4. page.render
// Render app and page and get the context of the page with collected side effects.
const sheets = new ServerStyleSheets();
const originalRenderPage = ctx.renderPage;
const newCtx = {
...ctx,
renderPage: () =>
originalRenderPage({
enhanceApp: App => props => sheets.collect(<App {...props} />)
})
};
const initialProps = await NextDocument.getInitialProps(newCtx);
return {
...initialProps,
canonical: pathnameToLanguage(ctx.req.url).canonical,
userLanguage: ctx.query.userLanguage as string,
// Styles fragment is rendered after the app and page rendering finish.
styles: (
<React.Fragment>
{initialProps.styles}
{sheets.getStyleElement()}
</React.Fragment>
) as any
// styles: [...(initialProps.styles || []), sheets.getStyleElement()]
};
};
export default MillipedeDocument;