#Add custom i18n keys in Starlight?
30 messages · Page 1 of 1 (latest)
To add custom keys to your site's translation dictionaries in Starlight, you can use the extend option in the i18nSchema() function. Here's an example of how to add a new, optional custom.label key to the default keys:
import { defineCollection, z } from 'astro:content';
import { docsSchema, i18nSchema } from '@astrojs/starlight/schema';
export const collections = {
docs: defineCollection({ schema: docsSchema() }),
i18n: defineCollection({
type: 'data',
schema: i18nSchema({
extend: z.object({
'custom.label': z.string().optional(),
}),
}),
}),
};
In this example, custom.label is a new key added to the default keys. You can add as many keys as you need by extending the object passed to z.object(). For example:
extend: z.object({
'custom.label': z.string().optional(),
'custom.key1': z.string().optional(),
'custom.key2': z.string().optional(),
// Add more keys as needed
}),
You can learn more about content collection schemas in the Astro documentation (https://docs.astro.build/en/guides/content-collections/#defining-a-collection-schema).
Source: Starlight Guide - Extend Translation Schema (https://starlight.astro.build/guides/i18n/#extend-translation-schema)
Note: you can ask me a follow up question by @ mentioning me again :speech_balloon:
@glossy plover kapa.ai is still learning and improving, please let us know how it did by reacting below
@inner moat I think adding every key as 'custom.label': z.string().optional(), is too complex, is there a way to make it simpler-written?
Let me check the knowledge base for you. One moment! :books:
The current design of the i18nSchema function in Starlight requires you to define each key individually. This is because each key is associated with a specific validation schema (z.string().optional() in this case). This design provides flexibility and control over the data types and validation rules for each key.
However, if you have a large number of keys and they all share the same validation schema, you could potentially simplify the code by programmatically generating the object passed to z.object(). Here's an example:
const keys = ['custom.label', 'custom.key1', 'custom.key2']; // Add your keys here
const schemaObject = keys.reduce((obj, key) => {
obj[key] = z.string().optional();
return obj;
}, {});
export const collections = {
docs: defineCollection({ schema: docsSchema() }),
i18n: defineCollection({
type: 'data',
schema: i18nSchema({
extend: z.object(schemaObject),
}),
}),
};
In this example, keys is an array of your custom keys. The reduce function is used to generate an object where each key is associated with z.string().optional().
Please note that this is a JavaScript technique and not specific to Starlight or Astro. Always ensure that your code meets the requirements of your project and follows best practices for the libraries and frameworks you are using.
Source: Starlight Guide - Extend Translation Schema (https://starlight.astro.build/guides/i18n/#extend-translation-schema)
Note: you can ask me a follow up question by @ mentioning me again :speech_balloon:
@glossy plover kapa.ai is still learning and improving, please let us know how it did by reacting below
@inner moat Then how do I add the localizations of the keys?
Let me check the knowledge base for you. One moment! :books:
To add localizations for your custom keys, you need to add the translations to your JSON files in the src/content/i18n/ directory. Each JSON file corresponds to a specific locale and contains key-value pairs where the keys are the ones you defined in your schema and the values are the translations.
Here's an example of how you might add translations for the custom.label key in English and French:
src/content/i18n/en.json
{
"custom.label": "Custom Label in English",
// Add more keys as needed
}
src/content/i18n/fr.json
{
"custom.label": "Libellé personnalisé en français",
// Add more keys as needed
}
In these examples, custom.label is the key you added to your schema, and the strings "Custom Label in English" and "Libellé personnalisé en français" are the translations of that key in English and French, respectively.
Remember to add translations for all the keys you defined in your schema and for all the locales your site supports.
Source: Starlight Guide - Translate Starlight’s UI (https://starlight.astro.build/guides/i18n/#translate-starlights-ui)
Note: you can ask me a follow up question by @ mentioning me again :speech_balloon:
@glossy plover kapa.ai is still learning and improving, please let us know how it did by reacting below
@inner moat if I want to insert some words in different places, for example, made by xxx and сделал xxx то are different expressions in different language,
then how do I achieve this in adding translations for the keys ? Is it even possible to do so ?
Let me check the knowledge base for you. One moment! :books:
Yes, it is possible to handle such cases using placeholders in your translation strings. You can define your translation strings with placeholders and replace them with the actual values at runtime.
Here's an example of how you might define a translation string with a placeholder:
src/content/i18n/en.json
{
"made.by": "Made by {name}",
// Add more keys as needed
}
src/content/i18n/ru.json
{
"made.by": "Сделал {name}",
// Add more keys as needed
}
In these examples, {name} is a placeholder that you can replace with the actual value at runtime. The way to replace the placeholder with the actual value depends on how you implement your localization logic.
For example, if you're using a library like i18next (https://www.i18next.com/), you can use the t function to replace the placeholder:
i18next.t('made.by', { name: 'xxx' }); // Returns "Made by xxx" in English and "Сделал xxx" in Russian
Please note that this is a general approach to handling dynamic content in translation strings and not specific to Astro or Starlight. Always ensure that your code meets the requirements of your project and follows best practices for the libraries and frameworks you are using.
Source: Starlight Guide - Translate Starlight’s UI (https://starlight.astro.build/guides/i18n/#translate-starlights-ui)
Note: you can ask me a follow up question by @ mentioning me again :speech_balloon:
@glossy plover kapa.ai is still learning and improving, please let us know how it did by reacting below
@inner moat how do I use these translated phrases in my component?
Let me check the knowledge base for you. One moment! :books:
To use the translated phrases in your Astro components, you would typically use a helper function that retrieves the translation for a given key based on the current language. This function would read the translations from the JSON files in the src/content/i18n/ directory.
While the exact implementation of this function depends on your project setup and the libraries you are using, here's a general example of how you might use translated phrases in an Astro component:
---
// Import your i18n helper function
import { useTranslations } from '../i18n/utils';
// Get the current language from the URL
const lang = getLangFromUrl(Astro.url);
// Get the translation function for the current language
const t = useTranslations(lang);
---
<h1>{t('made.by', { name: 'xxx' })}</h1>
In this example, useTranslations is a hypothetical helper function that returns another function t. You can call t with a translation key and an object of placeholder values to get the translated string. The getLangFromUrl function is used to determine the current language based on the URL.
Please note that this is a general approach and not specific to Astro or Starlight. The actual implementation of the useTranslations and getLangFromUrl functions would depend on your project setup and the libraries you are using.
Source: Astro Guide - Translate UI strings (https://docs.astro.build/en/recipes/i18n/#translate-ui-strings)
Note: you can ask me a follow up question by @ mentioning me again :speech_balloon:
@glossy plover kapa.ai is still learning and improving, please let us know how it did by reacting below
@inner moat I've noticed that in some built-in components they use Astro.props.labels['lyricify.footer.madeBy'] to call the translatable texts.
So can I do so to call my customized texts?
Let me check the knowledge base for you. One moment! :books:
Yes, you can use Astro.props.labels['your.key'] to access your custom translations in your Astro components. The Astro.props.labels object contains the translations for the current language, and you can access each translation using its key.
Here's an example of how you might use a custom translation in an Astro component:
---
// Destructure the labels from Astro.props
const { labels } = Astro.props;
---
<h1>{labels['made.by']}</h1>
In this example, made.by is the key for your custom translation. Replace it with the actual key you used in your translation files.
Please note that this assumes that you have set up your project to pass the labels object as a prop to your Astro components. The exact way to do this depends on your project setup and the libraries you are using.
Source: Astro Guide - Translate UI strings (https://docs.astro.build/en/recipes/i18n/#translate-ui-strings)
Note: you can ask me a follow up question by @ mentioning me again :speech_balloon:
@glossy plover kapa.ai is still learning and improving, please let us know how it did by reacting below
@inner moat Cannot read properties of undefined (reading 'lyricify.madeBy')
Let me check the knowledge base for you. One moment! :books:
The error message "Cannot read properties of undefined (reading 'lyricify.madeBy')" suggests that the labels object in Astro.props is undefined when you're trying to access the lyricify.madeBy property.
This could happen for a few reasons:
-
The
labelsobject is not being passed as a prop to the component. Make sure that you're passinglabelsto your component in the parent component or page. -
The
lyricify.madeBykey does not exist in your translation files. Check your translation files in thesrc/content/i18n/directory and make sure that thelyricify.madeBykey is defined for all languages. -
The current language does not have a translation file or the translation file does not include the
lyricify.madeBykey. If the current language is determined dynamically (e.g., based on the URL or user settings), there might be a mismatch between the current language and the available translation files.
Here's an example of how you might use the labels prop in an Astro component:
---
// Destructure the labels from Astro.props
const { labels } = Astro.props;
---
<h1>{labels['lyricify.madeBy']}</h1>
In this example, make sure that labels is passed to your component and that lyricify.madeBy is defined in your translation files.
If you're still having trouble, you might find it helpful to add some debugging code to log the value of Astro.props and labels to the console. This can help you figure out what's going wrong.
Source: Astro Guide - Translate UI strings (https://docs.astro.build/en/recipes/i18n/#translate-ui-strings)
Note: you can ask me a follow up question by @ mentioning me again :speech_balloon:
@glossy plover kapa.ai is still learning and improving, please let us know how it did by reacting below
@inner moat no it doesn't work
Let me check the knowledge base for you. One moment! :books:
I'm sorry to hear that you're still having trouble. Without more specific information about your project setup and the exact code you're using, it's difficult to provide a more detailed solution.
However, here are a few general troubleshooting steps you can try:
-
Check your component props: Make sure that the
labelsobject is being passed as a prop to your component. You can logAstro.propsto the console to see what props are being passed. -
Check your translation keys: Make sure that the key you're trying to access (
lyricify.madeByin your example) is defined in your translation files. The keys in your translation files should match the ones you're using in your components. -
Check your language setting: If your site supports multiple languages, make sure that the current language is set correctly and that there is a corresponding translation file in the
src/content/i18n/directory. -
Check for typos or case mismatches: JavaScript object keys are case-sensitive, so make sure that the key you're using in your component matches the case of the key in your translation files.