Translate Payload CMS content in Crowdin without copying and pasting.
Documentation: thompsonsj.github.io/payload-crowdin-sync
Payload stores documents as nested JSON, and rich text as editor state. That's hard to translate directly. This plugin extracts the localized fields from every document and uploads them to Crowdin as clean files: HTML for rich text and JSON for everything else. It then writes the translations back into the right fields, however deeply nested.
- Uploads on save. Localized fields in collections and globals are sent to Crowdin when you save a draft or publish. Only fields that changed are uploaded again.
- Rich text as HTML. Slate and Lexical fields become HTML files that translators can edit in Crowdin's editor. Lexical blocks, uploads, relationships and tables are all converted back into Lexical when translations come in.
- Nested fields. Localized fields inside groups, arrays, blocks, tabs, collapsibles and rows are collected into a single
fields.jsonper document. - Tidy Crowdin projects. Each collection gets a folder, and each document gets a subfolder. Blocks inside a Lexical field get their own nested folders.
- Translations back in one click. Tick a checkbox in the admin panel to load translations for one locale or all of them, as a draft or published. You can also review changes first over REST, or run the sync as a Payload job.
- Safe updates. A translation that is missing a required field isn't applied, and validation errors are reported.
- Self-healing. If files or folders are deleted in Crowdin, the plugin removes its stale records and creates them again on the next save.
- Fine-grained control. Enable collections conditionally based on document data, and exclude individual fields from Crowdin.
npm install payload-crowdin-syncimport { buildConfig } from 'payload';
import { crowdinSync } from 'payload-crowdin-sync';
export default buildConfig({
plugins: [
crowdinSync({
projectId: 323731,
token: process.env.CROWDIN_TOKEN,
sourceLocale: 'en',
localeMap: {
de_DE: { crowdinId: 'de' },
fr_FR: { crowdinId: 'fr' },
},
}),
],
// The rest of your config goes here
});Save a document with localized fields, and its content appears in your Crowdin project:
When translations are ready, tick Sync all translations on the document and save:
Next: read the documentation for all options, supported fields and API endpoints.
This monorepo contains:
plugin/: thepayload-crowdin-syncpackage published to npmdev/: Payload install used for integration testsdocs-site/: the documentation site
npm install
npm run test
npm run docs:serveSee development and repository notes for testing, coverage, import maps and releases.