About this Starter
This starter is a mono-repo for marketing and content sites: Next.js 16 on the App Router, Sanity Studio v5, Tailwind v4, deployed with production defaults already wired. The goal is not a toy demo — you clone, configure env vars, and ship pages with draft preview, cache invalidation, SEO, i18n, and a typed GROQ layer on day one.
One repository, two apps (web/ and studio/), shared packages. Conventions are explicit: where tokens live, how modules stack, how locales prefix URLs, how cache tags map to routes. You extend content types and front-end components without fighting the scaffold.
Platform defaults
Draft mode gates live editing behind a read token; Presentation mirrors frontend routes from Studio. Revalidation is webhook-driven with HMAC and per-type tags so a single project publish does not flush the whole site. SEO metadata, sitemap entries, and hreflang pairs resolve from Sanity with settings fallbacks. Field-level i18n keeps one document per page with per-field language tabs. Generated GROQ types stay in sync via CI. Netlify ships hardened headers; the dataset resolver pins which Sanity dataset loads regardless of deploy context. Cookie categories and copy are editable in Settings; the nav can reopen the preference panel. Mux is integrated end-to-end (see section 8).
Modules
All page-like documents expose modules[] in Studio order. Text modules combine an optional i18n title with a richTextMedia body that supports headings, lists, links, inline code, and embedded media or carousel blocks. Standalone Media modules handle hero imagery, featured video, or looping background clips. Carousels lazy-load client JS and support thumbnails, dots, loop, and autoplay. Content Refs query pages, projects, or both — manually curated or “all” with optional category filters on project lists.
Design system
Fonts load through Next with no layout shift; swap families or self-host without touching component code. Semantic color tokens cover text, surfaces, links, code blocks, and status colors — light on :root, dark on [data-theme="dark"]. Spacing tokens scale at larger breakpoints and drive both Tailwind utilities and rich-text vertical rhythm. Typography uses a seven-step scale with a fluid root from 1440px upward. Portable Text block styles map 1:1 to utilities; mono semibold accents H3/H4 and inline strong/em in body copy. .rich-text caps line length in ch for readability. BEM-style block classes (.rich-text, .mux-player) complement Tailwind where markup is CMS-driven or third-party.
Work & projects
/work is a fixed singleton — ideal landing for a portfolio with a Content Refs module set to “all projects”. Each project lives at /projects/[slug] with its own module stack and SEO fields. Categories classify projects for filtering, not routing. Editors connect work to projects through modules, not cross-document references in schema.
Content Refs
One module type replaces hard-coded “latest work” grids. Scope limits to pages or projects; selection is either hand-picked references or a GROQ “all” query. Project scope adds client-side category pills and sort (newest, A–Z). Links resolve through the same rules as the rest of the site: home, /{slug}, or /projects/{slug}.
Tech stack
pnpm workspaces, parallel dev scripts, Biome + Husky locally, four CI workflows on GitHub. Studio plugins cover Presentation, i18n arrays, Mux, media library, Netlify tool, code input, and dashboard. Structure separates editorial content from site settings. Two git branches demonstrate field-level vs document-level i18n; choose one strategy before forking for production.
Mux Video
Upload in Studio; playback IDs flow through GROQ. Standard video uses lazy Mux Player with poster, optional controls, and high-tier ABR. Loops use hls.js with stricter performance budgets: viewport intersection, reduced motion, codec negotiation, and pre-buffer inside carousels. Upload guidance differs for hero players vs short loops.
Routes & UI.
Default locale unprefixed; /de/… for secondary languages. Section A lists document types and paths; section C lists visible chrome strings (nav, footer, draft badge, clone CTA).
Structure
/—home—/or/[language-slug]/work—work/[slug]—page—/about/projects/[slug]—project—/projects/acme
Default unprefixed. Others prefixed. proxy.ts + siteLanguageSettings, fallback en/de.