Skip to content

Next.js Integration

StateMesh works with both Next.js App Router and Pages Router. All browser API access is SSR-guarded.

App Router

tsx
// providers.tsx
"use client";

import { StateMeshProvider } from "statemesh-core";
import { mesh } from "./mesh";

export function Providers({ children }: { children: React.ReactNode }) {
  return (
    <StateMeshProvider mesh={mesh}>
      {children}
    </StateMeshProvider>
  );
}
tsx
// app/layout.tsx
import { Providers } from "./providers";

export default function RootLayout({ children }: { children: React.ReactNode }) {
  return (
    <html>
      <body>
        <Providers>{children}</Providers>
      </body>
    </html>
  );
}

SSR Safety

All StateMesh features are SSR-safe:

  • isBrowser() guards all browser API access
  • URL state is SSR-guarded (no window access on server)
  • Persistence adapters check for localStorage/sessionStorage availability
  • Tab sync uses BroadcastChannel only in browser

Hydration

For SSR data transfer:

tsx
// Server component
export default async function Page() {
  const data = await fetchData();
  return (
    <>
      <script
        dangerouslySetInnerHTML={{
          __html: `window.__STATEMESH__ = ${JSON.stringify(data)}`
        }}
      />
      <ClientApp initialData={data} />
    </>
  );
}
tsx
// Client component
"use client";

export function ClientApp({ initialData }: { initialData: Data }) {
  // Hydrate on mount
  useEffect(() => {
    mesh.hydrate(initialData);
  }, []);

  return <AppContent />;
}

Important Notes

TIP

Create the mesh instance outside of React (module scope) to persist across re-renders in development.

WARNING

In Next.js App Router, components are server components by default. Add "use client" to components that use StateMesh hooks.

Next Steps

Released under the MIT License.