Commerce8 min read

How to Integrate Swell with Your Headless CMS

Sync product storytelling, buying guides, and merchandising content from structured content into Swell so commerce teams can publish faster without copying product data by hand.

Published April 29, 2026
01Overview

What is Swell?

Swell is an API-first commerce platform for brands that need custom storefronts, flexible product models, subscriptions, B2B pricing, carts, checkout, and order workflows. Teams use Swell when they want commerce APIs without being locked into a fixed storefront system. Its core role is handling commerce data and transactions, while your content layer handles the editorial, merchandising, and multi-channel experience around those products.


02The case for integration

Why integrate Swell with a headless CMS?

Commerce teams usually hit the same wall: product data lives in Swell, but the story around the product lives somewhere else. A product detail page may need specs, SEO copy, comparison tables, care instructions, collection narratives, ingredient callouts, and localized buying guides. If that content is copied into Swell by hand, every launch creates duplicate work and a higher chance that the storefront, email campaign, and product feed disagree.


03Architecture

Architecture overview

A typical Sanity and Swell integration starts when an editor publishes a product content document in Sanity Studio. A Sanity webhook fires on the publish event, or a Sanity Function runs directly on the content mutation. The handler receives the changed document ID, uses @sanity/client to query the Content Lake with GROQ, and selects the exact fields Swell needs, such as title, slug, SEO description, product badges, image URLs, related category references, and a stored Swell product ID. The handler then calls Swell's Admin API through the swell-node SDK, usually with swell.put('/products/{id}', payload) for an existing product or swell.post('/products', payload) for a new one. Swell updates the commerce record, and the storefront reads from Swell for transactional product data while also querying Sanity for richer content. The end user sees one product experience, even though pricing, checkout, and editorial content are handled by the systems best suited for each job.


04Use cases

Common use cases

🛍️

Merchandised product detail pages

Publish editorial product copy, badges, comparison modules, and care notes from Sanity while Swell handles variants, prices, carts, and checkout.

📦

Catalog enrichment

Add buying guides, ingredient details, sizing notes, and SEO fields to Swell products without asking commerce admins to edit long-form content.

🌎

Localized commerce content

Keep Swell product records stable while Sanity supplies market-specific descriptions, campaigns, and landing page modules for each locale.

🤖

Shopping agents with product context

Use Agent Context to let AI shopping agents read structured product education, FAQs, and comparison data alongside Swell commerce data.


05Implementation

Step-by-step integration

  1. 1

    Set up Swell and get API credentials

    Create a Swell store, add at least one product or product type, and copy your store ID plus a secret API key from the Swell dashboard. Install the Admin API client with npm install swell-node.

  2. 2

    Model product content in Sanity Studio

    Create a product content schema with fields like title, slug, swellProductId, shortDescription, seoTitle, seoDescription, badges, productImages, and references to categories or buying guides. Keep Swell-owned fields, such as price, SKU, and inventory, out of the editorial schema unless you have a specific sync rule.

  3. 3

    Query only the fields Swell needs

    Write a GROQ projection that returns the published product content, resolves image asset URLs, and joins referenced category slugs. This keeps the Swell update payload small and predictable.

  4. 4

    Create the sync mechanism

    Use a Sanity Function for server-side sync logic triggered by content mutations, or create a webhook listener in your app. Filter the trigger to product content publish events so draft edits don't update Swell.

  5. 5

    Call Swell's Admin API

    Initialize swell-node with your store ID and secret key, map Sanity fields to Swell product fields, and call swell.put('/products/{id}', payload) for updates. If your flow creates products from Sanity, call swell.post('/products', payload) and write the returned Swell ID back to Sanity.

  6. 6

    Test the storefront experience

    Publish a test product in Sanity Studio, confirm the Swell product record updates, and check your frontend. A common pattern is to fetch price, variants, and cart state from Swell, then fetch editorial modules, SEO fields, and content references from Sanity.


06Code

Code example

typescriptapi/sanity-to-swell.ts
import {createClient} from '@sanity/client'
import swell from 'swell-node'

const sanity = createClient({
  projectId: process.env.SANITY_PROJECT_ID!,
  dataset: process.env.SANITY_DATASET!,
  apiVersion: '2025-01-01',
  token: process.env.SANITY_READ_TOKEN!,
  useCdn: false,
})

swell.init(process.env.SWELL_STORE_ID!, process.env.SWELL_SECRET_KEY!)

export async function POST(req: Request) {
  const body = await req.json()
  const id = body._id?.replace('drafts.', '')

  const product = await sanity.fetch(`
    *[_type == "product" && _id == $id][0]{
      title,
      "slug": slug.current,
      swellProductId,
      shortDescription,
      seoTitle,
      seoDescription,
      "images": images[]{"file": asset->url, alt},
      "categories": categories[]->{"slug": slug.current}
    }
  `, {id})

  if (!product?.swellProductId) {
    return Response.json({skipped: true, reason: 'Missing swellProductId'})
  }

  await swell.put(`/products/${product.swellProductId}`, {
    name: product.title,
    slug: product.slug,
    description: product.shortDescription,
    meta_title: product.seoTitle,
    meta_description: product.seoDescription,
    images: product.images,
    content: {
      category_slugs: product.categories?.map((c: any) => c.slug) || []
    }
  })

  return Response.json({ok: true})
}

07Why Sanity

How Sanity + Swell works

Build your Swell integration on Sanity

Sanity's AI Content Operating System gives you the structured content foundation, real-time event system, and flexible APIs to connect editorial product content with Swell commerce workflows.

Start building free →

08Comparison

CMS approaches to Swell

CapabilityTraditional CMSSanity
Product content modelingProduct storytelling often lives inside pages, which makes reuse across Swell, storefronts, and campaigns harder.Schema-as-code lets you model product stories, badges, comparison blocks, localized fields, and Swell IDs as typed content.
Sync on publishUpdates often depend on manual exports, plugins, or scheduled jobs that can lag behind product launches.GROQ-filtered webhooks and Functions can trigger a Swell update when specific product content changes.
Field-level API controlAPIs may return page-shaped content, which means the integration has to remove fields Swell doesn't need.GROQ can project Swell-ready payloads with joined references, image URLs, and localized fields in one query.
Commerce ownership boundariesEditors may end up changing commerce fields and editorial fields in the same screen, increasing risk.Sanity Studio can show editorial teams only the fields they should own, while Swell remains the source for SKU, price, inventory behavior, and checkout.
Multi-channel deliveryContent is usually shaped for the website first, then adapted for other channels later.The same structured product content can feed web, mobile, Swell enrichment, email, and production AI agents through Agent Context.

09Next steps

Keep building

Explore related integrations to complete your content stack.

Ready to try Sanity?

See how Sanity's Content Operating System powers integrations with Swell and 200+ other tools.