Skip to content
Permalink
Newer
Older
100644 126 lines (117 sloc) 4.06 KB
1
import React from 'react';
2
import Document, { Head, Main, NextScript } from 'next/document';
3
import getPageContext from 'docs/src/modules/styles/getPageContext';
4
import config from 'docs/src/config';
6
// You can find a benchmark of the available CSS minifiers under
7
// https://github.com/GoalSmashers/css-minification-benchmark
8
// We have found that clean-css is faster than cssnano but the output is larger.
9
// Waiting for https://github.com/cssinjs/jss/issues/279
10
// 4% slower but 12% smaller output than doing it in a single step.
11
//
12
// It's using .browserslistrc
13
let prefixer;
14
let cleanCSS;
15
if (process.env.NODE_ENV === 'production') {
16
const postcss = require('postcss');
17
const autoprefixer = require('autoprefixer');
18
const CleanCSS = require('clean-css');
19
20
prefixer = postcss([autoprefixer]);
21
cleanCSS = new CleanCSS();
22
}
23
24
class MyDocument extends Document {
25
render() {
26
const { canonical, pageContext } = this.props;
28
return (
29
<html lang="en" dir="ltr">
30
<Head>
31
{/*
32
Preconnect allows the browser to setup early connections before an HTTP request
33
is actually sent to the server.
34
This includes DNS lookups, TLS negotiations, TCP handshakes.
35
*/}
36
<link href="https://fonts.gstatic.com" rel="preconnect" crossOrigin="true" />
37
{/* Use minimum-scale=1 to enable GPU rasterization */}
38
<meta
39
name="viewport"
40
content={
41
'user-scalable=0, initial-scale=1, ' +
42
'minimum-scale=1, width=device-width, height=device-height'
43
}
44
/>
45
{/*
46
manifest.json provides metadata used when your web app is added to the
47
homescreen on Android. See https://developers.google.com/web/fundamentals/engage-and-retain/web-app-manifest/
48
*/}
49
<link rel="manifest" href="/static/manifest.json" />
50
{/* PWA primary color */}
51
<meta name="theme-color" content={pageContext.theme.palette.primary.main} />
52
<link rel="shortcut icon" href="/static/favicon.ico" />
53
<link rel="canonical" href={canonical} />
54
<link
55
rel="stylesheet"
56
href="https://fonts.googleapis.com/css?family=Roboto:300,400,500"
57
/>
58
<style id="insertion-point-jss" />
59
</Head>
60
<body>
61
<Main />
62
{/* Global Site Tag (gtag.js) - Google Analytics */}
63
<script async src={`https://www.googletagmanager.com/gtag/js?id=${config.google.id}`} />
64
<script
65
// eslint-disable-next-line react/no-danger
66
dangerouslySetInnerHTML={{
67
__html: `
68
window.dataLayer = window.dataLayer || [];function gtag(){dataLayer.push(arguments)};
69
gtag('js', new Date());
70
`,
71
}}
72
/>
73
<NextScript />
74
<script async src="https://cdn.jsdelivr.net/docsearch.js/2/docsearch.min.js" />
75
</body>
76
</html>
77
);
78
}
79
}
80
81
MyDocument.getInitialProps = async ctx => {
82
// Resolution order
83
//
84
// On the server:
85
// 1. page.getInitialProps
86
// 2. document.getInitialProps
87
// 3. page.render
88
// 4. document.render
89
//
90
// On the server with error:
91
// 2. document.getInitialProps
92
// 3. page.render
93
// 4. document.render
94
//
95
// On the client
96
// 1. page.getInitialProps
97
// 3. page.render
98
99
// Get the context of the page to collected side effects.
100
const pageContext = getPageContext();
101
const page = ctx.renderPage(Component => props => (
102
<Component pageContext={pageContext} {...props} />
105
let css = pageContext.sheetsRegistry.toString();
106
if (process.env.NODE_ENV === 'production') {
107
const result1 = await prefixer.process(css, { from: undefined });
108
css = result1.css;
109
css = cleanCSS.minify(css).styles;
112
return {
113
...page,
114
pageContext,
115
canonical: `https://material-ui.com${ctx.req.url.replace(/\/$/, '')}/`,
116
styles: (
117
<style
118
id="jss-server-side"
119
// eslint-disable-next-line react/no-danger
120
dangerouslySetInnerHTML={{ __html: css }}
121
/>
122
),
123
};
124
};
125
126
export default MyDocument;