Qwik is unique in that it has fine-grained lazy loading of code. The classical way to do translation is at runtime by looking up the translation strings in the translation map. This is not conducive with lazy loading because it requires that the translations be eagerly loaded, defeating the fine-grained lazy loading of Qwik.
There are two ways to do translation:
We think that the best approach is to use a hybrid approach.
$localize
(by Angular)The translation system is based on the $localize
system from Angular. The translations can be extracted in xmb
, xlf
, xlif
, xliff
, xlf2
, xlif2
, xliff2
, and json
formats.
NOTE: The
$localize
system is a compile-time translation system and is completely removed from the final output.$localize
is a sub-project of Angular, and including its usage does not mean that Angular is used for rendering of applications.
Any string can be marked for translation by using the $localize
template function like so:
export default component$((props: { name: string }) => {
return <span>{$localize`Hello ${props.name}!`}</span>;
});
The first step in translation is to build the application. Once the artifacts are build the strings can be extracted for translation.
npm run build.client
npm run i18n-extract
The result of the commands is src/locale/message.en.json
.
Take the resulting string and send them for translation. Produce a file for each language. For example:
src/locale/message.en.json # Original strings
src/locale/message.fr.json
src/locale/message.sp.json
The strings need to be inlined into the application. This is done automatically as part of the build.client process.
npm run build.client
The result of this command is that the browser chunks are generated once for each locale. For example:
dist/build/q-*.js # Original chunks
dist/build/en/q-*.js
dist/build/fr/q-*.js
dist/build/sp/q-*.js
npm run dev
Navigate to http://localhost:5173
. The resulting language should match your browser language. It will pick sk
if it can't detect a language, this can happen when you run under StackBlitz for example. You can also override the language by adding ?locale=fr
to the URL.
Here are the steps to build the application for production.
npm run build.client && npm run build.server && npm run i18n-translate && npm run serve
Inside of you project, you'll see the following directories and files:
├── public/
│ └── ...
└── src/
├── components/
│ └── ...
└── routes/
└── ...
src/routes
: Provides the directory based routing, which can include a hierarchy of layout.tsx
layout files, and index.tsx
files as the page. Additionally, index.ts
files are endpoints. Please see the routing docs for more info.
src/components
: Recommended directory for components.
public
: Any static assets, like images, can be placed in the public directory. Please see the Vite public directory for more info.
Use the npm run qwik add
command to add other integrations. Some examples of integrations include as a Cloudflare, Netlify or Vercel server, and the Static Site Generator (SSG).
npm run qwik add
Development mode uses Vite's development server. For Qwik during development, the dev
command will also server-side render (SSR) the output. The client-side development modules loaded by the browser.
npm run dev
Note: during dev mode, Vite will request many JS files, which does not represent a Qwik production build.
The preview command will create a production build of the client modules, production build of src/entry.preview.tsx
, and create a local server. The preview server is only for convenience to locally preview a production build, but it should not be used as a production server.
npm run preview
The production build should generate the client and server modules by running both client and server build commands. Additionally, the build command will use Typescript run a type check on the source.
npm run build
This app has a minimal Express server implementation. After running a full build, you can preview the build using the command:
npm run serve
Then visit http://localhost:8080/