Everything *[NYC] 2026: see what we announced. →
Skip to content

Sane Kit

A starter template combining Next.js, Sanity, and TWBlocks. Designed for rapid development with pre-built components and internationalization support.

By Vinicius Leal

Loading
Preview

README

Sane-Kit

A Sanity + Next.js starter kit: a monorepo with a page-builder frontend and a customizable Studio. Built on the 2026 stack.

2026 release. Upgraded to Next.js 16 · React 19 · Sanity 6 · next-sanity 13, with sanityFetch live content and an optimistic page builder. See CHANGELOG.md and docs/RELEASE.md.

FrontendNext.js 16 (App Router, Turbopack) · React 19 · next-sanity 13
StudioSanity 6 · @sanity/document-internationalization · Presentation tool
UITailwind CSS v4 · shadcn/ui (Base UI)
Toolingpnpm 10 workspaces · Turborepo · TypeScript · ESLint (flat config)

Features

  • Page builder with 12+ section types (hero, features, pricing, FAQ, CTA, blog, contact, newsletter, …).
  • Typed content end to end — Sanity TypeGen with overloadClientMethods; no hand-written query types.
  • Live Content API (defineLive / <SanityLive />) — published changes appear without a redeploy.
  • Visual Editing + Presentation — click-to-edit overlays and draft preview, with block-level updates.
  • Document internationalization (English / Portuguese) via the official Sanity plugin.
  • Live Content & caching — Cache Components prerenders a partial static shell per route, and <SanityLive /> streams published changes and revalidates the cached content without a redeploy.
  • SEO — sitemap.xml, robots.txt, RSS feed, Open Graph metadata.
  • Analytics — GA4 via @next/third-parties, PostHog, both consent-gated.

Repository layout

sane-kit/
├── frontend/   # Next.js app (routes under src/app/[locale])
│   └── src/sanity/   # env, client, live, image, queries, generated types
├── studio/     # Sanity Studio (schemas, structure, presentation resolver)
├── functions/  # Sanity Functions (deployed via the Blueprint)
├── sanity.blueprint.ts   # project setup as code (CORS, functions)
├── turbo.json
└── pnpm-workspace.yaml

Getting started

Requires Node 24 and pnpm 10.

pnpm install
cp frontend/.env.example frontend/.env.local   # fill in your Sanity project
cp studio/.env.example studio/.env.local
pnpm dev

Environment variables

frontend/.env.local

VariableRequiredPurpose
NEXT_PUBLIC_SANITY_PROJECT_IDyesSanity project id
NEXT_PUBLIC_SANITY_DATASETyesDataset (e.g. production)
NEXT_PUBLIC_SANITY_API_VERSIONnoAPI version date (default 2026-10-01)
NEXT_PUBLIC_SANITY_STUDIO_URLnoStudio URL for click-to-edit (default http://localhost:3333)
NEXT_PUBLIC_SITE_URLnoCanonical site URL (sitemap, RSS, OG)
SANITY_API_READ_TOKENfor previewsViewer token — enables Draft Mode + Live Content
NEXT_PUBLIC_GA_MEASUREMENT_IDnoGoogle Analytics 4
NEXT_PUBLIC_POSTHOG_KEY / _HOSTnoPostHog
RESEND_API_KEYfor formsResend API key (contact + newsletter forms)
CONTACT_FORM_TOfor formsRecipient inbox for the contact form
CONTACT_FORM_FROMfor formsVerified Resend sender, e.g. Sane Kit <hello@yourdomain.com>

studio/.env.local: SANITY_STUDIO_PROJECT_ID, SANITY_STUDIO_DATASET, SANITY_STUDIO_SITE_URL (the frontend origin used by the Presentation tool).

Locales

Languages live in Sanity as locale documents — the single source of truth used by the Studio's translation workflow. Seed them once (the tag must match the frontend route segment):

pnpm --filter studio exec sanity dataset import seed/locales.ndjson production

Scripts

pnpm dev          # run frontend + studio (Turborepo)
pnpm build        # build both
pnpm typecheck    # tsc across workspaces
pnpm lint         # eslint across workspaces
pnpm test         # Vitest unit tests
pnpm test:e2e     # Playwright smoke tests (builds + starts the production server)
pnpm typegen      # extract schema + regenerate frontend/src/sanity/types.ts
pnpm blueprint:plan    # preview Blueprint changes (CORS, functions)
pnpm blueprint:deploy  # apply the Blueprint to your Sanity project
pnpm verify       # typecheck + typecheck:blueprint + lint + build + test

TypeGen

Types are generated from the Studio schema and the GROQ queries in frontend/src. Config lives in studio/sanity.cli.ts (typegen), and typegen.enabled regenerates during sanity dev/sanity build. Run pnpm typegen after changing a schema or a query.

Visual Editing / previews

  1. Create a Viewer API token in Sanity and set SANITY_API_READ_TOKEN.
  2. Add the frontend origin to the project's CORS origins with Allow credentials:
    pnpm --filter studio exec sanity cors add http://localhost:3000 --credentials
  3. Open the Presentation tool in the Studio — the site loads in an iframe with click-to-edit overlays.

Live updates

On-demand revalidation is handled by the Live Content API: <SanityLive /> (in app/[locale]/layout.tsx) subscribes to content changes and revalidates the cache tags sanityFetch produces — no webhook required.

Redirects

Editors manage 307/308 redirects with the Redirect document type in the Studio. next.config.ts loads them in redirects() at build time, so a new redirect takes effect on the next deploy.

Deployment

  • Studio: pnpm --filter studio deploy.
  • Frontend: deploy frontend/ to Vercel (or any Next host); set the environment variables above, then re-check CORS.

Agent rules

Sanity schema/query conventions follow the official sanity-best-practices agent skill. Turborepo guidance ships with the installed turbo package.

License

MIT — see LICENSE.