Translation & Localization8 min read

How to Integrate Smartling with Your Headless CMS

Connect Smartling to your headless CMS so source content can move from publish to translation workflows, review, and localized delivery without copy-and-paste handoffs.

Published April 29, 2026
01Overview

What is Smartling?

Smartling is an enterprise localization platform for translating digital content, product copy, websites, apps, documents, and support content. It combines translation workflow, translation memory, glossaries, machine translation, human review, visual context, and APIs for teams that ship content across multiple languages. Localization, marketing, product, and content operations teams use Smartling when translated content needs approvals, quality checks, and repeatable workflows.


02The case for integration

Why integrate Smartling with a headless CMS?

If your team publishes in 5, 12, or 40 locales, translation handoffs can become the slowest part of the release. A product page goes live in English, someone exports fields to a spreadsheet, another person uploads files to Smartling, translators ask which headline belongs to which page section, and then localized copy gets pasted back into the wrong field. That works for a few pages. It breaks when you have hundreds of articles, product descriptions, legal notices, and campaign pages changing every week.

Connecting Smartling to a headless CMS lets you send structured source content directly into translation workflows. Instead of sending full pages or raw HTML, you can send the exact fields translators need, such as title, excerpt, body, CTA label, SEO title, and alt text. With Sanity's AI Content Operating System, content in the Content Lake is typed JSON, so Smartling receives clean field names and predictable JSON files. GROQ can select only translatable fields, including referenced content like product names or category labels.

The alternative is disconnected work: manual exports, folder conventions, stale translation memory context, and no reliable way to know whether a translation matches the current source. Webhooks and Functions reduce that risk. A publish event can trigger a Smartling upload within seconds, and a Smartling callback can write completed translations back to the right localized document. You still need to define locale rules, review workflows, and fallback behavior. The integration won't decide those for you. But once those rules are clear, the handoff becomes repeatable.


03Architecture

Architecture overview

A typical Sanity and Smartling integration starts when an editor publishes source-language content in Sanity Studio. A Sanity webhook filters for the document types and events you care about, for example published articles where language == "en". The webhook sends the document ID to a Sanity Function or your own webhook endpoint. That server-side code fetches the full source document from the Content Lake with GROQ. The query can project only the fields Smartling should translate, such as title, slug, body, SEO fields, CTA labels, image alt text, and referenced category names. The function then authenticates with Smartling's Auth API using a user identifier and user secret, creates a JSON payload, and uploads it to the Smartling Files API at /files-api/v2/projects/{projectId}/file with fileType=json, fileUri set to a stable path like articles/my-post.json, and authorize=true when you want Smartling to start translation authorization immediately. From there, Smartling routes the file through the project's workflow, translation memory, glossary, machine translation, human review, and quality checks. When translations are ready, your integration can use a Smartling callback or scheduled check to download each locale's translated file from the Files API. The final step writes localized fields back into Sanity as locale-specific documents or field-level translations. Your frontend then queries the right locale from the Content Lake and renders localized content for web, mobile, or any other channel.


04Use cases

Common use cases

🌍

Global marketing launches

Send campaign pages, SEO fields, CTA labels, and image alt text to Smartling when English content is published, then return approved translations to locale-specific Sanity documents.

🧩

Product copy with placeholders

Translate JSON content while preserving variables, product names, ICU messages, and structured fields that shouldn't be edited by translators.

📚

Help center localization

Route articles, categories, and related links through Smartling workflows so support content stays aligned across languages after source updates.

👀

Translation review with context

Send page metadata, preview URLs, and field labels from Sanity so Smartling reviewers can understand where each string appears.


05Implementation

Step-by-step integration

  1. 1

    Set up Smartling project access

    Create or choose a Smartling project, confirm the source locale and target locale IDs, and generate API credentials from Smartling. You'll need userIdentifier, userSecret, and projectId. If your team uses Smartling's SDK for your runtime, install it. The example below calls Smartling's REST API directly, which is the clearest path for a small webhook handler.

  2. 2

    Model localizable content in Sanity Studio

    Add fields that make translation state explicit. For example: language, translationGroup, title, slug, body, seoTitle, seoDescription, smartlingFileUri, smartlingStatus, and references to localized variants. Keep non-translatable fields, such as IDs, SKUs, and routing keys, separate from copy fields.

  3. 3

    Create a publish trigger

    Create a Sanity webhook that fires on publish events for source-language documents, or use a Sanity Function if you want the sync logic to run inside Sanity's server-side event system. Configure the webhook payload to include at least the document _id and _type.

  4. 4

    Fetch the exact fields Smartling needs

    Use @sanity/client and GROQ in the handler to fetch translatable fields, join referenced labels, and omit internal fields. This avoids sending draft metadata, workflow fields, or HTML that translators shouldn't touch.

  5. 5

    Upload JSON to Smartling

    Authenticate with Smartling's Auth API, then upload the JSON file to the Files API with a stable fileUri. Use fileType=json so Smartling can parse the payload, apply translation memory, and keep translated keys aligned with the source.

  6. 6

    Test the localized frontend path

    Publish one source document, confirm the file appears in Smartling, complete a test translation, download or receive the translated JSON, write it back to Sanity, and query it from your frontend by locale. Test fallback behavior when one locale is missing or still in review.


06Code

Code example

typescriptapp/api/smartling-sync/route.ts
import { createClient } from '@sanity/client';
import { NextRequest, NextResponse } from 'next/server';

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

export async function POST(req: NextRequest) {
  const { _id } = await req.json();

  const doc = await sanity.fetch(`*[_id == $id][0]{
    _id, title, "slug": slug.current, body, seoTitle, seoDescription,
    "category": category->title
  }`, { id: _id });

  if (!doc?.slug) return NextResponse.json({ skipped: true });

  const authRes = await fetch('https://api.smartling.com/auth-api/v2/authenticate', {
    method: 'POST',
    headers: { 'content-type': 'application/json' },
    body: JSON.stringify({
      userIdentifier: process.env.SMARTLING_USER_IDENTIFIER,
      userSecret: process.env.SMARTLING_USER_SECRET,
    }),
  });

  const auth = await authRes.json();
  const accessToken = auth.response.data.accessToken;
  const fileUri = `articles/${doc.slug}.json`;

  const form = new FormData();
  form.set('file', new Blob([JSON.stringify(doc)], { type: 'application/json' }), `${doc._id}.json`);
  form.set('fileUri', fileUri);
  form.set('fileType', 'json');
  form.set('authorize', 'true');

  const uploadRes = await fetch(
    `https://api.smartling.com/files-api/v2/projects/${process.env.SMARTLING_PROJECT_ID}/file`,
    { method: 'POST', headers: { authorization: `Bearer ${accessToken}` }, body: form }
  );

  if (!uploadRes.ok) return NextResponse.json({ error: await uploadRes.text() }, { status: 502 });
  return NextResponse.json({ fileUri, smartling: await uploadRes.json() });
}

07Why Sanity

How Sanity + Smartling works

Build your Smartling integration on Sanity

Sanity gives you the structured content foundation, real-time event system, and flexible APIs you need to connect Smartling to your localization workflow.

Start building free →

08Comparison

CMS approaches to Smartling

CapabilityTraditional CMSSanity
Translation payload structureOften exports page HTML or plugin-specific formats, which can mix layout, copy, and metadata.Uses GROQ to send a single, typed JSON payload with only the fields Smartling should translate.
Sync timing after publishOften depends on scheduled exports, editor actions, or translation plugin queues.Webhooks and Functions can start the Smartling upload when source content is published.
Locale modelingLocale structure is often tied to pages, folders, or plugin rules that are hard to change later.Schema-as-code lets you model field-level locales, document-level locales, translation groups, and fallback rules.
Translator contextContext may be limited to page URLs or exported screenshots.Can include preview URLs, field labels, categories, and related content in the Smartling JSON payload.
Writing translations backTranslated content may be pasted into pages or imported through plugin-specific mappings.APIs can write translated fields back into locale documents while preserving references, drafts, and editorial workflows.
Multi-channel deliveryLocalized content is often tied to one website delivery path.The same localized structured content can serve web, mobile, search, Smartling sync, and AI agents.

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 Smartling and 200+ other tools.