To use Emotion with Next.js, you need to set up Emotion correctly to handle server-side rendering (SSR) and client-side hydration. The hydration error occurs when there is a mismatch between the styles rendered on the server side and the client side, leading to React warnings or errors.

Follow these steps to use Emotion with Next.js and avoid hydration errors:

  1. Install Dependencies:

    Install the required packages for Emotion and Next.js:

    npm install @emotion/react @emotion/server @emotion/styled emotion @emotion/babel-preset-css-prop
  2. Create a Custom Document:

    Next.js uses a custom _document.js file to handle the server-side rendering. Create the _document.js file in the pages directory if it doesn't exist and set it up as follows:

    // pages/_document.js import Document, { Html, Head, Main, NextScript } from 'next/document'; import { extractCritical } from '@emotion/server'; export default class MyDocument extends Document { static async getInitialProps(ctx) { const initialProps = await Document.getInitialProps(ctx); const styles = extractCritical(initialProps.html); return { ...initialProps, styles: ( <> {initialProps.styles} <style data-emotion-css={styles.ids.join(' ')} dangerouslySetInnerHTML={{ __html: styles.css }} /> </> ), }; } render() { return ( <Html> <Head /> <body> <Main /> <NextScript /> </body> </Html> ); } }

    This custom document setup captures the CSS generated by Emotion on the server side and injects it into the page as inline styles. This ensures that the same styles are used during server-side rendering and client-side hydration.

  3. Configure Babel:

    Ensure that you have the @emotion/babel-preset-css-prop preset configured in your .babelrc file or babel.config.js. This preset is needed to properly handle Emotion's css prop.

    Example .babelrc:

    { "presets": ["next/babel", "@emotion/babel-preset-css-prop"] }
  4. Wrap the pages/_app.js Component:

    In the _app.js file, wrap your Next.js app with the EmotionCacheProvider to handle client-side hydration:

    // pages/_app.js import { CacheProvider } from '@emotion/react'; import createCache from '@emotion/cache'; const cache = createCache({ key: 'css', prepend: true }); cache.compat = true; function MyApp({ Component, pageProps }) { return ( <CacheProvider value={cache}> <Component {...pageProps} /> </CacheProvider> ); } export default MyApp;

    Wrapping your app with CacheProvider ensures that the same Emotion cache is used during client-side rendering, preventing hydration errors.

Now, with Emotion set up correctly, you should be able to use Emotion's styling features in your Next.js components without encountering hydration errors. The server-side rendered styles will match the client-side hydrated styles, ensuring a smooth and consistent user experience.

Have questions or queries?
Get in Touch