czer
czer

Reputation: 471

How can I use adapter-static in SvelteKit to prerender my site without calling LayoutLoad in parallel?

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

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!

Upvotes: 1

Views: 1840

Answers (2)

czer
czer

Reputation: 471

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
        }
    }
};

Upvotes: 0

carlosV2
carlosV2

Reputation: 1419

I had the same problem but during DB initialisation instead.

The solution I applied was to filter the code with the building variable. For example:

import { building } from '$app/environment';

if (!building) {
  // Connect to the DB
}

In your case, you might want to wrap the loadTranslations to prevent it from running.

Upvotes: 0

Related Questions