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 repo | Choose Sanity |
|---|---|
| A few people edit, and they are fine with GitHub or Claude Code | Many editors who need a visual editor and roles |
| Content changes weekly or less | Content changes daily, such as news or listings |
| Pages follow fixed layouts | Content is reused across sites, apps or newsletters |
| No extra service to pay for or maintain | Editors need drafts, scheduling and media management |
Create a Sanity project and Studio
- In a separate folder or repository, run:
pnpm create sanity@latest
- Log in, create a new project and keep the default
productiondataset. - Pick a clean template, then describe your content types (for example
postwithtitle,slug,description,mainImageandbody) in the Studio’s schema files. - Start the Studio locally with
pnpm devand add a test document. - Deploy the Studio so editors can reach it on a
sanity.studioaddress:
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
- In the Astro project, add the integration:
pnpm astro add @sanity/astro
- Configure it in
astro.config.ts, next tofulldevIntegration():
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,
}),
],
})
- 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 prefixedPUBLIC_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:
- In Netlify, open the project configuration, find Build hooks under the continuous deployment settings and add a hook for your main branch.
- Copy the hook URL.
- At sanity.io/manage, open your project, go to API, then Webhooks, and create a webhook that posts to the hook URL for the
productiondataset on create, update and delete. - Leave any option to fire on drafts switched off, so only published changes trigger a build.
- 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.
Strategic call