SSR / Next.js
The library is SSR-safe at module scope (no top-level window/storage access), but the component is deeply client-side — render it client-only:
// Next.js (app or pages router)
import dynamic from 'next/dynamic';
const WindowsXP = dynamic(
() => import('@caoergou/windows-xp').then((m) => m.WindowsXP),
{ ssr: false }
);Import @caoergou/windows-xp/style.css globally as usual. For Astro/Vite SSR setups, the equivalent client-only island wrapper applies.
Verified consumption (#206)
Every push to main (and every release-labelled PR) runs a consumer-smoke CI job — npm pack → a clean Vite + React app installs the tarball → builds → renders <WindowsXP> in a real browser. It asserts, from the outside of the package, that:
- the
.,./components, and./style.cssexport subpaths all resolve; - the i18n
init()side-effect survives tree-shaking (asideEffectsentry that matches no packaged file fails the job — the class of bug that once shipped a desktop with raw i18n keys); - heavy apps stay code-split out of first paint;
- the published
.d.tstype-checks against both@types/react@18and@19.
The Next.js path is the dynamic(..., { ssr: false }) wrapper above: the same tarball the consumer-smoke validates, loaded client-only. If you hit an SSR edge case, mirror the Vite consumer under scripts/consumer-smoke/ as a starting point.