Reputation: 412
I'm trying to implement localization in Qwik
framework with Qwik Speak
but i'm getting the following error when trying to resolve locale:
Internal server error: locale is not a function
I'm following the instructions in the Qwik Speak docs.
src/speak-config.ts
fileQwikSpeakProvider
to the src/root.tsx
onRequest
function to the src/routes/layout.tsx
public/i18n/en-US/app.json
and public/i18n/it-IT/app.json
But still getting the error on the locale(lang || config.defaultLocale.lang);
call in the src/routes/layout.tsx
.
My src/speak-config.ts
:
export const config: SpeakConfig = {
defaultLocale: { lang: 'en-US', currency: 'USD', timeZone: 'America/Los_Angeles' },
supportedLocales: [
{ lang: 'it-IT', currency: 'EUR', timeZone: 'Europe/Rome' },
{ lang: 'en-US', currency: 'USD', timeZone: 'America/Los_Angeles' }
],
assets: [
'app' // Translations shared by the pages
]
};
export const loadTranslation$: LoadTranslationFn = $(async (lang: string, asset: string, origin?: string) => {
let url = '';
// Absolute urls on server
if (isServer && origin) {
url = origin;
}
url += `/i18n/${lang}/${asset}.json`;
const response = await fetch(url);
if (response.ok) {
return response.json();
}
else if (response.status === 404) {
console.warn(`loadTranslation$: ${url} not found`);
}
});
export const translationFn: TranslationFn = {
loadTranslation$: loadTranslation$
};
My src/root.tsx
:
export default component$(() => {
useStyles$(globalStyles);
return (
<QwikSpeakProvider config={config} translationFn={translationFn}>
<QwikCityProvider>
<head>
<meta charSet="utf-8" />
<link rel="manifest" href="/manifest.json" />
<QwikPartytown forward={["dataLayer.push"]} />
<RouterHead />
</head>
<body lang="en">
<RouterOutlet />
<ServiceWorkerRegister />
</body>
</QwikCityProvider>
</QwikSpeakProvider>
);
});
My src/routes/layout.tsx
:
export default component$(() => {
return (
<>
<Header />
<main>
<section>
<Slot />
</section>
</main>
<Footer />
</>
);
});
export const onRequest: RequestHandler = ({ request, locale }) => {
const cookie = request.headers?.get("cookie");
const acceptLanguage = request.headers?.get("accept-language");
let lang: string | null = null;
// Try whether the language is stored in a cookie
if (cookie) {
const result = new RegExp(
"(?:^|; )" + encodeURIComponent("locale") + "=([^;]*)"
).exec(cookie);
if (result) {
lang = JSON.parse(result[1])["lang"];
}
}
// Try to use user language
if (!lang) {
if (acceptLanguage) {
lang = acceptLanguage.split(";")[0]?.split(",")[0];
}
}
// Set Qwik locale
locale(lang || config.defaultLocale.lang);
};
Upvotes: 3
Views: 651
Reputation: 517
From what I read it seems you are missing the step to create the function.
/**
* Translation files are lazy-loaded via dynamic import and will be split into separate chunks during build.
* Keys must be valid variable names
*/
const translationData = import.meta.glob<Translation>('/i18n/**/*.json');
/**
* Using server$, translation data is always accessed on the server
*/
const loadTranslation$: LoadTranslationFn = server$(async (lang: string, asset: string) =>
await translationData[`/i18n/${lang}/${asset}.json`]?.()
);
export const translationFn: TranslationFn = {
loadTranslation$: loadTranslation$
};
You can follow the step by step guide here: https://github.com/robisim74/qwik-speak/blob/main/docs/tutorial-routing.md
Upvotes: 0
Reputation: 1
Move this piece of code to a new file src/routes/plugin.ts
export const onRequest: RequestHandler = ({ request, locale }) => {
const cookie = request.headers?.get("cookie");
const acceptLanguage = request.headers?.get("accept-language");
let lang: string | null = null;
// Try whether the language is stored in a cookie
if (cookie) {
const result = new RegExp(
"(?:^|; )" + encodeURIComponent("locale") + "=([^;]*)"
).exec(cookie);
if (result) {
lang = JSON.parse(result[1])["lang"];
}
}
// Try to use user language
if (!lang) {
if (acceptLanguage) {
lang = acceptLanguage.split(";")[0]?.split(",")[0];
}
}
// Set Qwik locale
locale(lang || config.defaultLocale.lang);
};
Upvotes: 0