diff --git a/.changeset/p2-15-per-route-critical-css.md b/.changeset/p2-15-per-route-critical-css.md new file mode 100644 index 0000000..f52866b --- /dev/null +++ b/.changeset/p2-15-per-route-critical-css.md @@ -0,0 +1,6 @@ +--- +'@typestyles/build-runner': minor +'@typestyles/next': minor +--- + +Per-route critical CSS for Next.js App Router (P2.15): `buildTypestylesForNext` emits route-scoped stylesheets and manifest v2 with a `routes` map; `getRouteCss` reads them at request time instead of the full `getRegisteredCss()` buffer. diff --git a/IMPROVEMENTS.md b/IMPROVEMENTS.md index d17f3af..3c9dabc 100644 --- a/IMPROVEMENTS.md +++ b/IMPROVEMENTS.md @@ -120,7 +120,7 @@ Bugs and credibility issues that lose evaluations on contact. Do these first. variants with JSX call-site rewrites. - Parse `@media` (and other at-rules) in static templates into nested style objects. -- [ ] **P2.15 — Per-route critical CSS** (PR: ) +- [x] **P2.15 — Per-route critical CSS** (PR: #100) - `getRegisteredCss()` returns everything ever registered. Use the extraction manifest in `@typestyles/next/build` to emit route-level CSS. diff --git a/docs/content/docs/ssr.md b/docs/content/docs/ssr.md index e394625..89a3d89 100644 --- a/docs/content/docs/ssr.md +++ b/docs/content/docs/ssr.md @@ -321,7 +321,41 @@ TypeStyles automatically deduplicates CSS during collection. If multiple compone ### Critical CSS -All CSS is included by default. For large applications, you might want to implement critical CSS extraction (only including styles for above-the-fold content). This isn't built into TypeStyles—you'd need to implement it at the framework level. +By default, `getRegisteredCss()` returns every rule registered in the process. For large apps, prefer **build-time per-route CSS** on Next.js: `buildTypestylesForNext` writes route-scoped stylesheets and a v2 manifest (see [zero-runtime — Next.js](/docs/zero-runtime#nextjs) and [per-route critical CSS](#per-route-critical-css-nextjs) below). + +### Per-route critical CSS (Next.js) + +`buildTypestylesForNext` traces each App Router `page` plus its layout chain, extracts CSS for modules that import `typestyles`, and writes self-contained files under `app/_typestyles/routes/` (default). The manifest maps route paths to those files: + +```json +{ + "version": 2, + "css": "app/typestyles.css", + "routes": { + "/": { "css": "app/_typestyles/routes/index.css" }, + "/about": { "css": "app/_typestyles/routes/about.css" } + } +} +``` + +At request time, read the pre-built CSS for the current route instead of the full global sheet: + +```tsx +// app/about/layout.tsx (Server Component) +import { getRouteCss } from '@typestyles/next/server'; + +export default function AboutLayout({ children }: { children: React.ReactNode }) { + const css = getRouteCss('/about', { root: process.cwd() }); + return ( + <> +