Creating a custom input component to search for documents with the same language as the current workspace.

2 replies
Last updated: Apr 9, 2024
Hi all.
I'm looking to make a custom input component and trying to see if something like this is possible.

On my site, I'm currently using the
document localisation plugin in order to create a "multisite". Aka, one admin dashboard, three websites. The schema and structure is the same throughout all three sites.
What I'm wanting to create is a replica of the reference search component. However, I'd like to be able to only search for documents with the same language as the current workspace (the workspace and the language ID's are the same for each unique site).

It's a bit of a pain trying to link to say, the homepage, but having three distinct homepages popup every time you search.

Is there any way of doing this?
AI Update

Absolutely! You can filter reference inputs based on the current workspace/language by using the options.filter function on your reference field. This function has access to the document context, which you can use to match against the workspace language.

Here's how to set this up:

{
  name: 'homepageReference',
  type: 'reference',
  to: [{type: 'page'}],
  options: {
    filter: ({document}) => {
      // Get the current document's language
      const currentLanguage = document.__i18n_lang || document.language
      
      return {
        filter: '_type == $type && __i18n_lang == $language',
        params: {
          type: 'page',
          language: currentLanguage
        }
      }
    }
  }
}

The key points here:

  1. The filter function receives context objects including document, parent, value, and currentUser. You can use document to access the current document's language field.

  2. Return both filter and params: As shown in the Sanity docs on reference filters, when using a filter function, you need to return an object containing both the filter (GROQ query string) and params (the parameter values).

  3. Match the language field name: The exact field name depends on how your document localization plugin stores language info. Common patterns:

    • __i18n_lang for the @sanity/document-internationalization plugin
    • language for custom implementations
    • Check your plugin's documentation for the exact field name
  4. Filter by document type and language: The GROQ filter _type == $type && __i18n_lang == $language ensures you only see documents of the correct type AND matching language.

Alternative approach using the parent context:

If you're using this reference field inside an object or array, you might need to access the root document differently:

options: {
  filter: ({document, parent}) => {
    // For nested fields, traverse up to get the root document's language
    const currentLanguage = document?.__i18n_lang || document?.language
    
    return {
      filter: '_type == $type && __i18n_lang == $language',
      params: {
        type: 'page',
        language: currentLanguage
      }
    }
  }
}

This approach works great for multisite setups where workspace names match language IDs, and it will significantly clean up your reference selection UI by only showing relevant documents for the current language context!

You’ll want to use a dynamic filter on your reference. If you’re using that plugin, you most likely have the
lang
set on the document, which will show up in the context that’s passed into your filter function.
Amazing thank you!!

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?