Next.js App Router, Remix and other SSR setups need no special handling.
Every file that needs the browser carries 'use client', so you can import from
a server component without marking your own file.
The first render emits the color as CSS custom properties, so there is no flash before hydration.
Nothing is read from window at module scope. injectStyles is a no-op when
document is undefined.
Avoiding the unstyled flash
The panel injects its stylesheet from an effect, which means server-rendered markup is unstyled until hydration. Import the stylesheet yourself and turn injection off:
// app/layout.tsx
import "chroma-panel/style.css";<ChromaPanel injectStyles={false} />See styling with Tailwind for where that import has to sit relative to your own CSS.
Tree shaking
Importing chroma-panel registers all five modes through side effects listed in
the package's sideEffects field. If you import a mode entry point directly,
import it for its side effect rather than a binding:
import { ChromaPanel } from "chroma-panel/panel";
import "chroma-panel/wheel";