How to localize a block array with the internationalized array plugin in Sanity.io

5 replies
Last updated: Mar 14, 2024
Hello Sanity peeps,Does anyone know how to localize a block array with
the internationalized array plugin ? I have tried changing the type to "internationalizedArrayString" but that returns an error.

defineField({

name: 'information',

title: 'Information',

type: 'array',

of: [{ type: 'block'}],

}),
AI Update

You're trying to use the internationalized array plugin with block content (Portable Text), and getting an error with internationalizedArrayString. Here's how to properly configure it:

How the plugin actually works

When you configure the internationalized array plugin, the fieldTypes array tells it which field types to generate internationalized versions for. The plugin automatically creates new schema types based on what you pass in.

Configuration for block content

For your block array (Portable Text), you need to pass a field definition into fieldTypes:

import {defineConfig, defineField} from 'sanity'
import {internationalizedArray} from 'sanity-plugin-internationalized-array'

export default defineConfig({
  // ...
  plugins: [
    internationalizedArray({
      languages: [
        {id: 'en', title: 'English'},
        {id: 'fr', title: 'French'}
      ],
      fieldTypes: [
        'string', // This creates internationalizedArrayString
        defineField({
          name: 'information',
          type: 'array',
          of: [{type: 'block'}]
        })
      ],
    })
  ]
})

This configuration will create two new schema types:

  • internationalizedArrayInformation (the array wrapper)
  • internationalizedArrayInformationValue (the object containing your block content)

Using it in your schema

Then use it in your document schema like this:

defineField({
  name: 'information',
  title: 'Information',
  type: 'internationalizedArrayInformation',
})

Note that the type name is generated from the name field you provided in the fieldTypes configuration.

Important notes

Type naming: When you pass 'string' in fieldTypes, it creates internationalizedArrayString. When you pass a field definition with name: 'information', it creates internationalizedArrayInformation. The name gets converted to the type name, and the actual field inside becomes value.

Stored data structure: Your data will be stored as an array with language keys:

"information": [
  { "_key": "en", "value": [{type: 'block', ...}] },
  { "_key": "fr", "value": [{type: 'block', ...}] }
]

Querying: To query a specific language:

*[_type == "yourType"] {
  "information": information[_key == "en"][0].value
}

If you're still experiencing issues, make sure you're using the latest version of the plugin (check for updates beyond 1.6.2, as version 1.10.1+ fixed some Portable Text compatibility issues).

đź‘‹ I just want to caution you that field level translation of a portable text field will eat through your attribute limit and cause you massive headaches down the line.
That is a fair point. Guess I will localize on the document level in that case. Thanks!
user A
Did you use Document Level Localization in the end? Doesn't it cause issues down the line when you want to link to a certain page, for example, with document level localization if you use a reference field it would be possible to link to any of the translated items of that page, for example.
user P
This is probably not the answer that anyone wants to hear but I switched to StoryBlok because their internationalization had much better documentation that I could follow better.
user A
thanks for letting us know! It’s a super useful piece of feedback to bring to the product team.

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?