Docs · Framework
Next.js
App Router, Cache Components, React Compiler and the config we use.
Arise UI runs on Next.js 16.4 with the App Router. Every page is prerendered as static HTML at build time.
Install
create-next-app is the quickest start; the Installation guide lists the answers to pick. To add Next.js to an existing project by hand:
pnpm add next@latest react@latest react-dom@latestNext.js needs Node.js 20.9 or later and supports Chrome, Edge and Firefox 111+ and Safari 16.4+.
Configuration
import type { NextConfig } from "next"; const nextConfig: NextConfig = { cacheComponents: true, partialPrefetching: true, reactCompiler: true, experimental: { // Hugeicons ships ~15k named exports from one entry point. // This makes Next load only the icons we actually import. optimizePackageImports: ["@hugeicons/core-free-icons"], }, turbopack: { rules: { "*.css": { loaders: ["@tailwindcss/turbopack"], as: "*.css", }, }, },}; export default nextConfig;| Option | What it does |
|---|---|
cacheComponents | Pages are static by default; dynamic parts opt in. Visited pages stay mounted but hidden, so going back is instant. |
partialPrefetching | Links prefetch one shared shell per route instead of each page in full. Needs cacheComponents. |
reactCompiler | Memoizes components for you, so useMemo and useCallback are rarely needed. Needs the babel-plugin-react-compiler dev dependency. |
optimizePackageImports | Hugeicons exports thousands of icons from one file; this loads only the ones you import. |
turbopack.rules | Runs Tailwind CSS through Turbopack. Optional; see the Tailwind guide. |
pnpm add -D babel-plugin-react-compilerServer and client components
Files are Server Components unless they start with "use client". Add it only when a file uses hooks, motion or browser APIs. Pages in Arise UI are Server Components that render client components inside them.
Class helpers that Server Components need live in plain .ts files, so they don't cross the client boundary:
// button-styles.ts: no "use client", so Server Components can use itexport function buttonClasses({ variant = "primary" } = {}) { /* … */ } // page.tsx: a Server Component styling a link as a buttonimport Link from "next/link";import { buttonClasses } from "@/components/ui/button-styles"; <Link href="/pricing" className={buttonClasses({ size: "lg" })}>Pricing</Link>Cache Components
Hidden pages stay mounted
After you leave a page, Next.js keeps it mounted but hidden. A menu left open would still be open when you come back, so anything that opens closes itself with useResetOnHide:
"use client"; import { useState } from "react";import { useResetOnHide } from "@/hooks/use-reset-on-hide"; export function Menu() { const [open, setOpen] = useState(false); // Close the menu when the user navigates away and its page is kept hidden. useResetOnHide(() => setOpen(false)); return <div>{/* … */}</div>;}No clock or randomness while rendering
Static pages are rendered once at build time. Date.now(), new Date() and Math.random() during render would freeze one value into the HTML. Call them in effects or event handlers.
Reading files
To read a file or other data at build time, wrap it in a "use cache" function. This is how the Code views and these docs show source files:
import { readFile } from "node:fs/promises"; async function readSource(file: string) { "use cache"; // the result is part of the static build return readFile(file, "utf8");}Docs for this version
Next.js 16 changed some APIs. The docs for the installed version ship with the package in node_modules/next/dist/docs/, and AGENTS.md points coding agents to them. Online: nextjs.org/docs.
pnpm devstarts the dev server with Turbopack on port 3000.pnpm buildbuilds for production;pnpm startserves it.