Querying for default locale docs when specific locale docs are missing in multi-lingual project

4 replies
Last updated: May 12, 2021
Hello! I am working on a multi-lingual project. Which has 3 locales en-SG, en-VN, and vi-VN. Among them, en-SG is a default locale.
Is this possible to query the docs in a way so that when there is no doc for any locale(especially en-VN) the site shows the default locale doc?

I have achieved something similar with this query.


*[_type == "cardPage" && (__i18n_lang == $locale || __i18n_lang == $defaultLocale ) && !(_id in path('drafts.**'))]
But it's not working properly when the $locale doc available, it's querying the $locale doc and $defaultLocale doc at the same time. And showing the $defaultLocale doc instead of the actual $locale doc on some pages.

I am using nextjs for front end and
sanity-plugin-intl-input plugin for localization.
May 9, 2021, 6:02 AM
This would return two results if there is a locale-specific document, right? One result for the locale-specific one, and one result for the default one. So on the client side you’d have to look at the results and pick the right one.
May 9, 2021, 10:30 AM
There’s a way you can do this in a single query. It’s a bit hacky, but it will work.

{
  "doc": *[_type == "cardPage" && __i18n_lang == $locale && !(_id in path('drafts.**'))][0]
} | {
  "doc": select(
    doc != null => doc,
    *[_type == "cardPage" && __i18n_lang == $defaultLocale && !(_id in path('drafts.**'))][0]
  )
}.doc
This is equivalent to:


let doc = getLocaleSpecificDoc()
doc != null ? doc : getDefaultDoc()
But since GROQ doesn’t have variables, we have go through an object.
May 9, 2021, 10:37 AM
I thought of another solution, in case you’re interested:

*[_type == "cardPage" && (__i18n_lang == $locale || __i18n_lang == $defaultLocale)] {
  ...,
  "priority": select(__i18n_lang == $locale => 0, 1)
} | order(priority) [0]
This is like sorting on a computed column in SQL. If you want to get rid of the temporary
priority
filed, just add:
| { .., "priority": null}
at the end.
May 12, 2021, 7:43 AM
I thought of another solution, in case you’re interested:

*[_type == "cardPage" && (__i18n_lang == $locale || __i18n_lang == $defaultLocale)] {
  ...,
  "priority": select(__i18n_lang == $locale => 0, 1)
} | order(priority) [0]
This is like sorting on a computed column in SQL. If you want to get rid of the temporary
priority
filed, just add:
| { .., "priority": null}
at the end.
May 12, 2021, 7:43 AM

Sanity– build remarkable experiences at scale

Sanity is a modern headless CMS that treats content as data to power your digital business. Free to get started, and pay-as-you-go on all plans.

Was this answer helpful?