aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/app.html3
-rw-r--r--src/components/contact.svelte79
-rw-r--r--src/components/header.svelte12
-rw-r--r--src/components/locale-switcher.svelte46
-rw-r--r--src/global.d.ts13
-rw-r--r--src/hooks.server.ts43
-rw-r--r--src/i18n/en/index.ts13
-rw-r--r--src/i18n/formatters.ts11
-rw-r--r--src/i18n/i18n-svelte.ts12
-rw-r--r--src/i18n/i18n-types.ts66
-rw-r--r--src/i18n/i18n-util.async.ts27
-rw-r--r--src/i18n/i18n-util.sync.ts26
-rw-r--r--src/i18n/i18n-util.ts38
-rw-r--r--src/i18n/nb/index.ts13
-rw-r--r--src/lib/sanity-client.ts9
-rw-r--r--src/lib/utils.ts27
-rw-r--r--src/params/lang.ts7
-rw-r--r--src/routes/+layout.server.ts6
-rw-r--r--src/routes/+layout.svelte15
-rw-r--r--src/routes/+layout.ts14
-rw-r--r--src/routes/+page.svelte0
-rw-r--r--src/routes/[lang=lang]/+page.server.ts19
-rw-r--r--src/routes/[lang=lang]/+page.svelte17
-rw-r--r--src/routes/[lang=lang]/+page.ts18
24 files changed, 501 insertions, 33 deletions
diff --git a/src/app.html b/src/app.html
index c9bd64d..ef0bfa1 100644
--- a/src/app.html
+++ b/src/app.html
@@ -1,6 +1,5 @@
<!DOCTYPE html>
-<html lang="en">
-
+<html lang="%lang%">
<head>
<meta charset="utf-8" />
<link rel="icon" href="%sveltekit.assets%/favicon.png" />
diff --git a/src/components/contact.svelte b/src/components/contact.svelte
index c7b0be3..9f5bb98 100644
--- a/src/components/contact.svelte
+++ b/src/components/contact.svelte
@@ -1,45 +1,66 @@
+<script context="module" lang="ts">
+ export type ContactModel = {
+ addressLines: Array<string>;
+ email?: string;
+ phone?: string;
+ phoneHours?: string;
+ };
+</script>
+
<script lang="ts">
- export let address1: string;
- export let address2: string;
- export let address3: string;
- export let email: string;
- export let phone: string;
- export let phoneHours: string;
+ import LL from "$i18n/i18n-svelte";
+
+ export let model: ContactModel;
+
+ let visible = true;
+
+ $: if (!model.addressLines) {
+ visible = false;
+ } else {
+ visible = true;
+ }
</script>
<section class="contact relative z-1">
<div class="w-[calc(100%_-_2.5rem)] lg:w-[calc(100%_-_4rem)] mx-auto max-w-7xl">
<div class="mb-8 lg:mb-12">
- <h1 class="text-center">Contact Us</h1>
+ <h1 class="text-center">{$LL.contact.title()}</h1>
</div>
<div class="grid grid-cols-12 gap-8 lg:gap-12">
<div class="col-span-12 lg:col-span-6">
<dl class="details-list details-list--rows">
- <div class="details-list__item py-5 lg:py-8 lg:flex lg:justify-between">
- <dt class="font-bold mb-1.5 lg:mb-2 lg:mb-0">Address</dt>
- <dd class="leading-snug lg:text-right">
- {address1}<br />{address2}<br />{address3}
- </dd>
- </div>
-
- <div class="details-list__item py-5 lg:py-8 lg:flex lg:justify-between">
- <dt class="font-bold mb-1.5 lg:mb-2 lg:mb-0">Email</dt>
- <dd>
- <a href="mailto:webmaster@example.com">{email}</a>
- </dd>
- </div>
-
- <div class="details-list__item py-5 lg:py-8 lg:flex lg:justify-between">
- <dt class="font-bold mb-1.5 lg:mb-2 lg:mb-0">Phone</dt>
- <dd class="leading-snug lg:text-right">
- <p><a href="tel:+44 7656 6455">{phone}</a></p>
- <p class="text-contrast-medium">{phoneHours}</p>
- </dd>
- </div>
+ {#if (model.addressLines?.length ?? 0) > 0}
+ <div class="details-list__item py-5 lg:py-8 lg:flex lg:justify-between">
+ <dt class="font-bold mb-1.5 lg:mb-2 lg:mb-0">{$LL.contact.addressTitle()}</dt>
+ <dd class="leading-snug lg:text-right">
+ {#each model.addressLines as line}
+ {line}<br />
+ {/each}
+ </dd>
+ </div>
+ {/if}
+ {#if model.email}
+ <div class="details-list__item py-5 lg:py-8 lg:flex lg:justify-between">
+ <dt class="font-bold mb-1.5 lg:mb-2 lg:mb-0">{$LL.contact.emailTitle()}</dt>
+ <dd>
+ <a href="mailto:webmaster@example.com">{model.email}</a>
+ </dd>
+ </div>
+ {/if}
+ {#if model.phone}
+ <div class="details-list__item py-5 lg:py-8 lg:flex lg:justify-between">
+ <dt class="font-bold mb-1.5 lg:mb-2 lg:mb-0">{$LL.contact.phoneTitle()}</dt>
+ <dd class="leading-snug lg:text-right">
+ <p><a href="tel:+44 7656 6455">{model.phone}</a></p>
+ {#if model.phoneHours}
+ <p class="text-contrast-medium">{model.phoneHours}</p>
+ {/if}
+ </dd>
+ </div>
+ {/if}
</dl>
</div>
-
<div class="rounded col-span-12 lg:col-span-6 lg:h-auto lg:pb-0" />
</div>
</div>
diff --git a/src/components/header.svelte b/src/components/header.svelte
new file mode 100644
index 0000000..5789196
--- /dev/null
+++ b/src/components/header.svelte
@@ -0,0 +1,12 @@
+<script lang="ts">
+ import { locale } from "$i18n/i18n-svelte";
+ import LocaleSwitcher from "./locale-switcher.svelte";
+</script>
+
+<header>
+ <a href="/{$locale}">
+ <h1>Auroraklinikken</h1>
+ </a>
+
+ <LocaleSwitcher />
+</header>
diff --git a/src/components/locale-switcher.svelte b/src/components/locale-switcher.svelte
new file mode 100644
index 0000000..938d18a
--- /dev/null
+++ b/src/components/locale-switcher.svelte
@@ -0,0 +1,46 @@
+<script lang="ts">
+ import { browser } from "$app/environment";
+ import { invalidateAll } from "$app/navigation";
+ import { page } from "$app/stores";
+ import { setLocale, locale } from "$i18n/i18n-svelte";
+ import type { Locales } from "$i18n/i18n-types";
+ import { locales } from "$i18n/i18n-util";
+ import { loadLocaleAsync } from "$i18n/i18n-util.async";
+ import { replaceLocaleInUrl } from "$lib/utils";
+
+ const switchLocale = async (newLocale: Locales, updateHistoryState = true) => {
+ if (!newLocale || $locale === newLocale) return;
+ // load new dictionary from server
+ await loadLocaleAsync(newLocale);
+ // select locale
+ setLocale(newLocale);
+ // update `lang` attribute
+ document.querySelector("html")?.setAttribute("lang", newLocale);
+ if (updateHistoryState) {
+ // update url to reflect locale changes
+ history.pushState({ locale: newLocale }, "", replaceLocaleInUrl($page.url, newLocale));
+ }
+ // run the `load` function again
+ invalidateAll();
+ };
+ // update locale when navigating via browser back/forward buttons
+ const handlePopStateEvent = async ({ state }: PopStateEvent) => switchLocale(state.locale, false);
+ // update locale when page store changes
+ $: if (browser) {
+ const lang = $page.params.lang as Locales;
+ switchLocale(lang, false);
+ history.replaceState({ ...history.state, locale: lang }, "", replaceLocaleInUrl($page.url, lang));
+ }
+</script>
+
+<svelte:window on:popstate={handlePopStateEvent} />
+
+<ul>
+ {#each locales as l}
+ <li>
+ <a class:active={l === $locale} href={`${replaceLocaleInUrl($page.url, l)}`}>
+ {l}
+ </a>
+ </li>
+ {/each}
+</ul>
diff --git a/src/global.d.ts b/src/global.d.ts
new file mode 100644
index 0000000..e49922a
--- /dev/null
+++ b/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/src/hooks.server.ts b/src/hooks.server.ts
new file mode 100644
index 0000000..ddd9342
--- /dev/null
+++ b/src/hooks.server.ts
@@ -0,0 +1,43 @@
+import { detectLocale, i18n, isLocale } from '$i18n/i18n-util'
+import { loadAllLocales } from '$i18n/i18n-util.sync'
+import type { Handle, RequestEvent } from '@sveltejs/kit'
+import { initAcceptLanguageHeaderDetector } from 'typesafe-i18n/detectors'
+
+loadAllLocales()
+const L = i18n()
+
+export const handle: Handle = async ({ event, resolve }) => {
+ // read language slug
+ const [, lang] = event.url.pathname.split('/')
+
+ // redirect to base locale if no locale slug was found
+ if (!lang) {
+ const locale = getPreferredLocale(event)
+
+ return new Response(null, {
+ status: 302,
+ headers: { Location: `/${locale}` },
+ })
+ }
+
+ // if slug is not a locale, use base locale (e.g. api endpoints)
+ const locale = isLocale(lang) ? (lang as Locales) : getPreferredLocale(event)
+ const LL = L[locale]
+
+ // bind locale and translation functions to current request
+ event.locals.locale = locale
+ event.locals.LL = LL
+
+ console.info(LL.log({ fileName: 'hooks.server.ts' }))
+
+ // replace html lang attribute with correct language
+ return resolve(event, { transformPageChunk: ({ html }) => html.replace('%lang%', locale) })
+}
+
+const getPreferredLocale = ({ request }: RequestEvent) => {
+ // detect the preferred language the user has configured in his browser
+ // https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Accept-Language
+ const acceptLanguageDetector = initAcceptLanguageHeaderDetector(request)
+
+ return detectLocale(acceptLanguageDetector)
+} \ No newline at end of file
diff --git a/src/i18n/en/index.ts b/src/i18n/en/index.ts
new file mode 100644
index 0000000..796f4a5
--- /dev/null
+++ b/src/i18n/en/index.ts
@@ -0,0 +1,13 @@
+import type { BaseTranslation } from '../i18n-types'
+
+const en = {
+ contact: {
+ title: "Contact us",
+ addressTitle: "Address",
+ emailTitle: "Email",
+ phoneTitle: "Phone"
+ },
+ homeTitle: "Home",
+} satisfies BaseTranslation
+
+export default en
diff --git a/src/i18n/formatters.ts b/src/i18n/formatters.ts
new file mode 100644
index 0000000..78734f9
--- /dev/null
+++ b/src/i18n/formatters.ts
@@ -0,0 +1,11 @@
+import type { FormattersInitializer } from 'typesafe-i18n'
+import type { Locales, Formatters } from './i18n-types'
+
+export const initFormatters: FormattersInitializer<Locales, Formatters> = (locale: Locales) => {
+
+ const formatters: Formatters = {
+ // add your formatter functions here
+ }
+
+ return formatters
+}
diff --git a/src/i18n/i18n-svelte.ts b/src/i18n/i18n-svelte.ts
new file mode 100644
index 0000000..6cdffb3
--- /dev/null
+++ b/src/i18n/i18n-svelte.ts
@@ -0,0 +1,12 @@
+// This file was auto-generated by 'typesafe-i18n'. Any manual changes will be overwritten.
+/* eslint-disable */
+
+import { initI18nSvelte } from 'typesafe-i18n/svelte'
+import type { Formatters, Locales, TranslationFunctions, Translations } from './i18n-types'
+import { loadedFormatters, loadedLocales } from './i18n-util'
+
+const { locale, LL, setLocale } = initI18nSvelte<Locales, Translations, TranslationFunctions, Formatters>(loadedLocales, loadedFormatters)
+
+export { locale, LL, setLocale }
+
+export default LL
diff --git a/src/i18n/i18n-types.ts b/src/i18n/i18n-types.ts
new file mode 100644
index 0000000..9a32b2f
--- /dev/null
+++ b/src/i18n/i18n-types.ts
@@ -0,0 +1,66 @@
+// This file was auto-generated by 'typesafe-i18n'. Any manual changes will be overwritten.
+/* eslint-disable */
+import type { BaseTranslation as BaseTranslationType, LocalizedString } from 'typesafe-i18n'
+
+export type BaseTranslation = BaseTranslationType
+export type BaseLocale = 'en'
+
+export type Locales =
+ | 'en'
+ | 'nb'
+
+export type Translation = RootTranslation
+
+export type Translations = RootTranslation
+
+type RootTranslation = {
+ contact: {
+ /**
+ * C​o​n​t​a​c​t​ ​u​s
+ */
+ title: string
+ /**
+ * A​d​d​r​e​s​s
+ */
+ addressTitle: string
+ /**
+ * E​m​a​i​l
+ */
+ emailTitle: string
+ /**
+ * P​h​o​n​e
+ */
+ phoneTitle: string
+ }
+ /**
+ * H​o​m​e
+ */
+ homeTitle: string
+}
+
+export type TranslationFunctions = {
+ contact: {
+ /**
+ * Contact us
+ */
+ title: () => LocalizedString
+ /**
+ * Address
+ */
+ addressTitle: () => LocalizedString
+ /**
+ * Email
+ */
+ emailTitle: () => LocalizedString
+ /**
+ * Phone
+ */
+ phoneTitle: () => LocalizedString
+ }
+ /**
+ * Home
+ */
+ homeTitle: () => LocalizedString
+}
+
+export type Formatters = {}
diff --git a/src/i18n/i18n-util.async.ts b/src/i18n/i18n-util.async.ts
new file mode 100644
index 0000000..3f38e3e
--- /dev/null
+++ b/src/i18n/i18n-util.async.ts
@@ -0,0 +1,27 @@
+// This file was auto-generated by 'typesafe-i18n'. Any manual changes will be overwritten.
+/* eslint-disable */
+
+import { initFormatters } from './formatters'
+import type { Locales, Translations } from './i18n-types'
+import { loadedFormatters, loadedLocales, locales } from './i18n-util'
+
+const localeTranslationLoaders = {
+ en: () => import('./en'),
+ nb: () => import('./nb'),
+}
+
+const updateDictionary = (locale: Locales, dictionary: Partial<Translations>): Translations =>
+ loadedLocales[locale] = { ...loadedLocales[locale], ...dictionary }
+
+export const importLocaleAsync = async (locale: Locales): Promise<Translations> =>
+ (await localeTranslationLoaders[locale]()).default as unknown as Translations
+
+export const loadLocaleAsync = async (locale: Locales): Promise<void> => {
+ updateDictionary(locale, await importLocaleAsync(locale))
+ loadFormatters(locale)
+}
+
+export const loadAllLocalesAsync = (): Promise<void[]> => Promise.all(locales.map(loadLocaleAsync))
+
+export const loadFormatters = (locale: Locales): void =>
+ void (loadedFormatters[locale] = initFormatters(locale))
diff --git a/src/i18n/i18n-util.sync.ts b/src/i18n/i18n-util.sync.ts
new file mode 100644
index 0000000..f1a8e9e
--- /dev/null
+++ b/src/i18n/i18n-util.sync.ts
@@ -0,0 +1,26 @@
+// This file was auto-generated by 'typesafe-i18n'. Any manual changes will be overwritten.
+/* eslint-disable */
+
+import { initFormatters } from './formatters'
+import type { Locales, Translations } from './i18n-types'
+import { loadedFormatters, loadedLocales, locales } from './i18n-util'
+
+import en from './en'
+import nb from './nb'
+
+const localeTranslations = {
+ en,
+ nb,
+}
+
+export const loadLocale = (locale: Locales): void => {
+ if (loadedLocales[locale]) return
+
+ loadedLocales[locale] = localeTranslations[locale] as unknown as Translations
+ loadFormatters(locale)
+}
+
+export const loadAllLocales = (): void => locales.forEach(loadLocale)
+
+export const loadFormatters = (locale: Locales): void =>
+ void (loadedFormatters[locale] = initFormatters(locale))
diff --git a/src/i18n/i18n-util.ts b/src/i18n/i18n-util.ts
new file mode 100644
index 0000000..0d1cef0
--- /dev/null
+++ b/src/i18n/i18n-util.ts
@@ -0,0 +1,38 @@
+// This file was auto-generated by 'typesafe-i18n'. Any manual changes will be overwritten.
+/* eslint-disable */
+
+import { i18n as initI18n, i18nObject as initI18nObject, i18nString as initI18nString } from 'typesafe-i18n'
+import type { LocaleDetector } from 'typesafe-i18n/detectors'
+import type { LocaleTranslationFunctions, TranslateByString } from 'typesafe-i18n'
+import { detectLocale as detectLocaleFn } from 'typesafe-i18n/detectors'
+import { initExtendDictionary } from 'typesafe-i18n/utils'
+import type { Formatters, Locales, Translations, TranslationFunctions } from './i18n-types'
+
+export const baseLocale: Locales = 'en'
+
+export const locales: Locales[] = [
+ 'en',
+ 'nb'
+]
+
+export const isLocale = (locale: string): locale is Locales => locales.includes(locale as Locales)
+
+export const loadedLocales: Record<Locales, Translations> = {} as Record<Locales, Translations>
+
+export const loadedFormatters: Record<Locales, Formatters> = {} as Record<Locales, Formatters>
+
+export const extendDictionary = initExtendDictionary<Translations>()
+
+export const i18nString = (locale: Locales): TranslateByString => initI18nString<Locales, Formatters>(locale, loadedFormatters[locale])
+
+export const i18nObject = (locale: Locales): TranslationFunctions =>
+ initI18nObject<Locales, Translations, TranslationFunctions, Formatters>(
+ locale,
+ loadedLocales[locale],
+ loadedFormatters[locale]
+ )
+
+export const i18n = (): LocaleTranslationFunctions<Locales, Translations, TranslationFunctions> =>
+ initI18n<Locales, Translations, TranslationFunctions, Formatters>(loadedLocales, loadedFormatters)
+
+export const detectLocale = (...detectors: LocaleDetector[]): Locales => detectLocaleFn<Locales>(baseLocale, locales, ...detectors)
diff --git a/src/i18n/nb/index.ts b/src/i18n/nb/index.ts
new file mode 100644
index 0000000..9e13fba
--- /dev/null
+++ b/src/i18n/nb/index.ts
@@ -0,0 +1,13 @@
+import type { Translation } from '../i18n-types'
+
+const nb = {
+ contact: {
+ title: "Kontakt oss",
+ addressTitle: "Adresse",
+ emailTitle: "E-postadresse",
+ phoneTitle: "Telefon"
+ },
+ homeTitle: "Hjem",
+} satisfies Translation
+
+export default nb
diff --git a/src/lib/sanity-client.ts b/src/lib/sanity-client.ts
new file mode 100644
index 0000000..70be363
--- /dev/null
+++ b/src/lib/sanity-client.ts
@@ -0,0 +1,9 @@
+import { env } from "$env/dynamic/private";
+import sanityClient from "@sanity/client";
+
+export const sanity = sanityClient({
+ projectId: env.SANITY_STUDIO_API_PROJECT_ID,
+ dataset: env.SANITY_STUDIO_API_DATASET,
+ apiVersion: "2022-03-24",
+ useCdn: true,
+}); \ No newline at end of file
diff --git a/src/lib/utils.ts b/src/lib/utils.ts
new file mode 100644
index 0000000..4ec8b01
--- /dev/null
+++ b/src/lib/utils.ts
@@ -0,0 +1,27 @@
+// Replaces the locale slug in a URL.
+//
+// If the `full` argument is set to `true`, the full URL is returned as a string.
+// e.g. https://mywebsite.com/en/blog/article-1 => https://mywebsite.com/de/blog/article-1
+//
+// Otherwise (default) the URL relative to the base is returned.
+// e.g. https://mywebsite.com/en/blog/article-1 => /de/blog/article-1
+export const replaceLocaleInUrl = (url: URL, locale: string, full = false): string => {
+ const [, , ...rest] = url.pathname.split('/')
+ const new_pathname = `/${[locale, ...rest].join('/')}`
+ if (!full) {
+ return `${new_pathname}${url.search}`
+ }
+ const newUrl = new URL(url.toString())
+ newUrl.pathname = new_pathname
+ return newUrl.toString()
+}
+
+export function fromLocalizedString(localizedString: string | object, locale: Locales) {
+ if (typeof localizedString === "string") return localizedString;
+ // @ts-ignore
+ if (localizedString[locale]) return localizedString[locale];
+ // @ts-ignore
+ if (localizedString["nb"]) return localizedString["nb"];
+ // @ts-ignore
+ if (localizedString["en"]) return localizedString["en"];
+}
diff --git a/src/params/lang.ts b/src/params/lang.ts
new file mode 100644
index 0000000..5f0b857
--- /dev/null
+++ b/src/params/lang.ts
@@ -0,0 +1,7 @@
+import type { ParamMatcher } from '@sveltejs/kit'
+import { isLocale } from '$i18n/i18n-util'
+
+// only accept valid languages as a segment in the URL
+export const match: ParamMatcher = (param) => {
+ return isLocale(param)
+} \ No newline at end of file
diff --git a/src/routes/+layout.server.ts b/src/routes/+layout.server.ts
new file mode 100644
index 0000000..fc087d8
--- /dev/null
+++ b/src/routes/+layout.server.ts
@@ -0,0 +1,6 @@
+import type { LayoutServerLoad } from './$types'
+
+export const load: LayoutServerLoad = ({ locals: { locale, LL } }) => {
+ // pass locale information from "server-context" to "shared server + client context"
+ return { locale }
+}
diff --git a/src/routes/+layout.svelte b/src/routes/+layout.svelte
index 30062ed..990dd94 100644
--- a/src/routes/+layout.svelte
+++ b/src/routes/+layout.svelte
@@ -1,8 +1,19 @@
<script lang="ts">
- import '../app.postcss';
- import type { LayoutData } from './$types';
+ import { page } from "$app/stores";
+ import "../app.postcss";
+ import type { LayoutData } from "./$types";
+ import { locales, baseLocale } from "$i18n/i18n-util";
+ import { replaceLocaleInUrl } from "$lib/utils";
export let data: LayoutData;
</script>
+<svelte:head>
+ <title>{$page.data.title || "auroraklinikken.no"}</title>
+ {#each locales as l}
+ <link rel="alternate" hreflang={l} href={`${replaceLocaleInUrl($page.url, l, true)}`} />
+ {/each}
+ <link rel="alternate" hreflang="x-default" href={`${replaceLocaleInUrl($page.url, baseLocale, true)}`} />
+</svelte:head>
+
<slot />
diff --git a/src/routes/+layout.ts b/src/routes/+layout.ts
new file mode 100644
index 0000000..5a78ab1
--- /dev/null
+++ b/src/routes/+layout.ts
@@ -0,0 +1,14 @@
+import type { LayoutLoad } from './$types'
+import { loadLocaleAsync } from '$i18n/i18n-util.async'
+import { setLocale } from '$i18n/i18n-svelte'
+
+export const load = (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 }
+}) satisfies LayoutLoad<{ locale: Locales }>; \ No newline at end of file
diff --git a/src/routes/+page.svelte b/src/routes/+page.svelte
deleted file mode 100644
index e69de29..0000000
--- a/src/routes/+page.svelte
+++ /dev/null
diff --git a/src/routes/[lang=lang]/+page.server.ts b/src/routes/[lang=lang]/+page.server.ts
new file mode 100644
index 0000000..d3a98a5
--- /dev/null
+++ b/src/routes/[lang=lang]/+page.server.ts
@@ -0,0 +1,19 @@
+import { sanity } from '$lib/sanity-client';
+import type { PageServerLoad } from './$types';
+import groq from "groq";
+import type { ContactModel } from '$components/contact.svelte';
+import { fromLocalizedString } from '$lib/utils';
+
+export const load = (async ({ locals }) => {
+ const contactSection = await sanity.fetch(groq`*[_type == "contact"][0]`);
+ console.log(contactSection);
+
+ return {
+ contact: {
+ phone: fromLocalizedString(contactSection.phone, locals.locale),
+ email: fromLocalizedString(contactSection.email, locals.locale),
+ phoneHours: fromLocalizedString(contactSection.phoneHours, locals.locale),
+ addressLines: contactSection.addressLines.map((el: string | object) => fromLocalizedString(el, locals.locale)),
+ } as ContactModel
+ };
+}) satisfies PageServerLoad; \ No newline at end of file
diff --git a/src/routes/[lang=lang]/+page.svelte b/src/routes/[lang=lang]/+page.svelte
new file mode 100644
index 0000000..666aa80
--- /dev/null
+++ b/src/routes/[lang=lang]/+page.svelte
@@ -0,0 +1,17 @@
+<script lang="ts">
+ import Contact, { type ContactModel } from "$components/contact.svelte";
+ import type { PageData } from "./$types";
+
+ export let data: PageData;
+
+ type Model = {
+ contact: ContactModel;
+ };
+
+ const M: Model = {
+ contact: data.contact,
+ };
+ console.log(data);
+</script>
+
+<Contact model={M.contact} />
diff --git a/src/routes/[lang=lang]/+page.ts b/src/routes/[lang=lang]/+page.ts
new file mode 100644
index 0000000..fa3907b
--- /dev/null
+++ b/src/routes/[lang=lang]/+page.ts
@@ -0,0 +1,18 @@
+import type { PageLoad } from './$types';
+import LL, { setLocale } from '$i18n/i18n-svelte'
+import { get } from 'svelte/store'
+
+export const load = (async ({ parent, data }) => {
+ // wait for `+layout.ts` to load dictionary and pass locale information
+ const { locale } = await parent()
+
+ // 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)
+ // get the translation functions value from the store
+ const $LL = get(LL)
+ return {
+ title: $LL.homeTitle(),
+ contact: data.contact
+ }
+}) satisfies PageLoad; \ No newline at end of file