# Configuring @sanity/astro

Configure the integration in your `astro.config.mjs` file. The integration accepts the same options as `@sanity/client`, plus additional integration-specific options:

**astro.config.mjs**

```typescript
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:

**src/pages/index.astro**

```typescript
---
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):

**src/env.d.ts**

```typescript
/// <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:

**.env**

```sh
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:

**src/lib/sanity.ts**

```typescript
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'`): set `useCdn: 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'`): set `useCdn: true` for published content. The CDN reduces latency for repeated queries. Set it to `false` when fetching draft content with a token.
- **Mixed static and server rendering**: Astro 5 removed the `output: 'hybrid'` mode. Use `output: 'static'` or `output: 'server'` and opt individual pages in or out with `export const prerender = true` or `export const prerender = false`. Set `useCdn` to match the rendering mode of each page: `false` for prerendered pages, `true` for server-rendered pages fetching published content. 

## Minimal working configuration

Here's the smallest setup that works for a statically generated Astro site:

**astro.config.mjs**

```typescript
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,
    }),
  ],
})
```

**src/env.d.ts**

```typescript
/// <reference types="astro/client" />
/// <reference types="@sanity/astro/module" />
```

From here, you can import `sanityClient` in any `.astro` file and start querying content.

