# Sanity field-level i18n arrays and preferredLocale, who resolves the language?

Asked by Malin Aas on 2025-02-05. Tags: sanity, i18n, localization.

We run a Norwegian public sector site where documents store translations as
internationalized arrays per field, so a title is `[{_key: "nb", value: "..."},
{_key: "nn", value: "..."}, {_key: "en", value: "..."}]`.

I am reading the Croct docs and see that fetches accept a `preferredLocale`
option. What I cannot work out is the division of responsibility. If I pass the
whole i18n array as the fallback, does anything resolve it? Or should my code
pick the locale value first and pass a flat object?

Language fallback chains matter a lot for us (nn falls back to nb, never to en),
so I want the resolution to happen in exactly one place.

## 2 answers

### Answer from jonas_w (2025-02-05)

Resolve the array yourself, before the slot fetch. The `preferredLocale`
option tells Croct which locale's variant content to serve for the slot, but
it does not know anything about Sanity's i18n array structure, that is a
convention of your dataset, not a content format Croct parses.

So the clean split is: your code resolves the i18n array to the active locale
(applying your nn to nb fallback chain), producing a flat object, and that
flat object is what you pass as the fallback. Then both sources render
identically: Croct-served content is already in the requested locale, and the
fallback is too. Your locale logic lives in exactly one function, which sounds
like what you want.

If you pass the raw array as fallback, the component either needs to handle
two shapes or breaks when the fallback kicks in, which is the worst possible
time to discover it.

### Answer from petra_l (2025-02-06)

Adding the other half of the picture: on the Croct side, per-locale default
content (the localization feature) is an add-on, but you may not need it for
your setup. Multi-language works without extra dev because the localized
Sanity value remains the per-locale fallback, so each locale already renders
the right default through your own resolution. The add-on matters when you
want locale-specific defaults managed inside Croct itself rather than falling
back to what your code passes in.
