diff --git a/README.md b/README.md index e463524..84b1770 100755 --- a/README.md +++ b/README.md @@ -391,6 +391,101 @@ property limits styles to highlighted languages. When converting a Prism CSS theme it's mostly just necessary to use classes as `types` and convert the declarations to object-style-syntax and put them on `style`. +### SSR Support / Avoiding FOUC + +If your React app supports "light mode / dark mode" you need to do additional work to avoid a flash of unstyled content (FOUC). +Suppose you have the following application code: + +```jsx +import { useState, useEffect } from 'react'; +import Highlight from 'prism-react-renderer' +import duotoneDark from 'prism-react-renderer/themes/duotoneDark'; +import duotoneLight from 'prism-react-renderer/themes/duotoneLight'; + +const useTheme = () => { + const [theme, _setTheme] = useState(duotoneLight); + + useEffect(() => { + const colorMode = window.localStorage.getItem('color-mode'); + _setTheme(colorMode === 'dark' ? duotoneDark : duotoneLight); + }, []); + + const setTheme = (themeId) => { + if (themeId === duotoneLight.id) { + window.localStorage.setItem('color-mode', 'light'); + _setTheme(duotoneLight); + } + if (themeId === duotoneDark.id) { + window.localStorage.setItem('color-mode', 'dark'); + _setTheme(duotoneDark); + } + } + + return { theme, setTheme } +} + +const MyComponent = () => { + const { setTheme, theme } = useTheme(); + + return ( + <> + + // omitted for brevity + + + + + ) +} +``` + +You should generate the following script tag and inject it into your HTML so it runs _before_ your content loads. Note: **Do NOT copy/paste the following code.** Use it as a starting point and modify it to match your application's method of persisting theme state. + +```js +import Highlight, { generateScriptForSSR } from 'prism-react-renderer' +import duotoneDark from 'prism-react-renderer/themes/duotoneDark'; +import duotoneLight from 'prism-react-renderer/themes/duotoneLight'; + +const getThemeIdFuncStr = ` + () => ( + window.localStorage.getItem('color-mode') === 'dark' + ? '${duotoneDark.id}' + : '${duotoneLight.id}' + ); +`.trim() + +const codeToRunOnClient = generateScriptForSSR( + // Include whatever themes `getThemeIdFuncStr` might return + [duotoneDark, duotoneLight], + getThemeIdFuncStr +); + +// Gatsby +export const onRenderBody = ({ setPreBodyComponents }) => { + setPreBodyComponents( +