Configuring @sanity/astro
Reference for Sanity integration configuration in Astro. Covers integration options, the sanity:client virtual module, environment variables, type declarations, and creating additional client instances.
Configure the integration in your astro.config.mjs file. The integration accepts the same options as @sanity/client, plus additional integration-specific options:
import sanity from '@sanity/astro'
import { defineConfig } from 'astro/config'
export default defineConfig({
integrations: [
sanity({
projectId: 'your-project-id',
dataset: 'production',
apiVersion: '2026-03-01',
useCdn: false,
}),
],
})Configuration options
The integration accepts these options:
projectId(string): your Sanity project ID. Find it at sanity.io/manage.dataset(string): the dataset to query. Typically "production".apiVersion(string): API version date string (e.g., '2026-03-01'). Required for predictable query behavior.useCdn(boolean): whether to use the Sanity CDN. Set to false for static builds, true for server-rendered pages.token(string): API token for authenticated requests. Required for draft content and Visual Editing. Never hardcode tokens; use environment variables.studioBasePath(string): route path for embedded Studio (e.g., '/admin'). Requires@astrojs/react(also needed for the Visual Editing component).stega(object): stega encoding configuration for Visual Editing.
The sanity:client virtual module
Once configured, the integration exposes a pre-configured Sanity client through a virtual module:
---
import { sanityClient } from 'sanity:client'
const posts = await sanityClient.fetch(
`*[_type == "post" && defined(slug)] | order(publishedAt desc)`
)
---This client uses the options you provided in astro.config.mjs. You can use it in any .astro component's frontmatter, in API routes, or in server-side scripts.
Adding type declarations
To get TypeScript support for the sanity:client module, add a reference to your env.d.ts file (typically in your src directory):
/// <reference types="astro/client" /> /// <reference types="@sanity/astro/module" />
After updating this file, restart your TypeScript language server (or restart your editor) for the types to resolve.
Environment variables
Store sensitive values like project IDs and tokens in environment variables rather than hardcoding them in your config. Create a .env file in your project root:
PUBLIC_SANITY_PROJECT_ID="your-project-id" PUBLIC_SANITY_DATASET="production" SANITY_API_READ_TOKEN="your-read-token"
Astro uses the PUBLIC_ prefix convention to distinguish client-side and server-side variables. Variables with the prefix are safe to expose to the browser. Never prefix tokens with PUBLIC_, as this would expose them in client-side JavaScript.
Creating additional client instances
The virtual module client works well for most use cases. If you need a second client with different settings (for example, one configured for draft content), create it from @sanity/client directly:
import { createClient } from '@sanity/client'
export const previewClient = createClient({
projectId: import.meta.env.PUBLIC_SANITY_PROJECT_ID,
dataset: import.meta.env.PUBLIC_SANITY_DATASET,
apiVersion: '2026-03-01',
useCdn: false,
token: import.meta.env.SANITY_API_READ_TOKEN,
perspective: 'drafts',
})This is useful when you need to query draft content alongside published content, or when different parts of your application require different API versions or perspectives.
When to set useCdn
The right useCdn value depends on your rendering mode:
- Static builds (
output: 'static'): setuseCdn: false. Content is fetched once at build time, so CDN caching adds no benefit. You want the freshest data at build time. - Server-rendered (
output: 'server'): setuseCdn: truefor published content. The CDN reduces latency for repeated queries. Set it tofalsewhen fetching draft content with a token. - Mixed static and server rendering: Astro 5 removed the
output: 'hybrid'mode. Useoutput: 'static'oroutput: 'server'and opt individual pages in or out withexport const prerender = trueorexport const prerender = false. SetuseCdnto match the rendering mode of each page:falsefor prerendered pages,truefor server-rendered pages fetching published content.
Minimal working configuration
Here's the smallest setup that works for a statically generated Astro site:
import sanity from '@sanity/astro'
import { defineConfig } from 'astro/config'
export default defineConfig({
integrations: [
sanity({
projectId: 'your-project-id',
dataset: 'production',
apiVersion: '2026-03-01',
useCdn: false,
}),
],
})/// <reference types="astro/client" /> /// <reference types="@sanity/astro/module" />
From here, you can import sanityClient in any .astro file and start querying content.