Issue with adding translations and multiple languages in Sanity

9 replies
Last updated: Dec 9, 2021
Hello, I have an issue when trying to add translations or multiple language in sanityI follow this official sanity tutorial on youtube:
https://www.youtube.com/watch?v=Rk70FSgTJeQ Minute: 1: 07

On my sanity, it gives an error:


Invalid property value
The property value is stored as a value type that does not match the expected type.


Developer info
The value of this property must be of type object according to the schema.

Mismatching value types typically occur when the schema has recently been changed.

The current value (string)
But type value that I put is already 'object', I'm not sure what else is the issue, this is my schema.js, will appreciate for any help:


{
      name: 'blog',
      type: 'document',
      title: 'Blog',
      fields: [
        {
          name: 'title',
          title: 'Title',
          type: 'object',
          fields: [
            {
              title: 'English',
              name: 'en',
              type: 'string'
            },
            {
              title: 'French',
              name: 'fr',
              type: 'string'
            }
          ]
        },
      ]
}
AI Update

This is a common issue when migrating existing content to a new internationalized schema structure. The error occurs because you already have documents in your dataset where title was stored as a simple string, but your new schema expects title to be an object with en and fr properties.

Here's what's happening: When you change a field from type: 'string' to type: 'object', Sanity doesn't automatically migrate your existing data. Any blog documents created before the schema change still have title: "some string value" instead of title: { en: "...", fr: "..." }.

Solutions

Option 1: Use Sanity's document internationalization plugin (Recommended)

Instead of manually creating nested object structures, use the @sanity/document-internationalization plugin. This is the official, supported approach for document-level translations and creates separate documents per language with proper references:

npm install @sanity/document-internationalization

Then configure it in your sanity.config.ts:

import {documentInternationalization} from '@sanity/document-internationalization'

export default defineConfig({
  plugins: [
    documentInternationalization({
      supportedLanguages: [
        {id: 'en', title: 'English'},
        {id: 'fr', title: 'French'}
      ],
      schemaTypes: ['blog']
    })
  ]
})

Your schema would then have a simple language field:

{
  name: 'blog',
  type: 'document',
  title: 'Blog',
  fields: [
    {
      name: 'title',
      title: 'Title',
      type: 'string' // Back to a simple string
    },
    {
      name: 'language',
      type: 'string',
      readOnly: true,
      hidden: true
    }
  ]
}

Option 2: Keep your object approach but migrate existing data

If you prefer the nested object structure from the tutorial, you need to migrate your existing documents. You can do this through the Vision plugin in your Studio or create a migration script:

  1. Temporarily revert title to type: 'string' to access your old data
  2. Create a migration to convert title: "Old Title" to title: { en: "Old Title", fr: "" }
  3. Update your schema back to the object structure

Option 3: Start fresh

If you're still in development without important content:

  1. Delete the existing blog documents from your dataset
  2. Keep your new schema
  3. Create new documents with the correct structure

Option 4: Use a different field name

Add a new field like localizedTitle with your object structure, leaving the old title field intact. This lets you gradually migrate content without breaking existing documents.

The tutorial approach works for new projects, but the document internationalization plugin is generally more robust for production use as it provides better querying capabilities, clearer separation between language versions, and works well with features like AI Assist for translation.

Hey User! Is this causing your Studio to crash or is it warning you that had already entered text into your
title
field as a string before you changed the schema to an object? If it's the latter, you can just unset the field to continue using your
localeString
.
It shows this when I added the fields for the language and change my type to object, before that everything is fine. I'm not sure what else is missing on my code.
// First, we must import the schema creator
import createSchema from 'part:@sanity/base/schema-creator'

// Then import schema types from any plugins that might expose them
import schemaTypes from 'all:part:@sanity/base/schema-type'

// Then we give our schema to the builder and provide the result to Sanity
export default createSchema({
  // We name our schema
  name: 'default',
  // Then proceed to concatenate our document type
  // to the ones provided by any plugins that are installed
  types: schemaTypes.concat([
    /* Your types here! */
    {
      name: 'author',
      type: 'document',
      title: 'Author',
      fields: [
        {
          name: 'name',
          title: 'Name',
          type: 'string'
        },
        {
          name: 'avatar',
          title: 'Avatar',
          type: 'image'
        }
      ]
    },
    {
      name: 'blog',
      type: 'document',
      title: 'Blog',
      fields: [
        {
          name: 'title',
          title: 'Title',
          type: 'object',
          fields: [
            {
              title: 'English',
              name: 'en',
              type: 'string'
            },
            {
              title: 'French',
              name: 'fr',
              type: 'string'
            }
          ]
        },
        {
          name: 'subtitle',
          type: 'string',
          title: 'Subtitle'
        },
        {
          name: 'coverImage',
          type: 'image',
          title: 'Cover Image',
          fields: [
            {
              type: 'text',
              name: 'alt',
              title: 'Description'
            }
          ],
        },
        {
          name: 'content',
          type: 'array',
          title: 'Content',
          of:[
            {
              type: 'block'
            },
            {
              type: 'image',
              fields: [
                {
                  type: 'text',
                  name: 'alt',
                  title: 'Description',
                  options: {
                    isHighlighted: true
                  }
                }
              ],
              options: {
                hotspot: true
              }
            },
            {
              type: 'code'
            }
          ]
        },
        {
          name: 'date',
          type: 'datetime',
          title: 'Date',
          validation: (Rule) => {return Rule.required()}
        },
        {
          name: 'author',
          type: 'reference',
          title: 'Author',
          to: [{type: 'author'}],
        },
        {
          name: 'slug',
          type: 'slug',
          title: 'Slug',
          validation: (Rule) => {return Rule.required()}
        }
      ]
    }
  ]),
})
Got it. It looks like you entered text into the field before you changed the schema to an
object
. You can click the
Reset Value
button and you'll be able to edit the field.
Thanks, it's fixed, I didnt know we just need to click the reset button, however, in my browser it shows this error now:
I dont know if I need to add internalization, but I follow this youtube video: https://www.youtube.com/watch?v=-bNYOn72c1g
It doesn't work, any input how to fix the error?

Also is there a video documentation that basically shows how to add multiple language or add translation using sanity and Next js? probably better so I can follow the tutorial, please advice
Is that error happening on your frontend? If so, it looks like you're trying to render the entire
title
object instead of
title.en
or
<http://title.fr|title.fr>
. I don't think anyone's ever created a Sanity/Next specific video for i18n. There's a guide on i18n routing here , though.
Is that error happening on your frontend? If so, it looks like you're trying to render the entire
title
object instead of
title.en
or
<http://title.fr|title.fr>
. I don't think anyone's ever created a Sanity/Next specific video for i18n. There's a guide on i18n routing here , though.
user M
I have another question, how should I create translation on the content blog sanity?
Under the content category, I tried to add the EN and FR following the video, but doesn't seem to work.

Also if I want to have 2 images en and fr, how should I add it in my schema?

please advice
🙏


        {
          name: 'content',
          type: 'array',
          title: 'Content',
          of:[
            {
              type: 'block'
            },
            {
              name: 'test',
              type: 'object',
              title: 'test',
              fields: [
                {
                  title: 'English',
                  name: 'en',
                  type: 'string'
                },
                {
                  title: 'French',
                  name: 'fr',
                  type: 'string'
                }
              ]
            },
            {
              type: 'image',
              fields: [
                {
                  type: 'text',
                  name: 'alt',
                  title: 'Description',
                  options: {
                    isHighlighted: true
                  }
                }
              ],
              options: {
                hotspot: true
              }
            },
            {
              type: 'code'
            }
          ]
        },
        

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?