Home Blog Talks

Avoiding Ant Design Style Flash in React Router v7 Framework / Remix

2025-01-28

The new version of React Router has merged with Remix, becoming React Router v7 Framework.

Projects that were previously based on React Router SPA can now use SSR technology to improve loading speed.

However, when using Ant Design, we encounter a flash of unstyled content issue due to CSS lazy loading.

The solution is to modify the App component in root.tsx to generate inline styles using @ant-design/cssinjs.

import {
  Outlet,
  useLocation,
} from 'react-router'
import { createCache, StyleProvider, extractStyle } from '@ant-design/cssinjs'
import { renderToString } from 'react-dom/server'
import type Entity from '@ant-design/cssinjs/lib/Cache'
import { useEffect, useInsertionEffect, useState } from 'react'

const CssCache = new Map<string, Entity>()

export default function App() {
  const location = useLocation()
  const pathname = location.pathname
  const isServer = typeof document === 'undefined'
  const cache = CssCache.get(pathname) || createCache()
  const [serverCss, setServerCss] = useState<string | null>(null)

  useInsertionEffect(() => {
    if (!CssCache.has(pathname)) {
      CssCache.set(pathname, cache)
    }
  }, [pathname, cache])

  useEffect(() => {
    if (isServer) {
      if (serverCss !== null) return

      renderToString(<StyleProvider cache={cache}>
        <Outlet />
      </StyleProvider>)

      const css = extractStyle(cache)
      setServerCss(css)
    } else {
      setServerCss('')
    }
  }, [pathname])

  if (serverCss === null) return null

  return (
    <>
      <style dangerouslySetInnerHTML={{ __html: serverCss }} />
      <Outlet />
    </>
  )
}
Back to all posts