Set a fallback locale

It would be nice to set a fallback locale that in case the other locales aren’t filled when you request the particular locale, it would be filled by the fallback locale.

And maybe there’s a switch on the field/model on whether the field is filled with the fallback locale or left as blank/null.

hello @hesedel.pajaron welcome :slight_smile:

Where would you like to see the fallback values? Directly in the APIs?

Currently we have implemented that logic in the Gatsby source plugin and in our Middleman extension, maybe you can already use those?

Hi @mat_jack1, thanks for the reply!
Well, I would’t first think of using plugins meant for other static site generators.
I also wrote my own logic to merge the missing fields.
I assume the plugin also uses DatoCMS Content Delivery API? And fetches both languages then merges?

It would be great if this was already returned by the API when querying.

Yes, I’m not sure what you are using yourself, I mentioned our plugins as examples.

We are using the REST API in the plugins at the moment, we want to switch to GraphQL but it’s not done yet. But yes, we merge the information in the plugin right now.

OK, we’ll consider returning the fallback already in the API, would be good for us too :slight_smile:

1 Like

I’m just using a deepmerge with another language and English.
This is fine at the moment as I’m doing this when building the project.
But I’ll soon be using it on the client side and would rather not have to do the double request and merging there.
Thanks!

definitely useful :+1:

Graphcms has this kind of fallback (https://graphcms.com/docs/reference/localization) that looks nice:

Defining a Fallback

   {
      messages(locales: [de_ch, de, en]) {
        subject
        locale
      }
    }

Locales will be served in the order they are requested, left to right (Swiss German, German, English).

4 Likes

It’s quite strange that localization can be optional but doesn’t have a fallback setting. Such API is quite error prone imo. Also manually querying fallback language results in over-fetching and complexity on the client side. This is quite frustrating for my project since I have to deal with 5 languages, otherwise I would love to use datocms.

I also think the “required” validator on localized fields could improve to “require on primary language” or “require on all languages”.

Right now, if I have multiple localized fields in a model, I want them all required but the user only wants to translate one field, it is not possible. The moment you add a language for a record, every required field must have a value…

We would also love to see a fallback locale. We are using Ruby with the GraphGQL API, and could have any number of locales but won’t necessarily translate EVERY piece of content into EVERY language. This currently means either doing double-fetches or pulling back every locale which is very expensive.

It would be much better if we could specify an array of fallbacks like @thomas.iacopino suggested.

Hi !

We’d also love to see this feature implemented.
Here are two implementations ideas that may help !

Current state

We can query all languages.

query {
  myModel {
     _allTitleLocales {
      value
      locale
    }
  }
}

And then find a value

// Just for the example. It can be optimized
const found = data._allTitleLocales.find(locale => userLocale === locale)
if (found) {
  return found
}
return data._allTitleLocales.find(locale => defaultLocale === locale)

However, this solution requires querying all locales when we may just need one (that can be an issue when querying a lot of data on the client side).
Also, this needs more implementation on the client.

GraphQL implementation: new fallbackLocales query filter

query {
  myModel {
    title(locale: fr, fallBackLocales: [en, de])
  }
}

This query would return the FR value if it is not empty. Or the EN value. Or the DE value.

Admin implementaion: model configuration

An alternative solution would be to add a default language field on the model configuration.

For example:

When this multi-select value is set to “it, en, fr”.
The following query would return the title value for IT locale if CN value is empty.

query {
  myModel {
    title(locale: cn)
  }
}

Required one default value

The advantage of the model-side implementation would allow another linked feature.
Currently, when the field is required, we need to fill the translations for every locales.

That would be awesome to have a field configuration (in the validation tab) to have a only one default value.
We can mark the field required without requiring all translations.

So, we have :

  • 10 locales in our project/model
  • Field Title i18n
  • Field Title with default language for en, fr
  • Field Title with required at least one locale

We can save the following record (without validation error because there is one value for a default language) :

{
  "title": {
    "en": "My Title",
    "fr": "",
    "cn": ""
  }
}

The following query

query {
  myModel {
    title(locale: cn)
  }
}

returns

{
  "title": "My Title"
}

What’s your thoughts on this ?
Thanks !

While we are still waiting for this feature, can we at least request to query a field that tells us whether the locale is present or not?

At the moment, even if a locale has not been added to a record in Dato, it is still possible to query that locale while getting back blank content, which doesn’t help to know if this is intentional or not, especially not every field is blank (only localized ones).

To at least facilitate the need for a double-fetch, it would be very helpful to receive a field that tells us whether the locale has been added to the record or not.

query {
  myModel(locale: fr) {
    _hasLocale
    title
    description
    linkedModel {
      _hasLocale
      content
    }
  }
}

hey @seth.jeffery

if you have a required field that is translated, what you can do is to fetch _allFieldLocales and see for which locales the field exists. Like this for example:

query MyQuery {
  allArticles {
    _allTitleLocales {
      locale
      value
    }
  }
}

If a locale is empty you get it like this:

{
   "locale": "en",
   "value": ""
}

Hope this works for you.

Thank you. While we have just 2 or 3 locales this seems like a good workaround.

When we end up with 20-30, I hope by then for a solution that won’t need to retrieve a huge data packet!

I would be very interested in this, any ETA?

Hello, we’re working on this, almost ready to launch.

We’re going to add a _locales field which will return the array of localizations for a particular record:

{
  allPosts {
    _locales  // returns ["it", "en"]
  }
}

A filter on _locales to only get records that have a certain set of localizations available (the following will return all records with both en and it locales):

{
  allPosts(filter:{_locales:{allIn:[en, it]}}) {
    title
  }
}

We’re also going to add a new fallbackLocales field. In the following example, if there’s no it_IT localization, or the it_IT localization has no title (null or empty string), then it will try to find a value in it, and then en locales:

{
  allPuppas(locale:it_IT, fallbackLocales:[it, en]) {
    title
  }
}

Any thoughts?

Thanks so much @s.verna!

5 Likes