I have a SvelteKit site that uses adapter-static
to prerender pages.
It's a multilingual site, so I pass the paths /
, /de
, /es
, pt
in svelte.config.js
. For translation I use sveltekit-i18n
.
I have
routes/+page.svelte
,routes/de/+page.svelte
,routes/es/+page.svelte
routes/pt/+page.svelte
The problem is sveltekit-i18n
and most i18n libraries use a reactive variable $t
and when the pages are built, it runs the LayoutLoad functions in parallel for these sites.
In my LayoutLoad (routes/layout.ts) and LayoutServerLoad (routes/+layout.server.ts)` I have something like this:
/** @type {import('./$types').LayoutServerLoad} */
export async function load(attrs: any) {
const startsWith = ['pt', 'es', 'de'].find((e) => attrs?.url?.pathname.startsWith(`/${e}`));
const locale = startsWith ?? defaultLocale;
await loadTranslations(initLocale, attrs?.url?.pathname);
return { locale };
}
and this
/** @type {import('./$types').LayoutLoad} */
export async function load({ data, url, parent }: any) {
await loadTranslations(data.locale, url?.pathname);
return { locale: data.locale };
}
now when I build my site with SvelteKit via vite build
then I find out that the load functions are loaded like this by using console.log
layout.server.ts es /es
layout.server.ts pt /pt
layout.server.ts de /de
layout.ts es /es
layout.ts pt /pt
layout.svelte es /es
page.svelte pt /es
layout.ts de /de
layout.svelte de /de
page.svelte de /de
layout.svelte pt /pt
page.svelte de /pt
layout.server.ts en /
layout.ts en /
layout.svelte en /
page.svelte en /
as you can see the page /es/+page.svelte
has suddenly the language pt
and not es
.
The same applies to the page /pt/+page.svelte
it suddenly has the language German de
.
I believe this is due to the reactivity of the $t
variable in i18n libraries like sveltekit-i18n, but I also don't know how to fix it, as load functions seem to be loaded in parallel and not right before the +page.svelte
is being built.
So what happens I have in my prerendered output html files the wrong language, for example in meta description tags etc.
I appreciate your help very much!
When I replicated the issue using a skeleton SvelteKit project, I noticed that I had set the concurrency level to 3 in prerender options in svelte.config.js
. This causes the mixed order of load runs above, setting it to 1 solved the problem.
/** @type {import('@sveltejs/kit').Config} */
const config = {
preprocess: preprocess({
sass: true,
postcss: true
}),
kit: {
adapter: adapter(),
prerender: {
concurrency: 1, // had to be set to 1 instead of 3
crawl: true,
entries: pages
}
}
};