Next.js App Router
SSR-safe ChartForge integration — client boundaries, dynamic imports, and hydration-warning prevention.
ChartForge's primary target is the Next.js App Router. The
library is fully compatible with React Server Components — but the
rendering engine itself is browser-only (Canvas, ResizeObserver,
devicePixelRatio), so the chart component must mount inside a
Client Component. This page covers the four patterns you'll need.
1. The 'use client' boundary
The simplest pattern. Mark the file that calls <EliteChart /> (or
any chart component) as a Client Component:
This is the recommended path for most apps. The whole route segment becomes a Client Component, hydration runs as normal, and the chart appears on first paint.
@elitechart/reactand@elitechart/elitechartalready prepend'use client';to their bundles, so technically you can import them from a Server Component file — but the file you put your own chart code in still needs'use client'if it uses hooks, refs, or event handlers around the chart.
2. Stylesheet in app/layout.tsx
Import the EliteChart stylesheet once in your root layout. The layout itself stays a Server Component:
suppressHydrationWarning on <html> is the recommended hedge
against theme-flash mismatch warnings (see §4 below).
3. next/dynamic with ssr: false
If you want to defer the chart bundle until after first paint —
useful for above-the-fold pages that don't immediately need the
chart — wrap the import in next/dynamic:
ssr: false skips server rendering for the dynamic chunk entirely,
so there's no hydration mismatch and no flash. The trade-off: the
chart is only painted after the chunk arrives client-side.
Use sparingly — for the common case (chart-first page), the
'use client' pattern from §1 is faster and still SSR-friendly.
4. Hydration-warning prevention (theme flash)
If you persist the user's theme preference in localStorage and
read it on first render, the server-rendered HTML and the
client-rendered HTML will diverge → React fires a hydration
warning. The standard fix is a tiny pre-hydration script in
<head> that applies the theme attribute before React mounts:
The script runs synchronously, before React hydrates, so the
data-theme attribute is already set when ChartForge reads it.
suppressHydrationWarning on <html> silences the expected
attribute-only diff between server (no data-theme) and client
(data-theme="dark").
SSR-safety rules of thumb
When writing your own components around ChartForge, follow these rules to avoid runtime errors during server render:
- Never read
window,document,navigator, ordevicePixelRatioat module scope. Lazily resolve inside event handlers,useEffect, or guardedtypeof window !== 'undefined'checks. - Don't measure the DOM during render. Use
useEffectto run measurements after mount. - Don't render time-sensitive output without seeding. Render a neutral placeholder server-side; populate client-side.
- Use
Suspenseboundaries around components that fetch market data, so streaming SSR can flush the rest of the page.
The internal skill at
.claude/skills/nextjs-ssr-safety.md
in the repo has more detail and reference examples.
What's next?
- Installation — the right package for your layout.
- Quickstart — a single-file working example.
- API Reference — full TypeDoc reference.