DEV Community

Cover image for Sanity in Production: Seven Decisions to Make Before You Build
Gyan Solutions
Gyan Solutions

Posted on

Sanity in Production: Seven Decisions to Make Before You Build

Sanity is easy to prototype. A schema, a Studio, one query, and a page can work in an afternoon.

The hard part comes later. Content models multiply. Preview routes break. Ecommerce data ends up in two systems. Editors start asking for changes the schema cannot support.

This article covers the decisions we think teams should settle early. They shape maintainability, editor experience, and frontend architecture more than any single feature.

Decide What Sanity Owns Before You Model Anything

Many Sanity problems we see start before the first schema. Nobody decided which system owns which data, so each team made a local guess.

For a content site, ownership is simple. Sanity holds articles, authors, categories, navigation, reusable blocks, and campaigns.

For ecommerce, Sanity should own the editorial layer. That means product stories, buying guides, landing pages, FAQs, SEO copy, and regional content.

The commerce platform should usually own prices, inventory, carts, checkout, orders, and payments. We keep transactional data outside Sanity unless there is a clear reason not to.

Duplicated ownership creates sync bugs. Say a price is copied into a Sanity product document. A promotion then starts in the commerce system. Now the storefront shows two prices, and an editor gets blamed. One owner per field prevents that.

Model Content Around Meaning, Not Pages

We often see teams model pages before defining reusable content. The schema list fills up with Homepage Hero, Category Page Hero, and Campaign Page Hero. Each looks fine alone. Together they are three copies of one idea.

A better model names what the business actually manages: Campaign, CTA, Product Story, FAQ, Promo Banner, Author, Guide. Pages then assemble these pieces.

Take one FAQ. Written once, it can serve a product page, a support article, a buying guide, and a mobile app. Editors update one document, and every channel reads the change.

Structured pieces are also easier to query, preview, and localize. When we review Sanity implementations, weak content models usually create more long-term friction than GROQ syntax. They are also the hardest thing to undo once real content exists.

Design the Editorial Experience, Not Just the Schema

A schema can be technically correct and still frustrating. Editors do not think in document types. They think in tasks: launch a campaign, fix a guide, update a regional page.

Studio is generated from your schema definitions. It stays extensible through React-based customization. Use that room.

Group fields into tabs. Add validation that catches mistakes early. Write short field descriptions. Configure list previews so editors can tell similar documents apart.

Custom Studio structure matters just as much. Editors should see Campaigns, Guides, and Regional Content, not one flat list of types.

We recommend putting two or three editors in front of the Studio before the schema is final. A thirty-minute walkthrough finds problems that code review never will. This is where Sanity is genuinely strong. The workspace can be shaped around the business, instead of the business adapting to the tool.

Treat Visual Editing as an Integration, Not a Checkbox

Visual Editing is one of Sanity's best features for editors. They see draft content on the real site, click text or images, and jump to the matching field in Studio. Sanity states that its Visual Editing tooling is available on all plans, including free.

It does not appear after installing Sanity, though. The Presentation tool is a Studio plugin that renders your frontend in an iframe. Your frontend must then load draft content for authenticated editors.

In practice, the tool opens a preview URL containing a fresh secret. Your enable route validates it and turns on draft mode. Draft queries need a read token, which must stay server-side. Content Source Maps, encoded into strings as "stega" characters, let overlays map each string to its document and field.

*We suggest planning these items before launch:
*

Secure preview access and token handling
Separate fetching paths for draft and published content
Document-to-URL mapping for every routable type
Preview URLs for each environment
Framework support, since some setups need server rendering for draft mode

Done well, editors preview changes in context. Developers field fewer small content requests.

Keep GROQ Queries Maintainable

GROQ is Sanity's query language. Its strength is precision. You ask for exactly the fields a component needs, follow references, and shape the response with a projection.

The risk is the opposite habit. Teams write one huge query per page type, and every component depends on it. A small schema change then breaks three routes.

We prefer small, named queries in one predictable location. Each returns a stable shape the frontend can rely on.

groq
*[_type == "campaign" && slug.current == $slug][0]{
title,
hero{headline, "imageUrl": image.asset->url},
"products": featuredProducts[]->{title, handle},
faqs[]->{question, answer}
}

The projection fetches only what the page renders. Reference-following replaces extra requests. If the shape changes, one query file changes with it.

Sanity + Ecommerce Works Best With Clear Boundaries

The strongest ecommerce setups we see split responsibilities cleanly:

Sanity: campaigns, buying guides, regional content, FAQs
Commerce platform: products, variants, prices, inventory, checkout, orders
Frontend: fetches from both and combines them at render time

Shopify and Medusa both fit this pattern. With Shopify, Sanity Connect can sync products into Sanity as documents. Editors can then reference them in guides and campaigns.

Sanity's own documentation says imported Shopify metafields are owned by Shopify and are read-only in Sanity. That is the right instinct. Reference commerce data. Do not edit a second copy of it.

This works because each system does what it handles best. Marketers move quickly on editorial content. The commerce platform keeps transactional accuracy. Live price and stock come from the commerce API.

Sanity is not a commerce engine, and it does not need to be. Its value is the storytelling layer. That means structured campaigns, in-context previews, and content for several markets.

Production Readiness Is More Than Content Modeling

Keep two parts straight. Studio is the editing application. Content Lake is Sanity's hosted datastore. Studio can be hosted by Sanity or self-hosted as a static app, but self-hosting changes where the editor runs, not where content lives.

Sanity may not fit every project. Tiny static sites, rare publishing, and content with no reuse rarely need it. The same goes for teams that need fully self-hosted content infrastructure, or have no technical ownership.

For projects that do fit, we ask these questions before launch:

  • Who owns schema changes, and how are they reviewed?
  • How is Studio deployed and upgraded?
  • How are preview URLs and read tokens secured?
  • Are datasets separated by environment?
  • How do we stop draft queries from reaching production?
  • Are required references validated?
  • How is content migration tested?
  • Who maintains Visual Editing as the frontend changes? When a project involves complex modeling, Visual Editing, ecommerce integration, migration, or custom Studio workflows, experienced Sanity development services can help teams avoid rebuilding the architecture later.

Content as Infrastructure

Sanity becomes especially valuable when teams treat content as structured infrastructure instead of finished pages.

The best results we see share four traits: clear ownership, thoughtful modeling, an editor-centered Studio, and deliberate frontend integration.

Sanity's flexibility rewards that discipline. Real-time collaboration, GROQ, and Visual Editing become far more useful on a foundation designed with care. Start with the decisions above. The features will then have something solid to build on.

Top comments (0)