Next.js Discord

Discord Forum

SSR with styled-components

Unanswered
Brown bear posted this in #help-forum
Open in Discord
Brown bearOP
I am attempting to setup styled-components with SSR. I have wrapped {children} with the registry and I cannot discern any difference and have no idea if they're actually being SSR'd because if I take off the 'use client' lines on the styled components, it gripes at me that I'm trying to render server components on the client. Is this something I'm just going to have to assume is working correctly? Here's my layout.tsx and registry.tsx for reference.

layout.tsx
import React from 'react';

import GlobalStyle from '@/app/_ui/layouts/GlobalStyle';
import StyledComponentsRegistry from '@/lib/registry';

export default function RootLayout({
   children,
}: Readonly<{
   children: React.ReactNode;
}>) {
   return (
      <html lang="en">
         <body>
            <StyledComponentsRegistry>
               <GlobalStyle />
               {children}
            </StyledComponentsRegistry>
         </body>
      </html>
   );
}


registry.tsx
'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>
   );
}

1 Reply

Are you worried about the “use client” in the <StylesComponentsRegistry> to turn your app into a client component because it’s wrapping children?

If so, this does not happen, children will still be a server component by default, the React tree is rendered separately.

In fact, all components in Next.js are SSR by default, unless you import them dynamically and disable SSR.