Nuxt + Sanity Integration Best Practices
Best-practices guide for the @nuxtjs/sanity module (Nuxt 3 and 4). Covers module
setup, composables, SSR data fetching, image handling, Portable Text, visual
editing, TypeScript, and Nitro server routes.
Also load the
nuxtskill for Nuxt core patterns andsanity-best-practicesfor GROQ query optimization and schema design. This skill covers the integration layer only.
ROUTING: Which rule file to load
IF setting up the module or configuring nuxt.config.ts:
→ Read rules/core-module-setup.md
IF using useSanityQuery, useLazySanityQuery, or useSanity composables:
→ Read rules/core-composables.md
IF writing Nitro server routes that query Sanity:
→ Read rules/core-server-routes.md
IF working with the SanityImage component or building image URLs programmatically:
→ Read rules/features-sanity-image.md
IF rendering Portable Text with SanityContent:
→ Read rules/features-sanity-content.md
IF implementing visual editing, live preview, stega, or the Presentation tool:
→ Read rules/features-visual-editing.md
IF following the Display Starter architecture or adding a new document type:
→ Read rules/arch-starter-pattern.md then rules/arch-extension-pattern.md
IF configuring CDN caching, cache tags, or webhook cache invalidation:
→ Read rules/perf-cdn-caching.md
IF experiencing stale CDN content after a Sanity publish (not query-level cache):
→ Read rules/perf-cdn-caching.md — start from "Diagnostics" and compare the live Sanity API,
Sanity API CDN, Netlify JSON, page HTML, and Nuxt payload separately
IF adding any cache in front of Sanity (defineCachedEventHandler, Nitro storage, longer TTLs):
→ Read rules/perf-cdn-caching.md first — every long-lived layer must have a reliable invalidation
path, and Sanity API-CDN propagation can race a downstream purge
IF experiencing stale data, cache misses, or reactive query bugs:
→ Read rules/perf-query-keys-and-caching.md
IF debugging CORS errors, auth token issues, or hydration mismatches:
→ Read rules/debug-common-errors.md
IF generating a dynamic sitemap from Sanity routes (works, case studies, etc.):
→ Read rules/features-sitemap.md
IF the sitemap uses locale prefixes or per-locale slugs:
→ Read rules/features-sitemap.md then rules/features-sitemap-i18n.md
IF deriving page title, description, Open Graph, or other SEO metadata from Sanity:
→ Read rules/features-seo-meta.md
Rule index
| Topic | Description | File |
|---|---|---|
| Sections overview | Categories and reading order | rules/_sections.md |
| Module setup | Installation, nuxt.config.ts options, env vars | rules/core-module-setup.md |
| Composables | useSanityQuery, useLazySanityQuery, useSanity usage, preview-switch pattern | rules/core-composables.md |
| Server routes | Nitro server routes with useSanity, validateSanityQuery | rules/core-server-routes.md |
| Starter architecture | Directory layout, data-flow, GROQ conventions, i18n | rules/arch-starter-pattern.md |
| Extension pattern | Connected query, endpoint, composable, page, dependency-tag, and webhook recipe | rules/arch-extension-pattern.md |
| CDN caching | Browser, Netlify, and Sanity CDN policy; preview bypass and webhook invalidation | rules/perf-cdn-caching.md |
| SanityImage | SanityImage component, @sanity/image-url builder, @nuxt/image integration |
rules/features-sanity-image.md |
| SanityContent | Portable Text rendering, custom components | rules/features-sanity-content.md |
| Visual editing | Stega, live preview, Presentation tool, draft mode | rules/features-visual-editing.md |
| Caching (queries) | Query key stability, reactive params, cache invalidation | rules/perf-query-keys-and-caching.md |
| Debug | CORS, auth tokens, hydration errors, common pitfalls | rules/debug-common-errors.md |
| Sitemap | Dynamic sitemap sources, defineSitemapEventHandler, stegaClean on slugs | rules/features-sitemap.md |
| Sitemap i18n | prefix_except_default, locale-specific slugs and sitemap assignment |
rules/features-sitemap-i18n.md |
| SEO metadata | useSeoMeta with cache-safe Sanity page data |
rules/features-seo-meta.md |
Quick access by priority
| Priority | When you need it | File |
|---|---|---|
| 🔴 FIRST | Setting up or configuring the module | core-module-setup.md |
| 🔴 FIRST | Understanding data flow & architecture | arch-starter-pattern.md |
| 🔴 FIRST | Adding a new content type | arch-extension-pattern.md |
| 🟠 OFTEN | Fetching data with useSanityQuery | core-composables.md |
| 🟠 OFTEN | Cache strategy (ISR vs SWR, purge) | perf-cdn-caching.md |
| 🟡 SOMETIMES | Visual editing & stega | features-visual-editing.md |
| 🟡 SOMETIMES | SEO meta tags | features-seo-meta.md |
| 🟡 SOMETIMES | Dynamic sitemap with i18n | features-sitemap-i18n.md |
| 🔵 TROUBLESHOOT | Caching misses or stale data | perf-query-keys-and-caching.md |
| 🔵 TROUBLESHOOT | CORS, hydration, or other bugs | debug-common-errors.md |
Coverage and maintenance
- Coverage map:
rules/_coverage-map.md - Module source: https://github.com/nuxt-modules/sanity
- Update when
@nuxtjs/sanityreleases a new major version or visual editing APIs change.