How to Integrate Crowdin with Your Headless CMS
Send structured content from your headless CMS to Crowdin the moment it’s published, then bring approved translations back for localized websites, apps, docs, and AI agents.
What is Crowdin?
Crowdin is a cloud localization platform for translating software strings, websites, documentation, mobile apps, and product content. Teams use it to coordinate source files, target languages, translation memory, glossaries, machine translation, human review, and delivery workflows. It sits in the translation and localization category alongside tools like Lokalise, Phrase, Smartling, and Transifex.
Why integrate Crowdin with a headless CMS?
Localization gets messy when content lives in one system and translation work happens somewhere else. A marketer publishes an English product page, exports a spreadsheet, emails it to a localization manager, waits for translations, copies strings back into the site, and repeats the same work for French, German, Japanese, and Spanish. That process breaks down fast when you have 50 landing pages, 300 product descriptions, and release notes shipping every week.
Connecting Crowdin to a headless CMS category system gives you a repeatable path: source content is sent to Crowdin, translators work with translation memory and glossary rules, and approved translations return to the content source. With Sanity, the source is structured JSON in the Content Lake, so the integration can send only the fields Crowdin needs, such as title, description, SEO text, CTA labels, and Portable Text blocks. GROQ handles precise field selection, and webhooks or Functions can start the sync when a document is published.
The trade-off is that you need to define your mapping. Crowdin works with files, projects, branches, directories, and language targets, while your content model may use documents, references, and field-level localization. That mapping is worth doing once. After that, you’re not asking translators to work from screenshots, pasted HTML, or unclear CSV columns.
Architecture overview
A typical Sanity and Crowdin integration starts when an editor publishes source-language content in Sanity Studio. A Sanity webhook listens for publish events, usually filtered by document type, language, or release state. The webhook calls a Sanity Function or a small middleware endpoint. That function uses @sanity/client and GROQ to fetch the exact translatable fields from the Content Lake. For example, it can query an article title, SEO description, CTA label, product reference title, and Portable Text children while leaving internal notes, pricing rules, and analytics fields out of the payload. The function then converts the content into a Crowdin-friendly file, often JSON with stable keys. It calls Crowdin’s Upload Storage API through the @crowdin/crowdin-api-client package, then creates or updates a source file in a Crowdin project with Source Files API methods such as createFile or updateFile. Crowdin handles target languages, translation memory, glossary matches, machine translation suggestions, screenshots, review, and translator assignment inside the project. When translations are ready, you have two common return paths. Crowdin can send a webhook when a file is translated, or your integration can call Crowdin’s Translations API to build and download translated files. The integration then writes localized fields or localized documents back to Sanity. Your frontend queries by locale, for example, /fr/products/running-shoe or /ja/docs/getting-started, and renders the translated content from the same structured back end that powers web, mobile, Crowdin, and AI agents.
Common use cases
Localized marketing pages
Publish an English landing page in Sanity, send selected fields to Crowdin, and return reviewed French, German, Spanish, and Japanese versions before campaign launch.
Product UI and app copy
Keep onboarding text, empty states, CTA labels, and release notes in structured content, then sync those strings into Crowdin projects by app, platform, or release branch.
Documentation translation
Send docs pages, headings, code-adjacent explanations, and metadata to Crowdin while preserving stable keys so translation memory improves with every update.
Glossary-controlled product content
Use Crowdin glossaries and translation memory for product names, regulated claims, and support terms while Sanity keeps the content structured by market and channel.
Step-by-step integration
- 1
Set up Crowdin
Create a Crowdin project, choose source and target languages, and note the project ID from the project settings. Create a personal access token in Crowdin under Account Settings, API. For a Node or TypeScript integration, install @crowdin/crowdin-api-client and @sanity/client.
- 2
Model translatable content in Sanity Studio
Add fields that make localization explicit, such as locale, translationStatus, crowdinFileId, and sourceDocument. Keep stable field names for source strings, such as title, summary, seoDescription, ctaLabel, and body. If you use Portable Text, decide whether you’ll send blocks as structured JSON or flatten only text spans.
- 3
Create the sync trigger
Add a Sanity webhook filtered to published source-language documents, for example, product, article, or landingPage where locale == 'en'. Point it at a Sanity Function or your own webhook listener. Use the webhook payload only as the trigger, then fetch the current document from the Content Lake with GROQ.
- 4
Push source files to Crowdin
In the function, convert the Sanity document into a JSON file with stable keys. Call Crowdin’s Upload Storage API to upload the file content, then call the Source Files API to create the file in the Crowdin project. In production, save the returned Crowdin file ID back to Sanity so future publishes update the same file instead of creating duplicates.
- 5
Bring translations back
Use a Crowdin webhook for translated or approved files, or run a scheduled job that calls Crowdin’s Translations API to build and download target-language files. Map translated values back into localized Sanity documents or localized fields, then mark translationStatus as ready or needsReview.
- 6
Test the frontend experience
Build locale-aware routes and queries, such as *[_type == 'product' && slug.current == $slug && locale == $locale][0]. Test missing translations, fallback behavior, preview mode, and cache invalidation before sending the workflow to translators.
How Sanity + Crowdin works
Build your Crowdin integration on Sanity
Sanity gives you the structured content foundation, real-time event system, and flexible APIs you need to connect Crowdin to your localization workflow.
Start building free →CMS approaches to Crowdin
| Capability | Traditional CMS | Sanity |
|---|---|---|
| Source content shape | Content often sits inside pages, templates, or HTML fields, so translation exports may include markup and unrelated text. | The Content Lake structures content as typed JSON, and GROQ can return one translation-ready payload with fields and references in a single query. |
| Sync trigger | Teams often export files manually or run scheduled plugins that may miss last-minute publish changes. | Webhooks can filter publish events, and Functions can run the Crowdin sync logic server-side without separate infrastructure. |
| Field-level control | Translators may receive full pages, including fields that shouldn’t be translated, such as tracking snippets or internal notes. | GROQ can project only translatable fields, join referenced content, and shape stable JSON keys for Crowdin files. |
| Translation return path | Approved translations often come back through imports that overwrite page content if the mapping changes. | Localized documents or fields can be patched back into the Content Lake, with explicit status fields, references, and fallback queries. |
| Multi-channel delivery | Localized content is usually tied to the website where it was authored. | The same localized content can power websites, mobile apps, docs, commerce surfaces, Crowdin sync, and AI agents from one structured back end. |
| Operational trade-off | Setup can be easier if a plugin matches your exact workflow, but custom localization rules get harder over time. | You still define the Crowdin mapping, file naming, and fallback rules, but the content structure, event triggers, and query layer are built for that work. |
Keep building
Explore related integrations to complete your content stack.
Sanity + Lokalise
Send structured product, app, and marketing copy from Sanity to Lokalise for translation workflows across web and mobile teams.
Sanity + Phrase
Connect Sanity content models to Phrase projects so product strings, docs, and campaign content can move through review and return by locale.
Sanity + Smartling
Use Smartling for enterprise translation workflows while Sanity keeps localized content structured for websites, apps, and AI agents.