aboutsummaryrefslogtreecommitdiffstats
path: root/src/pages/_document.tsx
blob: 36e079835df511ecce0fe4006ebfea31b4ee6187 (plain)
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
import { Html, Head, Main, NextScript } from 'next/document';
import Script from 'next/script';
import {
  PRISM_THEME_ATTRIBUTE,
  STORAGE_KEY,
  VALID_THEMES,
} from '../utils/constants';

const validPrismThemesStr = VALID_THEMES.map((t) => `"${t}"`);

// eslint-disable-next-line @typescript-eslint/no-shadow -- Required by NextJs
export default function Document() {
  const defaultAttributes = {
    [`data-${STORAGE_KEY.MOTION}`]: 'false',
    [`data-${STORAGE_KEY.THEME}`]: 'light',
    [PRISM_THEME_ATTRIBUTE]: 'light',
  };

  return (
    <Html {...defaultAttributes}>
      <Head>
        <Script
          dangerouslySetInnerHTML={{
            __html: `!function(){const t=localStorage.getItem("${STORAGE_KEY.MOTION}"),e="string"==typeof t&&"true"===t;document.documentElement.setAttribute("data-${STORAGE_KEY.MOTION}",e)}();`,
          }}
          // eslint-disable-next-line react/jsx-no-literals
          id="motion-hydration"
          // eslint-disable-next-line react/jsx-no-literals
          strategy="beforeInteractive"
        />
        <Script
          dangerouslySetInnerHTML={{
            __html: `!function(){const e=localStorage.getItem("${STORAGE_KEY.THEME}"),t="string"==typeof e?JSON.parse(e):void 0,o=window.matchMedia("(prefers-color-scheme: dark)").matches?"dark":"light",c=e&&["dark","light"].includes(t)?t:o;document.documentElement.setAttribute("data-${STORAGE_KEY.THEME}",c),document.documentElement.style.colorScheme=o}();`,
          }}
          // eslint-disable-next-line react/jsx-no-literals
          id="theme-hydration"
          // eslint-disable-next-line react/jsx-no-literals
          strategy="beforeInteractive"
        />
        <Script
          dangerouslySetInnerHTML={{
            __html: `!function(){const t=localStorage.getItem("${STORAGE_KEY.PRISM}"),e="string"==typeof t?JSON.parse(t):void 0,s=e&&[${validPrismThemesStr}].includes(e)?e:"system";document.documentElement.setAttribute("${PRISM_THEME_ATTRIBUTE}",s)}();`,
          }}
          // eslint-disable-next-line react/jsx-no-literals
          id="prism-theme-hydration"
          // eslint-disable-next-line react/jsx-no-literals
          strategy="beforeInteractive"
        />
      </Head>
      <body>
        <Main />
        <NextScript />
      </body>
    </Html>
  );
}