i18n

Kitbook can automatically display variants in each of your languages. By default Kitbook only displays variants in your first language but the interface has controls to change the displayed language or show multiple languages at once.

To get started, add an array of languages to your config, and a function so Kitbook knows how to add the language to the URL. If you detect language based off query params, like lang=es you can use the following code:

vite.config.ts
ts
import { defineConfig } from 'kitbook/defineConfig'
export default defineConfig({
// other config...
languages: [
{ name: 'English', code: 'en', },
{ name: 'Spanish', code: 'es', },
],
addLanguageToUrl: ({ code, url }) => {
const [path, search] = url.split('?')
const params = new URLSearchParams(search)
params.set('lang', code)
return `${path}?${params.toString()}`
},
})

If you only use browser settings and cookie-stored locale values then you will need to alter your i18n code to also listen to a query param like lang=es to set the language.

If you use route params to define the language code (e.g. /[lang]/foo or /[locale=locale]/foo) then you need to set the kitbookRoute manually and use a addLanguageToUrl function similar to what's seen here:

vite.config.ts
ts
import { defineConfig } from 'kitbook/defineConfig'
export default defineConfig({
// other config...
languages: [
{ name: 'English', code: 'en', },
{ name: 'Spanish', code: 'es', },
],
kitbookRoute: '/[locale=locale]/kitbook',
addLanguageToUrl: ({ code, url }) => url.replace(/^.[^/]+/, `/${code}`),
})

The above method is used in the Poly-I18n Kitbook.

Using regex to change just the first path segment and not global replacement, like replaceAll('[locale=locale]', code), is required because of how Kitbook works:

  • You place Kitbook inside your language route as seen above, e.g. /[locale=locale]/kitbook
  • Kitbook initializes using your first language, e.g. /en/kitbook
  • Kitbook shows sandboxed components by using it's sandbox route, /en/kitbook/sandbox, plus the filepath of the component being shown, e.g. /routes/[locale=locale]/+page?variantName=something to give a final path of /en/kitbook/sandbox/routes/[locale=locale]/+page?variantName=something. It's that first path segment which your i18n setup is listening to. Only that first [locale=locale] should be set by the addLanguageToUrl function. Since you have no component in your repo under /routes/en/+page, simple string replacement won't work as it would also replace the second occurrence of your locale matching param name but we want to preserve that so Kitbook knows what file to look for.

Visual Regression Testing

If you use [Visual Regression Testing], screenshots will be automatically be created using all of your languages.

If you have a lot of languages you may benefit from sharding your tests across multiple machines. If you don't know how to get started with sharding, you may need to settle for adjusting the workflow timeout length in the meantime.

Also consider turning off i18n where it's not needed as described next.

Fine-grained language control

Don't forget that all variants have [Fine-grained control] so you can override project language defaults on a variant file basis or for an individual variant. For example, in a project with English, Spanish, and French, we could do the following to restrict down to just two or even one language:

Foo.variants.ts
ts
import type { Variant, Viewport } from 'kitbook'
import type Component from './Foo.svelte'
export const shared_meta: VariantMeta = {
languages: [
{ code: 'en', name: 'English' },
{ code: 'es', name: 'Spanish' },
],
}
export const English_and_Spanish: Variant<Component> = {}
export const Just_Spanish: Variant<Component> = {
_meta: {
languages: [{ code: 'es', name: 'Spanish' }],
}
}

Some components may not have any translated strings and so it doesn't make sense to iterate across languages. In that case you can just set the shared_meta.languages property to an empty array to show only the first active language:

Foo.variants.ts
ts
import type { Variant, Viewport } from 'kitbook'
import type Component from './Foo.svelte'
export const shared_meta: VariantMeta = {
languages: [],
}

You can also set an individual variant's languages array to an empty array for the same effect on just that specific variant.

Languages can also be set for Compositions:

Foo.composition
svelte
<script lang="ts" context="module">
import { defineComposition } from 'kitbook'
export const config = defineComposition({
languages: [
{ code: 'en', name: 'English' },
{ code: 'fr', name: 'French' },
],
})
</script>

That will result in your Composition being displayed in both languages like so:

en
fr

Once again, an empty array is a quick way to just show the first active language.


You've now learned the basic features of Kitbook as far as they have been documented. As you document and prototype your components for each situation you need, you may run into questions as to how to accomplish something. Feel free to browse the Kitbook related files in any of the provided [repo examples] where Kitbook in is use. You may find your answer there. If not, please create an issue, and let's discuss how you could add a needed feature.

Edit page in GitHub