Language handling / redirection for sveltekit : Example implementations #1807
-
This is my code (sveltekit) : import type { Handle } from '@sveltejs/kit'
import type { AvailableLanguageTag } from '$paraglide/runtime'
export const handleLang: Handle = async ({ event, resolve }) => {
const userLanguage: AvailableLanguageTag | null =
// 1. If the user has set the lang in URL (eg captured by a path matcher), use that
getParamLang(event) ??
// 2. Else, check if the user has a preferred language in a cookie
getCookieLang(event)[0] ??
// 3. Missing or invalid cookie, detect language from the Accept-Language header
getHeaderLang(event) ??
// 4. No matching language, use default language
sourceLanguageTag
return await resolve(event, {
transformPageChunk({ done, html }) {
if (done) {
return html.replace('%lang%', userLanguage as AvailableLanguageTag)
}
},
})
} Provided the functions work, is this a good way to handle language for my users ? I plan to set the cookie from thie own actions like settings |
Beta Was this translation helpful? Give feedback.
Replies: 4 comments 6 replies
-
@MarArMar I believe this is the good way to implement i18n that good for SEO as well. |
Beta Was this translation helpful? Give feedback.
-
Yes! This is a very good way to implement language redirection! To do this, set // src/routes/[[lang]]/+layout.js
export function load({ locals }) {
return { lang: locals.lang}
} And then in your layout: <script>
import { setLanguageTag } from "../paraglide/runtime.js"
export let data;
$: setLanguageTag(data.lang)
</script>
{#key data.lang}
<slot />
{/key} Doing it this way ensures that there is never a disconnect between the server & client. |
Beta Was this translation helpful? Give feedback.
-
this is my script in hooks.server.js file to FORCE a language tag in the url(otherwise he will not be able to choose the language and have the url change as well. e.g. you are in the root path change the language and reload) and redirect the user based on the browser preference. Make sure prefixDefaultLanguage: 'always' is set in the i18n config. export const i18n = createI18n(runtime,{prefixDefaultLanguage: 'always'}); // Try to get locale from `pathname`.
let pathLang = pathname.match(/[^/]+?(?=\/|$)/);
if(pathLang!=null) pathLang = pathLang.toString().toLowerCase();
let lang = availableLanguageTags.find((l) => `${l}`.toLowerCase() === pathLang);
// If no language is specified in the url
if (!lang) {
lang = sourceLanguageTag; //default
let possibleSupportedLocale=getHeaderLang(event) //get user preference from request header
// take the first from the user preferences and if not continue using the default
if (possibleSupportedLocale) lang = possibleSupportedLocale;
let pathnameWithoutLang;
if(!pathLang) // Case A: Rooth url -> /
pathnameWithoutLang = "/";
else if(pathLang?.length==2) // Case B: An unsupported Language is specified in the url-> /fr/catalog
pathnameWithoutLang = pathname.replace(`${pathLang}`,"").replace("//","/");
else // Case C: Subpath is specified in the url -> /catalog
pathnameWithoutLang = "/" + pathLang;
return new Response(undefined, { headers: {'location': `/${lang}${pathnameWithoutLang}${search}` }, status: 301 });
} Update 2024: this works now with latest "@inlang/paraglide-js-adapter-sveltekit": "0.3.7", |
Beta Was this translation helpful? Give feedback.
-
Sorry I misread the question |
Beta Was this translation helpful? Give feedback.
Yes! This is a very good way to implement language redirection!
What you could do is to pass the language that you detect here into your layout. That way there isn't the risk that the client & server get out of sync.
To do this, set
event.locals.lang
to theuserLanguage
you detect here, and in your root+layout.js
file pass it to the frontend:And then in your layout:
Doing it this way ensures that there is neve…