Frameworks & Hosting8 min read

How to Integrate Render with Your Headless CMS

Connect Render to a headless CMS so every publish can trigger a fresh deploy, update a hosted app, and deliver structured content to users without manual rebuilds.

Published April 29, 2026
01 β€” Overview

What is Render?

Render is a cloud application platform for hosting static sites, web services, background workers, cron jobs, PostgreSQL, and Redis. Teams use it to deploy from GitHub or GitLab, run production services, manage TLS, and configure environments without building deployment infrastructure from scratch. It sits in the same hosting category as Heroku, Railway, Fly.io, and Vercel, with a focus on app hosting beyond front-end frameworks.


02 β€” The case for integration

Why integrate Render with a headless CMS?

If your site or app runs on Render, content changes need a clean path from editorial work to production. Without an integration, someone publishes content, then another person manually clicks "Deploy latest commit," clears a cache, or asks engineering to run a script. That works for a five-page site. It breaks when you have product launches, documentation updates, pricing pages, localized content, and campaign pages changing every day.


03 β€” Architecture

Architecture overview

A typical setup starts in Sanity Studio, where editors publish structured content into the Content Lake. A Sanity webhook listens for publish events, often filtered with GROQ so only production-relevant documents trigger work, for example articles, landing pages, or docs. The webhook sends the changed document ID to a Sanity Function or a small webhook route hosted on Render. That handler uses @sanity/client to run a GROQ query, fetches the exact fields the Render app needs, then calls Render’s API with POST https://api.render.com/v1/services/{serviceId}/deploys using a Render API key. Render starts a new deploy for the target Static Site or Web Service. During build or runtime, the app queries Sanity again and serves the latest content to the end user. For simpler static sites, you can use a Render Deploy Hook URL instead of the authenticated API endpoint. For more control, use the API so you can choose the service, log the deploy ID, and handle failures.


04 β€” Use cases

Common use cases

πŸš€

Publish-triggered static site deploys

Start a Render Static Site deploy when editors publish a page, article, or docs entry in Sanity.

🧭

Server-rendered content apps

Run a Next.js, Remix, or Express app on Render that reads structured content from the Content Lake at request time.

πŸ› οΈ

Background content jobs

Use a Render Background Worker to rebuild navigation, search documents, sitemaps, or RSS feeds after Sanity content changes.

🌿

Staging and branch previews

Route Sanity draft or release content to Render preview environments so teams can review changes before production.


05 β€” Implementation

Step-by-step integration

  1. 1

    Create your Render service

    In Render, create a Static Site or Web Service from your GitHub or GitLab repository. Add build and start commands, set environment variables, and confirm the first deploy finishes successfully.

  2. 2

    Create a Render API key or Deploy Hook

    For the authenticated API path, create a Render API key from your account settings and copy the target service ID from the Render dashboard or API. For a simpler setup, create a Deploy Hook on the service and copy the hook URL.

  3. 3

    Model the content in Sanity Studio

    Define the fields your Render app needs, such as title, slug, locale, body, seoTitle, seoDescription, publishedAt, and references to authors or categories. Keep the schema close to your domain instead of mirroring page HTML.

  4. 4

    Create the webhook or Sanity Function

    Create a Sanity webhook that fires on publish, update, and delete events. Filter it with GROQ when needed, for example _type in ["post", "page", "doc"], then send the event to a Sanity Function or a Render-hosted webhook route.

  5. 5

    Call Render from the handler

    Use @sanity/client to fetch the changed document, then call Render’s REST API at /v1/services/{serviceId}/deploys with your API key. Log the deploy ID so you can trace a Sanity publish event to a Render deploy.

  6. 6

    Test the full path

    Publish a small content change, confirm the webhook fired in Sanity, confirm the deploy started in Render, and verify the live page shows the new content. Also test deletes, draft-only changes, and failed Render API calls.


06 β€” Code

Code example

Minimal Express webhook route hosted on Render. It receives a Sanity webhook, fetches the changed document with GROQ, then starts a Render deploy with the Render API.

typescript
import express from 'express';
import {createClient} from '@sanity/client';

const app = express();
app.use(express.json());

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

app.post('/sanity-webhook', async (req, res) => {
  if (req.header('x-webhook-secret') !== process.env.WEBHOOK_SECRET) {
    return res.status(401).send('Unauthorized');
  }

  const id = req.body?._id?.replace('drafts.', '');
  const doc = await sanity.fetch(
    `*[_id == $id][0]{_id, _type, title, "slug": slug.current}`,
    {id}
  );

  if (!doc || !['post', 'page', 'doc'].includes(doc._type)) {
    return res.status(202).json({skipped: true});
  }

  const deploy = await fetch(
    `https://api.render.com/v1/services/${process.env.RENDER_SERVICE_ID}/deploys`,
    {
      method: 'POST',
      headers: {
        Authorization: `Bearer ${process.env.RENDER_API_KEY}`,
        'Content-Type': 'application/json'
      },
      body: JSON.stringify({clearCache: 'do_not_clear'})
    }
  );

  if (!deploy.ok) {
    return res.status(502).send(await deploy.text());
  }

  res.status(200).json({queued: true, document: doc.slug});
});

app.listen(process.env.PORT || 3000);

07 β€” Why Sanity

How Sanity + Render works

Build your Render integration on Sanity

Sanity gives you the structured content foundation, real-time event system, and flexible APIs to connect Render deploys with your publishing workflow.

Start building free β†’

08 β€” Comparison

CMS approaches to Render

CapabilityTraditional CMSSanity
Content-triggered Render deploysUsually depends on manual rebuilds, plugin-specific hooks, or custom scripts tied to page publishing.Webhooks can use GROQ filters, and Functions can run server-side logic before calling the Render API.
Data shape for hosted appsContent is often organized around pages, HTML fields, or theme templates, which can make reuse harder.Schemas define typed content as code, and the Content Lake keeps references queryable for Render-hosted apps.
Field-level query controlApps may receive more page data than they need, then trim it during build or runtime.GROQ can fetch one document, project only needed fields, and resolve references in a single query.
Static site rebuild strategyRebuilds are often coupled to the publishing UI or a site-specific plugin.A webhook or Function can decide which Render service to deploy, log the event, and skip irrelevant content types.
Preview and staging workflowsPreview is usually tied to one site theme or one rendering layer.Drafts, Content Releases, and structured queries can feed Render staging services and preview environments.
Multi-channel reuseContent often needs cleanup before it can serve web apps, mobile apps, and agents.The same structured content can serve Render apps, mobile clients, and AI agents through Agent Context.

09 β€” Next 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 Render and 200+ other tools.