@@ -37,6 +37,17 @@ const ThemeContext = React.createContext<{
37
37
setNightScheme : ( ) => null
38
38
} )
39
39
40
+ // inspired from __NEXT_DATA__, we use application/json to avoid CSRF policy with inline scripts
41
+ const getServerHandoff = ( ) => {
42
+ try {
43
+ const serverData = document . getElementById ( '__PRIMER_DATA__' ) ?. textContent
44
+ if ( serverData ) return JSON . parse ( serverData )
45
+ } catch ( error ) {
46
+ // if document/element does not exist or JSON is invalid, supress error
47
+ }
48
+ return { }
49
+ }
50
+
40
51
export const ThemeProvider : React . FC < ThemeProviderProps > = ( { children, ...props } ) => {
41
52
// Get fallback values from parent ThemeProvider (if exists)
42
53
const {
@@ -49,11 +60,8 @@ export const ThemeProvider: React.FC<ThemeProviderProps> = ({children, ...props}
49
60
// Initialize state
50
61
const theme = props . theme ?? fallbackTheme ?? defaultTheme
51
62
52
- const resolvedColorModePassthrough = React . useRef (
53
- // eslint-disable-next-line @typescript-eslint/ban-ts-comment
54
- // @ts -ignore This custom variable does not exist on window because we set it ourselves
55
- typeof window !== 'undefined' ? window . __PRIMER_RESOLVED_SERVER_COLOR_MODE : undefined
56
- )
63
+ const { resolvedServerColorMode} = getServerHandoff ( )
64
+ const resolvedColorModePassthrough = React . useRef ( resolvedServerColorMode )
57
65
58
66
const [ colorMode , setColorMode ] = React . useState ( props . colorMode ?? fallbackColorMode ?? defaultColorMode )
59
67
const [ dayScheme , setDayScheme ] = React . useState ( props . dayScheme ?? fallbackDayScheme ?? defaultDayScheme )
@@ -119,7 +127,11 @@ export const ThemeProvider: React.FC<ThemeProviderProps> = ({children, ...props}
119
127
< SCThemeProvider theme = { resolvedTheme } >
120
128
{ children }
121
129
{ props . preventSSRMismatch ? (
122
- < script dangerouslySetInnerHTML = { { __html : `__PRIMER_RESOLVED_SERVER_COLOR_MODE='${ resolvedColorMode } '` } } />
130
+ < script
131
+ type = "application/json"
132
+ id = "__PRIMER_DATA__"
133
+ dangerouslySetInnerHTML = { { __html : JSON . stringify ( { resolvedServerColorMode : resolvedColorMode } ) } }
134
+ />
123
135
) : null }
124
136
</ SCThemeProvider >
125
137
</ ThemeContext . Provider >
0 commit comments