DEV Community

Leandro Finger
Leandro Finger

Posted on

1

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.

Image of Datadog

Create and maintain end-to-end frontend tests

Learn best practices on creating frontend tests, testing on-premise apps, integrating tests into your CI/CD pipeline, and using Datadog’s testing tunnel.

Download The Guide

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.

Postmark Image

Speedy emails, satisfied customers

Are delayed transactional emails costing you user satisfaction? Postmark delivers your emails almost instantly, keeping your customers happy and connected.

Sign up