Prevent FOUC on Next.js + Chakra UI
January 2022 Update: Previously, the demo for this post was using my previous iteration of my personal website. But since my website has been updated, I had to either publish the previous version just for this post or create a separate repo for demonstrating the FOUC (flash of unstyled content) (I chose the latter).
For some reason I cannot replicate the flashing issue.
Maybe it has been fixed for the latest Next.js or Chakra UI. Maybe I am using Next.js experimental configurations. I haven’t pinpoint the actual reason why. Both the site with cache and site without cache has the same behavior. Only the flashing when changing the last known theme occurs, which is known by the Chakra UI team.
So that means this post is somewhat invalid for my initial issue, but maybe it’ll be useful for some cases. I’ll keep this post for archival purposes and also update all references to the new repository and website.
If you’re using Chakra UI with Next.js, chances are that you’ll encounter an initial white flash or some parts still unstyled before the full content loads. This is known as FOUC (flash of unstyled content). Here’s an example of this website with the FOUC issue:
This happens because the Chakra UI stylesheets from <ChakraProvider />
are not loaded server-side and only client-side. The solution, since Chakra UI is based on Emotion, is to render the styles server-side and cache it using two additional Emotion packages, @emotion/cache
and @emotion/server
.
# using yarn
yarn add @emotion/cache @emotion/server# using npm
npm install @emotion/cache @emotion/server
After adding those dependencies, first make the Emotion cache instance, preferably on a separate source file, e.g. lib/emotion-cache.ts
(example source file for this website):
import createCache from "@emotion/cache";export default createCache({
key: "css",
});
Then, render the stylesheets in pages/_document.tsx
via Document.getInitialProps
and use the previously made cache instance with @emotion/server
's extractCritical
(example source file for this website):
With that, the page should now render the stylesheets both server-side and client-side. Here’s an example of this website after adding the solution:
TL;DR, use @emotion/cache
and @emotion/server
to prevent initial unstyled content. Theoretically this should also work on Next.js static exports if you're using next export
. You can see the full project for this website on GitHub.
Hope this helps! 🙌🏻
This was originally posted on my personal blog: https://griko.id/writings/prevent-fouc-on-next-js-chakra-ui