Skip to Content
snapgrid is a react-grid-layout v2 alternative built on dnd-kit. Drag, resize, repack, and drag between grids.
DocumentationGuidesServer-side rendering

Server-side rendering

snapgrid works under SSR and static generation. This very site is a statically-exported Next.js app that renders the library. A couple of notes keep it smooth.

Width measurement is SSR-safe

useContainerWidth measures with a ResizeObserver, which only exists in the browser. The hook is SSR-safe by design:

  • it renders at initialWidth (default 1280) on the server and on the first client render, so the markup matches and there’s no hydration mismatch;
  • it then measures the real width after mount and updates.
const { width, mounted, containerRef } = useContainerWidth({ initialWidth: 1024 });

Pick an initialWidth close to your typical container to minimize the first-paint reflow, or gate on mounted if you’d rather not render until measured.

Avoiding layout flash

Because the server renders at initialWidth, tiles briefly appear at that width before the client measures. To avoid any flash you can render the grid only once measured:

const { width, mounted, containerRef } = useContainerWidth(); <div ref={containerRef}> {mounted ? ( <GridLayout layout={layout} width={width} onLayoutChange={setLayout}> {/* … */} </GridLayout> ) : ( <div style={{ minHeight: 240 }} /> )} </div>;

Next.js App Router

In the App Router, the file that renders snapgrid (or any of its hooks) must be a client component. Add "use client" at the top. dnd-kit attaches sensors in effects, so the interaction is inherently client-side.

"use client"; import { GridLayout, useContainerWidth } from "@snapgridjs/react"; // …

The drag overlay portals to document.body, which only exists in the browser. snapgrid guards this, so it simply renders nothing for the overlay during SSR and mounts it on the client.

Last updated on