Tutorial: localized routing with the language
Step by step, let's build a sample app with Qwik Speak and a localized router using Qwik City features
Setup
See Quick Start
Routing
Let's assume that we want to create a navigation of this type:
default language (en-US): routes not localized
http://127.0.0.1:4173/other languages (it-IT): localized routes
http://127.0.0.1:4173/it-IT/
In routes root level add [...lang] directory to catch all routes:
src/routes/
│
└───[...lang]/
index.tsx
layout.tsxNow let's handle it. Update plugin.ts in the root of the src/routes directory:
src/routes/plugin.ts
import type { RequestHandler } from '@builder.io/qwik-city';
import { setSpeakContext, validateLocale } from 'qwik-speak';
import { config } from '../speak-config';
/**
* This middleware function must only contain the logic to set the locale,
* because it is invoked on every request to the server.
* Avoid redirecting or throwing errors here, and prefer layouts or pages
*/
export const onRequest: RequestHandler = ({ params, locale }) => {
let lang: string | undefined = undefined;
if (params.lang && validateLocale(params.lang)) {
// Check supported locales
lang = config.supportedLocales.find(value => value.lang === params.lang)?.lang;
} else {
lang = config.defaultLocale.lang;
}
// Set Speak context (optional: set the configuration on the server)
setSpeakContext(config);
// Set Qwik locale
locale(lang);
};If you want to handle errors or redirects due to the locale, use layouts or pages. For example you could add in src/routes/layout.tsx:
Usage
Add index.tsx with some translation, providing optional default values for each translation: key@@[default value]:
src/routes/[...lang]/index.tsx
Add a page/index.tsx to try the router:
src/routes/[...lang]/page/index.tsx
Note that it is not necessary to provide the default value in the key once again: it is sufficient and not mandatory to provide it once in the app
Note the use of a dynamic key (which will therefore only be available at runtime), which we assign to the
runtimescope
Change locale
Now we want to change locale. Let's create a ChangeLocale component:
src/components/change-locale/change-locale.tsx
We use the
<a>tag tag because it is mandatory to reload the page when changing the language
Add the ChangeLocale component in header.tsx along with localized navigation links:
Extraction
We can now extract the translations and generate the assets as json. In package.json add the following command to the scripts:
The following files are generated:
app asset for each language, initialized with the default values we provided.
translations skipped due to dynamic keys is runtime.${key}. During configuration, we provided in runtimeAssets a runtime file, which we can now create and populate with dynamic keys:
i18n/[lang]/runtime.json
See Qwik Speak Extract for more details.
Development
We can translate the it-IT files and start the app:
Production
Build the production app in preview mode:
and inspect the qwik-speak-inline.log file in root folder to see warnings for missing values or dynamic keys.
Domain-based routing
Prefix always
If you want to use different domains in production, update speak-config.ts with the domains supported by each locale, and set the prefix usage strategy:
While in dev mode the navigation will only use the prefix, in production it will use the domain and the prefix:
In SSG mode, you can only use
alwaysas prefix strategy
Prefix as needed
If in production you don't want the prefix for the default domains, change the prefix strategy to as-needed:
It will result in:
Since the de language does not have a default domain, but we have associated another domain, it will automatically keep the prefix.
Usage
Update plugin.ts to get the language from the domain:
and in ChangeLocale component pass the URL instead of the pathname to getPath:
Last updated