Help needed with implementing real-time content translation in Sanity CMS

8 replies
Last updated: Mar 13, 2023
Hi Guys, Hope everyone doing great.
We got stuck in one feature of sanity, we are using sanity for the first time. So any help would be appreciated.

Use case:
We want to implement a CMS for a website and we found Sanity
🤩 and loved it. But stuck in 1 feature. The feature is we want to translate the content from english to any given language in real time means when we update the content it will automatically convert into all the defined language.
For that we find out sanity provide a handy plugin for this usecase i.e.
@sanity/document-internationalization
. We tried to follow the steps that are given in the documation . So there are 3 steps to implement that1.
Enabling and configuring the plugin 2.
Activating internationalization on schema 3.
Customise Desk Structure (Added the coded snippet of
sanity.config.ts
for the reference)
We got stuck on the 3rd step, we also tired looking on the online for possible solution or demo for this step, couldn’t able to find any. Please help us guide through the process, any help would be appreciated.



plugins: withDocumentI18nPlugin(
    (pluginConfig) => [
      deskTool({
        structure: (S, {schema}) => getDocumentList({S, schema, config: pluginConfig}),
      }),
      visionTool(),
      documentI18n({
        base: 'en-us',
        languages: [
          {
            title: 'English (US)',
            id: 'en-us',
          },
          {
            title: 'Japanese (JP)',
            id: 'ja-JP',
          },
        ],
        idStructure: IdStructure.DELIMITER,
        referenceBehavior: ReferenceBehavior.STRONG,
        withTranslationsMaintenance: true,
        fieldNames: {
          lang: '__i18n_lang',
          references: '__i18n_refs',
          baseReference: '__i18n_base',
        },
      }),
    ],
    {}
  ),

AI Update

I need to be upfront with you about something important: the @sanity/document-internationalization plugin does NOT automatically translate content. It only manages the structure and relationships between different language versions of your documents.

When you update your English content, it will not automatically convert to Japanese or any other language. This is a critical expectation mismatch with what you described wanting. Let me explain what the plugin actually does and how to get the automatic translation you're looking for.

What the Plugin Actually Does

The @sanity/document-internationalization plugin creates a document structure where:

  • Each language version is a separate document (not automatic translations)
  • Documents are linked together through shared references
  • You get a nice UI in Studio to manage these relationships
  • You can see which translations exist and which are missing

When you create a Japanese version from your English document, you'll get an empty Japanese document that you need to fill in yourself. The plugin manages the structure of multilingual content, not the actual translation.

Fixing Your Desk Structure Issue

Your code looks mostly correct! The destructuring pattern (S, {schema}) is valid JavaScript. However, one thing to check: if you're on Studio v3+, the tool was renamed from deskTool to structureTool. Here's a complete working example:

import {defineConfig} from 'sanity'
import {structureTool} from 'sanity/structure' // renamed in v3
import {visionTool} from '@sanity/vision'
import {
  documentI18n,
  withDocumentI18nPlugin,
  getDocumentList,
  IdStructure,
  ReferenceBehavior,
  DeleteTranslationAction,
} from '@sanity/document-internationalization'

export default defineConfig({
  name: 'default',
  title: 'My Project',
  projectId: 'your-project-id',
  dataset: 'production',
  
  plugins: withDocumentI18nPlugin(
    (pluginConfig) => [
      structureTool({
        structure: (S, context) => 
          getDocumentList({
            S, 
            schema: context.schema, 
            config: pluginConfig
          }),
      }),
      visionTool(),
      documentI18n({
        base: 'en-us',
        languages: [
          {
            title: 'English (US)',
            id: 'en-us',
          },
          {
            title: 'Japanese (JP)',
            id: 'ja-JP',
          },
        ],
        idStructure: IdStructure.DELIMITER,
        referenceBehavior: ReferenceBehavior.STRONG,
        withTranslationsMaintenance: true,
        fieldNames: {
          lang: '__i18n_lang',
          references: '__i18n_refs',
          baseReference: '__i18n_base',
        },
      }),
    ],
    {}
  ),
  
  document: {
    actions: (prev, context) => {
      return [...prev, DeleteTranslationAction]
    },
  },
})

Don't forget to enable i18n on your document schemas:

export default {
  name: 'page',
  type: 'document',
  title: 'Page',
  i18n: true, // Enable internationalization for this type
  fields: [
    // your fields
  ],
}

How to Get Actual Automatic Translation

Since you want real-time automatic translation when content updates, you'll need to add one of these solutions on top of the document internationalization plugin:

Option 1: AI Assist with Translate Action (Easiest)

Sanity has built-in AI translation capabilities through Agent Actions. The Translate action is schema-aware and can translate your structured content while preserving field types, references, and document structure.

You can use it in two ways:

A) Manual translation in Studio - Using the AI Assist plugin, editors can click a button to translate documents. Requires a Growth plan or higher.

B) Automated translation - More relevant to your "real-time" requirement. Here's how:

Create a Sanity Function that automatically triggers when you update the base language document, then uses the Translate Agent Action to update related language documents. This gives you true automatic translation on content updates.

Here's the concept:

// In your Blueprint function
export default function(event) {
  // When English document is published
  if (event.document.__i18n_lang === 'en-us') {
    // Use Agent Actions to translate to Japanese
    await client.agent.action.translate({
      documentId: event.document._id,
      targetDocument: { operation: "create" },
      fromLanguage: {id: "en-US", title: "English"},
      toLanguage: {id: "ja-JP", title: "Japanese"},
      protectedPhrases: ["YourBrandName"]
    });
  }
}

Sanity Functions run on Sanity's infrastructure (no external hosting needed), support Node.js v22, and integrate directly with your content. This is the modern, recommended approach for automation.

Option 3: External Translation APIs

You could also use Functions to call external translation services like Google Translate, DeepL, or OpenAI to translate content and write it back to the Japanese documents.

What You'll Get After Setup

Once your desk structure is working with the plugin, you'll see:

  • Documents grouped by language with a language switcher in the UI
  • Visual indicators showing which translations exist
  • A "Translation Maintenance" tab showing missing translations
  • The ability to create new language versions from the base document

But remember: those language versions start empty until you fill them (manually or with automation).

Summary

The @sanity/document-internationalization plugin is fantastic for managing multilingual content structure, but it's not a translation tool itself. For your use case of automatic translation when content updates, you'll want to:

  1. ✅ Use the document internationalization plugin for structure
  2. ✅ Add Sanity Functions + Agent Actions for automatic translation
  3. ✅ This combination gives you the real-time translation workflow you described

Welcome to Sanity! 🎉 The platform is incredibly powerful for multilingual content once you layer these pieces together.

Just to clarify, your content won’t automatically be translated by that plugin. It just allows you an ergonomic way of switching between different translation documents. If you’d like to have translations done, you’ll need to use a third party service.
user M
okay understood. Do you know any services which can helps us with our usecase
Also we are thinking that, we can use the sanity webhook to generate the content in multiple languages and then push those data into the sanity.
Let me know if it can work or not. Also if you have any other good suggestion please do let me know
This turned up on Google -- our usual friends, and not free, but USD 0.50 per 'page' is pretty cheap for competent translation. All the needed detail seem visible from this link, if it also marketerspeaks... Google Translation Hub .
How you would sensibly distribute the results to accesible pages,
user M
or compatriots might have good ideas about, and it would be interesting to hear...best fortune, @Aman.
We don’t currently have any V3 compatible plugins for managing this within the Studio, but you can see a couple of V2 plugins in this search.
user M
Are you planning to update the Google Translation plugin to support version 3 any time soon? https://github.com/sanity-io/sanity-plugin-google-translate
Not that I’m aware of

Sanity – Build the way you think, not the way your CMS thinks

Sanity is the developer-first content operating system that gives you complete control. Schema-as-code, GROQ queries, and real-time APIs mean no more workarounds or waiting for deployments. Free to start, scale as you grow.

Was this answer helpful?