Help Center

Astro / Content

Use Sanity with Astro

Decide when Sanity beats markdown, connect it to your Astro site with the official integration, and rebuild the site automatically when editors publish.

Advanced 45 min Updated

Sanity is a hosted content platform with an editing app called Sanity Studio. This guide is for developers who want editors to manage content in a friendly interface while the website stays a fast, static Astro site. You will create a Sanity project, connect it with the official @sanity/astro integration, fetch content with GROQ, render images and rebuild the site on every publish.

Sanity or markdown?

Most Viralistic sites keep content as markdown in the repository. Choose Sanity only when it solves a real problem.

Keep markdown in the repoChoose Sanity
A few people edit, and they are fine with GitHub or Claude CodeMany editors who need a visual editor and roles
Content changes weekly or lessContent changes daily, such as news or listings
Pages follow fixed layoutsContent is reused across sites, apps or newsletters
No extra service to pay for or maintainEditors need drafts, scheduling and media management

Create a Sanity project and Studio

  1. In a separate folder or repository, run:
pnpm create sanity@latest
  1. Log in, create a new project and keep the default production dataset.
  2. Pick a clean template, then describe your content types (for example post with title, slug, description, mainImage and body) in the Studio’s schema files.
  3. Start the Studio locally with pnpm dev and add a test document.
  4. Deploy the Studio so editors can reach it on a sanity.studio address:
pnpm dlx sanity@latest deploy

Standalone or embedded Studio

Sanity recommends deploying the Studio on its own, as above. You can also embed it in the Astro site at a path like /admin with the studioBasePath option. That requires @astrojs/react, a sanity.config.ts file, your site’s addresses in the project’s CORS origins (with credentials allowed) and a rewrite so Studio sub-pages do not return a 404 on a static host:

[[redirects]]
  from = "/admin/*"
  to = "/admin"
  status = 200

Tip: Viralistic sites ship no React. A standalone Studio keeps it that way and keeps editor traffic away from your website.

Connect Astro to Sanity

  1. In the Astro project, add the integration:
pnpm astro add @sanity/astro
  1. Configure it in astro.config.ts, next to fulldevIntegration():
import sanity from "@sanity/astro"

export default defineConfig({
  integrations: [
    fulldevIntegration({/* site, name, favicon, i18n */}),
    sanity({
      projectId: "your-project-id",
      dataset: "production",
      apiVersion: "2026-03-01",
      useCdn: false,
    }),
  ],
})
  1. Add the type reference to src/env.d.ts:
/// <reference types="astro/client" />
/// <reference types="@sanity/astro/module" />

Use useCdn: false for static builds: queries run once at build time, and you want the freshest content.

Warning: If you need a token (for drafts or private datasets), store it in an environment variable without the PUBLIC_ prefix. Anything prefixed PUBLIC_ can end up in the browser.

Fetch content with GROQ

The integration exposes a ready-made client:

---
import { sanityClient } from "sanity:client"

const posts = await sanityClient.fetch(
  `*[_type == "post" && defined(slug.current)] | order(publishedAt desc){
    title, description, "slug": slug.current, mainImage
  }`
)
---

To keep the Viralistic architecture, do not scatter queries through components. Fetch whole page sets in one place, give each entry a type and validate it with a strict schema, so the single catch-all route and the layout renderer handle Sanity pages exactly like markdown pages.

Render images

Use @sanity/image-url so Sanity’s image CDN resizes and converts images for you:

import { createImageUrlBuilder } from "@sanity/image-url"
import { sanityClient } from "sanity:client"

const builder = createImageUrlBuilder(sanityClient)

export const urlFor = (source: Parameters<typeof builder.image>[0]) =>
  builder.image(source)

In a block, request the size you display: urlFor(image).width(1280).auto("format").url(). Add a required alt field to every image type in your Sanity schema, because every image on a Viralistic site needs alt text. Do not pass Sanity image URLs through Astro’s <Image> component; that processes them twice.

Rebuild the site when editors publish

A static site only shows new content after a new build. Connect the two with a build hook:

  1. In Netlify, open the project configuration, find Build hooks under the continuous deployment settings and add a hook for your main branch.
  2. Copy the hook URL.
  3. At sanity.io/manage, open your project, go to API, then Webhooks, and create a webhook that posts to the hook URL for the production dataset on create, update and delete.
  4. Leave any option to fire on drafts switched off, so only published changes trigger a build.
  5. Publish a test change and watch a new deploy start in Netlify.

Note: Every publish starts a full build, which counts towards your Netlify build usage. For sites with many small edits a day, consider batching or server rendering instead.

If you would rather have Sanity set up for you, book a strategic call: https://calendly.com/marrallisa/30min

Next steps

Still stuck?

Send us what you tried and a screenshot, and we will help you further. For new projects, book a strategic call.