DEV Community

Leandro Finger
Leandro Finger

Posted on

Next.js hot-reload losing styled-components styles

It's been a while since I developed using React/Next.js for the last time, and I decided to start a side-project using Next.js 13 this week.

Back in time, I was used to using styled-components that in my opinion allows me to keep the styles separated from the component files (not inside the TSX) and also avoids the not desired CSS style override, which is common when you have a lot of CSS files spread all over your project.

After defining the base layout of my application and starting my app with next dev everything looked as usual. Although, after my first change, all my styles had gone when the application got hot-reloaded. I got confused, but I did remember to have heard something about some style changes in Next.js due to ServerSideRendering feature so I started googling. In my first search, I found a official link that explained how to fix that. Let's go to the solution:

Create the file lib/registry.tsx with the following content:

'use client';

import React, { useState } from 'react';
import { useServerInsertedHTML } from 'next/navigation';
import { ServerStyleSheet, StyleSheetManager } from 'styled-components';

export default function StyledComponentsRegistry({
  children,
}: {
  children: React.ReactNode;
}) {
  // Only create stylesheet once with lazy initial state
  // x-ref: https://reactjs.org/docs/hooks-reference.html#lazy-initial-state
  const [styledComponentsStyleSheet] = useState(() => new ServerStyleSheet());

  useServerInsertedHTML(() => {
    const styles = styledComponentsStyleSheet.getStyleElement();
    styledComponentsStyleSheet.instance.clearTag();
    return <>{styles}</>;
  });

  if (typeof window !== 'undefined') return <>{children}</>;

  return (
    <StyleSheetManager sheet={styledComponentsStyleSheet.instance}>
      {children}
    </StyleSheetManager>
  );
}
Enter fullscreen mode Exit fullscreen mode

After that, open your pages/_app.tsx file and make the following changes:

  1. Import the registry you've just created.
import StyledComponentsRegistry from '../lib/registry';
Enter fullscreen mode Exit fullscreen mode
  1. Wrap up the <Component {...pageProps} /> like below:
<StyledComponentsRegistry>
  <Component {...pageProps} />
</StyledComponentsRegistry>
Enter fullscreen mode Exit fullscreen mode

Finally, just stop your application and run next dev again.

Conclusion

Since I'm working in a side project that I know isn't going to use SSR I think that solution might be enough for me. Although, if you're working in a production application that uses a lot of SSR, please be careful.

Top comments (1)

Collapse
 
tharonuth profile image
Rothanouth

I find this blog helpful for me in understanding the concepts, but unfortunately, the provided solutions don't seem to work in .js.