Skip to content
THE PIMOLU HANDBOOK
Skip to content

Getting started

Next.js

Keep the App Router boundary clear and load the shared styles once.

Import the compiled packages

Published packages ship compiled ESM and declarations, so a Next.js application does not need transpilePackages for them. The workspace website and examples keep the setting for local source development.

next.config.tstsx
import type { NextConfig } from "next";

const config: NextConfig = {};

export default config;

Create a client boundary

The published React entry is marked use client and exports hooks and interactive components. Put the Provider and your event handlers in a client module. Keep the root layout and metadata on the server, and pass children through your provider.

app/providers.tsxtsx
"use client";

import type { ReactNode } from "react";
import { PimoluProvider } from "@pimolu/react";

export function Providers({ children }: { children: ReactNode }) {
  return (
    <PimoluProvider defaultTheme="system">
      {children}
    </PimoluProvider>
  );
}

Load the shared stylesheet

Import the package stylesheet once from your global CSS entry. It includes component styles, themes and visual presets. Do not import component CSS from the React registry or reproduce those styles in your application.

app/globals.csscss
@import "@pimolu/web-styles/styles.css";

@import "tailwindcss";

/* Add your application styles below. */

Connect the global stylesheet

Import globals.css from the root layout so Next.js includes Pimolu styles throughout the application.

app/layout.tsxtsx
import type { ReactNode } from "react";
import "./globals.css";
import { Providers } from "./providers";

export default function Layout({ children }: { children: ReactNode }) {
  return (
    <html lang="en">
      <body><Providers>{children}</Providers></body>
    </html>
  );
}

Keep preferences consistent

For a saved explicit light/dark preference, read a validated cookie on the server and pass the same initial value to your client provider. This website implements that in app/layout.tsx, lib/preferences.ts and components/site-provider.tsx.

System mode follows the user's media preference. Do not render different application markup based on window or matchMedia during the initial server render. Avoid suppressing hydration warnings to conceal a mismatch.