diff options
Diffstat (limited to 'apps/kit/src')
| -rw-r--r-- | apps/kit/src/global.d.ts | 13 | ||||
| -rw-r--r-- | apps/kit/src/hooks.server.ts (renamed from apps/kit/src/hooks/index.server.ts) | 37 | ||||
| -rw-r--r-- | apps/kit/src/lib/components/locale-switcher.svelte | 15 | ||||
| -rw-r--r-- | apps/kit/src/routes/(main)/+layout.server.ts | 15 | ||||
| -rw-r--r-- | apps/kit/src/routes/(main)/+layout.svelte | 23 | ||||
| -rw-r--r-- | apps/kit/src/routes/(main)/+layout.ts | 22 |
6 files changed, 74 insertions, 51 deletions
diff --git a/apps/kit/src/global.d.ts b/apps/kit/src/global.d.ts new file mode 100644 index 0000000..e49922a --- /dev/null +++ b/apps/kit/src/global.d.ts @@ -0,0 +1,13 @@ +/// <reference types="@sveltejs/kit" /> + +type Locales = import('$i18n/i18n-types').Locales +type TranslationFunctions = import('$i18n/i18n-types').TranslationFunctions + +declare namespace App { + interface Locals { + locale: Locales + LL: TranslationFunctions + } + + // interface Platform { } +}
\ No newline at end of file diff --git a/apps/kit/src/hooks/index.server.ts b/apps/kit/src/hooks.server.ts index 414318d..0f6e0c0 100644 --- a/apps/kit/src/hooks/index.server.ts +++ b/apps/kit/src/hooks.server.ts @@ -1,25 +1,29 @@ import { CookieNames } from "$lib/configuration"; -import { detectLocale, locales } from '$lib/i18n/i18n-util' +import { detectLocale, i18n, isLocale, locales } from '$lib/i18n/i18n-util' import type { Handle, RequestEvent } from '@sveltejs/kit' -import { sequence } from "@sveltejs/kit/hooks"; import { initAcceptLanguageHeaderDetector } from 'typesafe-i18n/detectors' import { parse, serialize } from "cookie"; -import { logDebug } from "$lib/logger"; +import type { Locales } from "$lib/i18n/i18n-types"; +import { loadAllLocales } from "$lib/i18n/i18n-util.sync"; -const handleLocale: Handle = async ({ event, resolve }) => { + +loadAllLocales() +const L = i18n() + +export const handle: Handle = async ({ event, resolve }) => { const cookies = parse(event.request.headers.get("Cookie") ?? ''); const localeCookie = cookies[CookieNames.locale]; const preferredLocale = getPreferredLocale(event); let finalLocale = localeCookie ?? preferredLocale; - logDebug("Handling locale", { + console.log("Handling locale", { locales, localeCookie, preferredLocale, finalLocale }); - if (locales.findIndex((locale) => locale === finalLocale) === -1) finalLocale = "en"; + if (!isLocale(finalLocale)) finalLocale = "en"; if (!localeCookie) { // Set a locale cookie event.setHeaders({ @@ -30,23 +34,14 @@ const handleLocale: Handle = async ({ event, resolve }) => { }) }); } - // replace html lang attribute with correct language - return resolve(event, { transformPageChunk: ({ html }) => html.replace('%lang%', finalLocale) }); -} -function getPreferredLocale(event: RequestEvent) { - // detect the preferred language the user has configured in it's browser - // https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Accept-Language - const headers = transformHeaders(event) - const acceptLanguageDetector = initAcceptLanguageHeaderDetector({ headers }) + event.locals.locale = finalLocale as Locales; + event.locals.LL = L[finalLocale as Locales]; - return detectLocale(acceptLanguageDetector) + return resolve(event, { transformPageChunk: ({ html }) => html.replace('%lang%', finalLocale) }); } -function transformHeaders({ request }: RequestEvent) { - const headers: Record<string, string> = {} - request.headers.forEach((value, key) => (headers[key] = value)) - return headers +function getPreferredLocale(event: RequestEvent) { + const acceptLanguageDetector = initAcceptLanguageHeaderDetector(event.request); + return detectLocale(acceptLanguageDetector); } - -export const handle = sequence(handleLocale); diff --git a/apps/kit/src/lib/components/locale-switcher.svelte b/apps/kit/src/lib/components/locale-switcher.svelte index 1f9eb37..477e2d7 100644 --- a/apps/kit/src/lib/components/locale-switcher.svelte +++ b/apps/kit/src/lib/components/locale-switcher.svelte @@ -1,16 +1,25 @@ <script lang="ts"> import { browser } from "$app/environment"; import { page } from "$app/stores"; + import { CookieNames } from "$lib/configuration"; + import { set_cookie } from "$lib/helpers"; import { setLocale, locale } from "$lib/i18n/i18n-svelte"; import type { Locales } from "$lib/i18n/i18n-types"; import { locales } from "$lib/i18n/i18n-util"; import { loadLocaleAsync } from "$lib/i18n/i18n-util.async"; + import Cookies from "js-cookie"; const switchLocale = async (newLocale: Locales) => { if (!newLocale || $locale === newLocale) return; await loadLocaleAsync(newLocale); setLocale(newLocale); document.querySelector("html")?.setAttribute("lang", newLocale); + set_cookie(CookieNames.locale, newLocale); + Cookies.set(CookieNames.locale, newLocale, { + sameSite: "strict", + domain: location.hostname, + }); + console.log("Switched to: " + newLocale); }; $: if (browser) { @@ -21,11 +30,7 @@ <ul> {#each locales as aLocale} <li> - <button - type="button" - class:active={aLocale === $locale} - on:click={() => switchLocale(aLocale)} - > + <button type="button" class:active={aLocale === $locale} on:click={() => switchLocale(aLocale)}> {aLocale} </button> </li> diff --git a/apps/kit/src/routes/(main)/+layout.server.ts b/apps/kit/src/routes/(main)/+layout.server.ts index 6bc7071..d2eb2eb 100644 --- a/apps/kit/src/routes/(main)/+layout.server.ts +++ b/apps/kit/src/routes/(main)/+layout.server.ts @@ -3,8 +3,9 @@ import { logError } from "$lib/logger"; import { error, redirect } from "@sveltejs/kit"; import type { LayoutServerLoad } from "./$types"; -export const load: LayoutServerLoad = async ({ routeId, cookies }) => { - const isPublicRoute = routeId?.startsWith("(main)/(public)") ?? true; +export const load: LayoutServerLoad = async ({ routeId, cookies, locals }) => { + const isPublicRoute = (routeId?.startsWith("(main)/(public)") || routeId === "(main)") ?? true; + let sessionIsValid = (await fetch(api_base("_/valid-session"), { headers: { Cookie: CookieNames.session + "=" + cookies.get(CookieNames.session) @@ -15,9 +16,19 @@ export const load: LayoutServerLoad = async ({ routeId, cookies }) => { message: "We are experiencing a service distruption! Have patience while we resolve the issue." }) })).ok; + + console.log("Base Layout loaded", { + sessionIsValid, + isPublicRoute, + routeId + }); + if (sessionIsValid && isPublicRoute) { throw redirect(302, "/home"); } else if (!sessionIsValid && !isPublicRoute) { throw redirect(302, "/sign-in"); } + return { + locale: locals.locale + } };
\ No newline at end of file diff --git a/apps/kit/src/routes/(main)/+layout.svelte b/apps/kit/src/routes/(main)/+layout.svelte index 5354f02..236cd75 100644 --- a/apps/kit/src/routes/(main)/+layout.svelte +++ b/apps/kit/src/routes/(main)/+layout.svelte @@ -1,32 +1,23 @@ <script lang="ts"> import "../../app.pcss"; import { setLocale } from "$lib/i18n/i18n-svelte"; + import LocaleSwitcher from "$lib/components/locale-switcher.svelte"; + import { ExclamationTriangleIcon } from "$lib/components/icons"; import type { LayoutData } from "./$types"; let online = true; export let data: LayoutData; - + // at the very top, set the locale before you access the store and before the actual rendering takes place setLocale(data.locale); </script> <svelte:window bind:online /> + {#if !online} - <div class="bg-yellow-50 relative z-50 border-yellow-400 p-4"> + <div class="bg-yellow-50 relative z-50 p-4"> <div class="flex"> <div class="flex-shrink-0"> - <svg - class="h-5 w-5 text-yellow-400" - xmlns="http://www.w3.org/2000/svg" - viewBox="0 0 20 20" - fill="currentColor" - aria-hidden="true" - > - <path - fill-rule="evenodd" - d="M8.257 3.099c.765-1.36 2.722-1.36 3.486 0l5.58 9.92c.75 1.334-.213 2.98-1.742 2.98H4.42c-1.53 0-2.493-1.646-1.743-2.98l5.58-9.92zM11 13a1 1 0 11-2 0 1 1 0 012 0zm-1-8a1 1 0 00-1 1v3a1 1 0 002 0V6a1 1 0 00-1-1z" - clip-rule="evenodd" - /> - </svg> + <ExclamationTriangleIcon class="bg-yellow-400" /> </div> <div class="ml-3"> <p class="text-sm text-yellow-700">You seem to be offline, please check your internet connection.</p> @@ -34,4 +25,6 @@ </div> </div> {/if} + +<LocaleSwitcher /> <slot /> diff --git a/apps/kit/src/routes/(main)/+layout.ts b/apps/kit/src/routes/(main)/+layout.ts index 13837be..5d0e005 100644 --- a/apps/kit/src/routes/(main)/+layout.ts +++ b/apps/kit/src/routes/(main)/+layout.ts @@ -1,9 +1,15 @@ -import type { Locales } from "$lib/i18n/i18n-types"; -import { loadLocaleAsync } from "$lib/i18n/i18n-util.async"; -import type { LayoutLoad } from "./$types"; +import type { LayoutLoad } from './$types' +import type { Locales } from '$lib/i18n/i18n-types' +import { loadLocaleAsync } from '$lib/i18n/i18n-util.async' +import { setLocale } from '$lib/i18n/i18n-svelte' -export const load: LayoutLoad<{ locale: Locales }> = async ({ url, params }) => { - let lang = "en" as Locales; - await loadLocaleAsync(lang); - return { locale: lang }; -}; +export const load: LayoutLoad<{ locale: Locales }> = async ({ data: { locale } }) => { + // load dictionary into memory + await loadLocaleAsync(locale) + + // if you need to output a localized string in a `load` function, + // you always need to call `setLocale` right before you access the `LL` store + setLocale(locale) + // pass locale to the "rendering context" + return { locale } +}
\ No newline at end of file |
