How can I make Metadata language specific? (i18n)
Answered
Satin Angora posted this in #help-forum
Satin AngoraOP
I have the type
I am not sure where the
Now this makes things complicated; I can't index
Also I can't enumerate string type literal
But I want to get values for
How can I solve this problem? Shouldn't I define language specific values for
Locale defined as export const i18n = {
defaultLocale: "tr",
locales: ["tr", "en"]
} as const
export type Locale = (typeof i18n)["locales"][number] and the dictionaries as const dictionaries = {
tr: () => import("./dictionaries/tr.json").then((module) => module.default),
en: () => import("./dictionaries/en.json").then((module) => module.default)
}
export const getDictionary =
async (locale: Locale) => dictionaries[locale]?.() ?? dictionaries.tr()I am not sure where the
generateMetadata takes it's parameters, but I thought they are same as RootLayout component, so I declared it as export async function generateMetadata(
{ params }: {params: { lang: string }},
parent?: ResolvingMetadata
): Promise<Metadata> {... because in the [i18n example](https://github.com/vercel/next.js/blob/canary/examples/app-dir-i18n-routing/app/%5Blang%5D/layout.tsx) RootLayout takes lang as a string, which I believe is due to app structure app/[lang]/....Now this makes things complicated; I can't index
getDictionary with string type, because the dictionaries Object can't be indexed with string. I can't write type to dictionaries, because then I lose access to the key autocompletion.Also I can't enumerate string type literal
Locale.But I want to get values for
Metadata which is defined in language.json files which is used as dictionaries.How can I solve this problem? Shouldn't I define language specific values for
Metadata using my current i18n setup?Answered by joulev
Now this makes things complicated; I can't index getDictionary with string type, because the dictionaries Object can't be indexed with string. I can't write type to dictionaries, because then I lose access to the key autocompletion.
Also I can't enumerate string type literal Locale.
if (!Object.keys(dictionaries).includes(params.lang)) {
return {};
}
const lang = params.lang as keyof typeof dictionaries;
const data = dictionaries[lang];2 Replies
@Satin Angora I have the type `Locale` defined as ts
export const i18n = {
defaultLocale: "tr",
locales: ["tr", "en"]
} as const
export type Locale = (typeof i18n)["locales"][number] and the `dictionaries` as ts
const dictionaries = {
tr: () => import("./dictionaries/tr.json").then((module) => module.default),
en: () => import("./dictionaries/en.json").then((module) => module.default)
}
export const getDictionary =
async (locale: Locale) => dictionaries[locale]?.() ?? dictionaries.tr()
I am not sure where the `generateMetadata` takes it's parameters, but I thought they are same as `RootLayout` component, so I declared it as ts
export async function generateMetadata(
{ params }: {params: { lang: string }},
parent?: ResolvingMetadata
): Promise<Metadata> {... because in the [i18n example](https://github.com/vercel/next.js/blob/canary/examples/app-dir-i18n-routing/app/%5Blang%5D/layout.tsx) `RootLayout` takes `lang` as a string, which I believe is due to app structure `app/[lang]/...`.
Now this makes things complicated; I can't index `getDictionary` with `string` type, because the `dictionaries` Object can't be indexed with `string`. I can't write type to `dictionaries`, because then I lose access to the key autocompletion.
Also I can't enumerate _string type literal_ `Locale`.
But I want to get values for `Metadata` which is defined in `language.json` files which is used as _dictionaries_.
How can I solve this problem? Shouldn't I define language specific values for `Metadata` using my current _i18n_ setup?
Now this makes things complicated; I can't index getDictionary with string type, because the dictionaries Object can't be indexed with string. I can't write type to dictionaries, because then I lose access to the key autocompletion.
Also I can't enumerate string type literal Locale.
if (!Object.keys(dictionaries).includes(params.lang)) {
return {};
}
const lang = params.lang as keyof typeof dictionaries;
const data = dictionaries[lang];Answer
Satin AngoraOP
TY @joulev I have learned new things about how TS works.