How to filter an array of linked documents based on the current language context.

4 replies
Last updated: Dec 13, 2023
Studio: Localized array references?Hey all,
πŸ–οΈ I am facing an issue with an array of linked documents (A featured Events List). The field lets me choose both languages, even though I am editing the current page in one specific language. How can I achieve – when users adding new items to the list –, to get rid of all the items in the list which are not in the current language context?
Thanks a lot in advance!
AI Update

Based on the documentation I found, here's how to filter reference options by the current document's language when using the Document Internationalization plugin:

When you have an array of references and want to filter them to only show documents in the current language context, you can use the dynamic filter function on your reference field. The plugin uses special metadata fields like __i18n_lang to track document languages.

Here's how to set it up:

{
  name: 'featuredEvents',
  title: 'Featured Events',
  type: 'array',
  of: [
    {
      type: 'reference',
      to: [{type: 'event'}],
      options: {
        filter: ({document}) => {
          // Make sure to check if the language field exists
          if (!document.__i18n_lang) {
            return {
              filter: '_type == $type',
              params: {type: 'event'}
            }
          }
          
          return {
            filter: '_type == $type && __i18n_lang == $lang',
            params: {
              type: 'event',
              lang: document.__i18n_lang
            }
          }
        }
      }
    }
  ]
}

Key points:

  1. The filter option accepts a function that receives an object containing document, parent, and parentPath properties
  2. The current document's language is stored in document.__i18n_lang when using the Document Internationalization plugin
  3. You can use this value in your GROQ filter to match only documents with the same __i18n_lang value
  4. Always check if the property exists before using it to avoid errors

This will ensure that when editors are adding items to the featured events list, they'll only see events that match the current document's language context.

The reference field documentation has more details on using dynamic filters, and you can learn more about the Document Internationalization plugin's structure in the internationalization docs.

You would need to change the
filter
on your reference field. What does that code currently look like?
Hey
user M
, thanks for responding!!

queries.ts
export const homePageQuery = groq`
  *[_type == "home" && language == $language][0]{
    _id,
    overview,
    featuredEvents[]->{
      _type,
      coverImage,
      overview,
      "slug": slug.current,
      tags,
      title,
      language,
    },
    title,
    language,
    "translations": *[
      _type == "translation.metadata" && 
      ^._id in translations[].value._ref
    ][0].translations[]{
      // and spread the "value" of each reference to the root level
      ...(value->{
        language,
        title,
        featuredEvents[]->{
          "slug": slug.current,
          title,
          language,
        },
      })
    }
  }
`

from home.ts (Schema)
…
defineField({
      name: 'featuredEvents',
      title: 'Featured events',
      description:
        'These are the events that will appear first on your landing page.',
      type: 'array',
      of: [
        defineArrayMember({
          type: 'reference',
          to: [{ type: 'event' }],
        }),
      ],
    }),
…
user M
EDIT: I could resolve by filtering like so:
defineField({
      name: 'featuredEvents',
      title: 'Featured events',
      description:
        'These are the events that will appear first on your landing page.',
      type: 'array',
      of: [
        defineArrayMember({
          type: 'reference',
          to: [{ type: 'event' }],
          options: {
            filter: ({ document }) => {
              return {
                filter: '_type == "event" && language == $language',
                params: { language: document.language },
              }
            },
          },
        }),
      ],
    }),
Nailed it!

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?