|
1 | | -import * as React from 'react'; |
2 | | -import Script from 'next/script'; |
3 | | -import { documentGetInitialProps } from '@mui/material-nextjs/v13-pagesRouter'; |
4 | | -import { ServerStyleSheet } from 'styled-components'; |
5 | | -import Document, { Html, Head, Main, NextScript } from 'next/document'; |
6 | | -import GlobalStyles from '@mui/material/GlobalStyles'; |
7 | | -import MuiInitColorSchemeScript from '@mui/material/InitColorSchemeScript'; |
| 1 | +import NextDocument from 'next/document'; |
| 2 | +import { Document as MuiDocsDocument, createGetInitialProps } from '@mui/docs/Document'; |
8 | 3 | import JoyInitColorSchemeScript from '@mui/joy/InitColorSchemeScript'; |
9 | | -import { pathnameToLanguage } from '@mui/docs/helpers'; |
10 | | -import createEmotionCache from '@mui/docs/createEmotionCache'; |
11 | | -import { getMetaThemeColor } from '@mui/docs/branding'; |
12 | | -import { fontClasses } from '@mui/docs/nextFonts'; |
13 | 4 |
|
14 | | -const PRODUCTION_GA = |
15 | | - process.env.DEPLOY_ENV === 'production' || process.env.DEPLOY_ENV === 'staging'; |
| 5 | +export default class MuiDocument extends NextDocument { |
| 6 | + static getInitialProps = createGetInitialProps({ setupStyledComponents: true }); |
16 | 7 |
|
17 | | -const GOOGLE_ANALYTICS_ID_V4 = PRODUCTION_GA ? 'G-5NXDQLC2ZK' : 'G-XJ83JQEK7J'; |
18 | | -const APOLLO_TRACKING_ID = PRODUCTION_GA ? '691c2e920c5e20000d7801b6' : 'dev-id'; |
19 | | - |
20 | | -export default class MyDocument extends Document { |
21 | 8 | render() { |
22 | | - const { canonicalAsServer, userLanguage } = this.props; |
23 | | - |
24 | 9 | return ( |
25 | | - <Html lang={userLanguage} data-mui-color-scheme="light" data-joy-color-scheme="light"> |
26 | | - <Head> |
27 | | - {/* |
28 | | - manifest.json provides metadata used when your web app is added to the |
29 | | - homescreen on Android. See https://developers.google.com/web/fundamentals/engage-and-retain/web-app-manifest/ |
30 | | - */} |
31 | | - <link rel="manifest" href="/static/manifest.json" /> |
32 | | - {/* PWA primary color */} |
33 | | - <meta |
34 | | - name="theme-color" |
35 | | - content={getMetaThemeColor('light')} |
36 | | - media="(prefers-color-scheme: light)" |
37 | | - /> |
38 | | - <meta |
39 | | - name="theme-color" |
40 | | - content={getMetaThemeColor('dark')} |
41 | | - media="(prefers-color-scheme: dark)" |
42 | | - /> |
43 | | - <link rel="icon" href="/static/favicon.ico" /> |
44 | | - {/* iOS Icon */} |
45 | | - <link rel="apple-touch-icon" sizes="180x180" href="/static/icons/180x180.png" /> |
46 | | - {/* SEO */} |
47 | | - <link |
48 | | - rel="canonical" |
49 | | - href={`https://mui.com${ |
50 | | - userLanguage === 'en' ? '' : `/${userLanguage}` |
51 | | - }${canonicalAsServer}`} |
52 | | - /> |
53 | | - <link rel="alternate" href={`https://mui.com${canonicalAsServer}`} hrefLang="x-default" /> |
54 | | - <GlobalStyles |
55 | | - styles={{ |
56 | | - // First SSR paint |
57 | | - '.only-light-mode': { |
58 | | - display: 'block', |
59 | | - }, |
60 | | - '.only-dark-mode': { |
61 | | - display: 'none', |
62 | | - }, |
63 | | - // Post SSR Hydration |
64 | | - '.mode-dark .only-light-mode': { |
65 | | - display: 'none', |
66 | | - }, |
67 | | - '.mode-dark .only-dark-mode': { |
68 | | - display: 'block', |
69 | | - }, |
70 | | - // TODO migrate to .only-dark-mode to .only-dark-mode-v2 |
71 | | - '[data-mui-color-scheme="light"] .only-dark-mode-v2': { |
72 | | - display: 'none', |
73 | | - }, |
74 | | - '[data-mui-color-scheme="dark"] .only-light-mode-v2': { |
75 | | - display: 'none', |
76 | | - }, |
77 | | - '.plan-pro, .plan-premium': { |
78 | | - display: 'inline-block', |
79 | | - height: '0.9em', |
80 | | - width: '1em', |
81 | | - verticalAlign: 'middle', |
82 | | - marginLeft: '0.3em', |
83 | | - marginBottom: '0.08em', |
84 | | - backgroundSize: 'contain', |
85 | | - backgroundRepeat: 'no-repeat', |
86 | | - flexShrink: 0, |
87 | | - }, |
88 | | - '.plan-pro': { |
89 | | - backgroundImage: 'url(/static/x/pro.svg)', |
90 | | - }, |
91 | | - '.plan-premium': { |
92 | | - backgroundImage: 'url(/static/x/premium.svg)', |
93 | | - }, |
94 | | - }} |
95 | | - /> |
96 | | - </Head> |
97 | | - <body className={fontClasses}> |
98 | | - <MuiInitColorSchemeScript defaultMode="system" /> |
99 | | - <JoyInitColorSchemeScript defaultMode="system" /> |
100 | | - <Main /> |
101 | | - <script |
102 | | - // eslint-disable-next-line react/no-danger |
103 | | - dangerouslySetInnerHTML={{ |
104 | | - __html: ` |
105 | | -window.dataLayer = window.dataLayer || []; |
106 | | -function gtag(){dataLayer.push(arguments);} |
107 | | -window.gtag = gtag; |
108 | | -
|
109 | | -${/* Set default consent to denied (Google Consent Mode v2) */ ''} |
110 | | -gtag('consent', 'default', { |
111 | | - 'ad_storage': 'denied', |
112 | | - 'ad_user_data': 'denied', |
113 | | - 'ad_personalization': 'denied', |
114 | | - 'analytics_storage': 'denied', |
115 | | - 'wait_for_update': 500 |
116 | | -}); |
117 | | -gtag('set', 'ads_data_redaction', true); |
118 | | -gtag('set', 'url_passthrough', true); |
119 | | -
|
120 | | -gtag('js', new Date()); |
121 | | -gtag('config', '${GOOGLE_ANALYTICS_ID_V4}', { |
122 | | - send_page_view: false, |
123 | | -}); |
124 | | -
|
125 | | -${/* Apollo initialization - called by AnalyticsProvider when consent is granted */ ''} |
126 | | -window.initApollo = function() { |
127 | | - if (window.apolloInitialized) return; |
128 | | - window.apolloInitialized = true; |
129 | | - var n = Math.random().toString(36).substring(7), |
130 | | - o = document.createElement('script'); |
131 | | - o.src = 'https://assets.apollo.io/micro/website-tracker/tracker.iife.js?nocache=' + n; |
132 | | - o.async = true; |
133 | | - o.defer = true; |
134 | | - o.onload = function () { |
135 | | - window.trackingFunctions.onLoad({ appId: '${APOLLO_TRACKING_ID}' }); |
136 | | - }; |
137 | | - document.head.appendChild(o); |
138 | | -}; |
139 | | -
|
140 | | -${/* Check localStorage for existing consent and initialize if already granted */ ''} |
141 | | -(function() { |
142 | | - try { |
143 | | - var consent = localStorage.getItem('docs-cookie-consent'); |
144 | | - if (consent === 'analytics') { |
145 | | - window.initApollo(); |
146 | | - } |
147 | | - } catch (e) {} |
148 | | -})(); |
149 | | -`, |
150 | | - }} |
151 | | - /> |
152 | | - {/** |
153 | | - * A better alternative to <script async>, to delay its execution |
154 | | - * https://developer.chrome.com/blog/script-component/ |
155 | | - */} |
156 | | - <Script |
157 | | - strategy="afterInteractive" |
158 | | - src={`https://www.googletagmanager.com/gtag/js?id=${GOOGLE_ANALYTICS_ID_V4}`} |
159 | | - /> |
160 | | - <NextScript /> |
161 | | - </body> |
162 | | - </Html> |
| 10 | + <MuiDocsDocument {...this.props}> |
| 11 | + <JoyInitColorSchemeScript defaultMode="system" /> |
| 12 | + </MuiDocsDocument> |
163 | 13 | ); |
164 | 14 | } |
165 | 15 | } |
166 | | - |
167 | | -MyDocument.getInitialProps = async (ctx) => { |
168 | | - const styledComponentsSheet = new ServerStyleSheet(); |
169 | | - |
170 | | - try { |
171 | | - const finalProps = await documentGetInitialProps(ctx, { |
172 | | - emotionCache: createEmotionCache(), |
173 | | - plugins: [ |
174 | | - { |
175 | | - // styled-components |
176 | | - enhanceApp: (App) => (props) => styledComponentsSheet.collectStyles(<App {...props} />), |
177 | | - resolveProps: async (initialProps) => ({ |
178 | | - ...initialProps, |
179 | | - styles: [styledComponentsSheet.getStyleElement(), ...initialProps.styles], |
180 | | - }), |
181 | | - }, |
182 | | - ], |
183 | | - }); |
184 | | - |
185 | | - // All the URLs should have a leading /. |
186 | | - // This is missing in the Next.js static export. |
187 | | - let url = ctx.req.url; |
188 | | - if (url[url.length - 1] !== '/') { |
189 | | - url += '/'; |
190 | | - } |
191 | | - |
192 | | - return { |
193 | | - ...finalProps, |
194 | | - canonicalAsServer: pathnameToLanguage(url).canonicalAsServer, |
195 | | - userLanguage: ctx.query.userLanguage || 'en', |
196 | | - styles: [ |
197 | | - <style id="material-icon-font" key="material-icon-font" />, |
198 | | - <style id="font-awesome-css" key="font-awesome-css" />, |
199 | | - ...finalProps.emotionStyleTags, |
200 | | - <style id="app-search" key="app-search" />, |
201 | | - <style id="prismjs" key="prismjs" />, |
202 | | - ...React.Children.toArray(finalProps.styles), |
203 | | - ], |
204 | | - }; |
205 | | - } finally { |
206 | | - styledComponentsSheet.seal(); |
207 | | - } |
208 | | -}; |
0 commit comments