3

I'm working on a project at the moment which requires my components to react to frequently changing conditions on the client side, however NextJS 13 seems to be forcing server-side rendering as far as I can tell. I tried dynamic loading using import dynamic from 'next/dynamic'; and const Component = dynamic(() => import('@/components/Component/Component'), { ssr: false }); which I am loading all my subcomponents with but even still it seems to be rendering server-side.

There seems to be a lot of hydration issues trying to use Zustand store with persist mode since this is stored in the localStorage so the components often ignore the current state of the store indicating that it's trying to use the server-side store values. I am also trying to manage app-wide communications with WebSockets using console.logs to indicate outgoing and incoming messages. Outgoing messages console log to the browser console but incoming messages console.log to the terminal, again, indicating it's being rendered server-side. This is despite the component being loaded dynamically which should load them client side.

I'm totally stumped about what to do at the moment. I have considered ditching NextJS and just using React and Node but I really like Next and it's convenience of having everything you need ready to go out of the box but it's really annoying that I can't just tell it I don't want to use SSR for this project. Does anybody have any advice?

Marcus Horne
  • 363
  • 1
  • 5
  • 16
  • Same. Very annoying all documentation seems to be old regarding this stuff, or we both have one setting incorrect that's causing the issue. – GollyJer Mar 27 '23 at 21:31

2 Answers2

2

I've wrote this simple component

import dynamic from 'next/dynamic';

type ClientOnlyProps = { children: JSX.Element };
const ClientOnly = (props: ClientOnlyProps) => {
  const { children } = props;

  return children;
};

export default dynamic(() => Promise.resolve(ClientOnly), {
  ssr: false,
});

so by wrapping components like

<ClientOnly>{children}</ClientOnly>

your child components will not use ssr.

remember to add 'use client' as well.

Nathaniel
  • 501
  • 5
  • 9
  • Thanks, this answer helped me. I did the types a little different, maybe you find it useful: `import dynamic from "next/dynamic" import { FunctionComponent, PropsWithChildren } from "react" const ClientOnly: FunctionComponent = ({ children }) => children export default dynamic(() => Promise.resolve(ClientOnly), { ssr: false, })` – Lisandro Pastinante Jul 13 '23 at 13:28
0

Expanding on the answer above:

import dynamic from "next/dynamic"
import { FunctionComponent, PropsWithChildren } from "react"

const ClientOnly: FunctionComponent<PropsWithChildren> = ({ children }) => children

export default dynamic(() => Promise.resolve(ClientOnly), {
    ssr: false,
})