ivanhofer/typesafe-i18n-demo-sveltekit

Help on implementing SvelteKitAuth with i18n

Closed this issue · 4 comments

Hi,
I don't have any idea on how to implement both at the same time as they both modify the handle function in hooks.server.ts file

SvelteKitAuth is used like this :

import { SvelteKitAuth } from "@auth/sveltekit";
import GitHub from "@auth/core/providers/github";
import { GITHUB_ID, GITHUB_SECRET } from "$env/static/private";

export const handle = SvelteKitAuth({
  providers: [GitHub({ clientId: GITHUB_ID, clientSecret: GITHUB_SECRET })],
});

or like this

import { SvelteKitAuth } from "@auth/sveltekit"
import GitHub from "@auth/core/providers/github"
import type { Handle } from "@sveltejs/kit";

export const handle = SvelteKitAuth(async (event) => {
  const authOptions = {
    providers: [GitHub({ clientId: event.platform.env.GITHUB_ID, clientSecret: event.platform.env.GITHUB_SECRET })]
    secret: event.platform.env.AUTH_SECRET,
    trustHost: true
  }
  return authOptions
}) satisfies Handle;

whereas typesafe-i18n does this :

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

Ref: https://authjs.dev/reference/sveltekit

Does anyone have a clue on how to make them work together?

Re,
solved it by adapting this code in the doc : https://authjs.dev/reference/sveltekit#per-path :)

// https://kit.svelte.dev/docs/modules#sveltejs-kit-hooks
// https://authjs.dev/reference/sveltekit#per-path

import type { Handle } from "@sveltejs/kit";
import { sequence } from '@sveltejs/kit/hooks';

import { SvelteKitAuth } from "@auth/sveltekit"
import GitHub from "@auth/core/providers/github"
import { GITHUB_ID, GITHUB_SECRET } from "$env/static/private"

// i18n
async function translation({ event, resolve }) {
    // do i18n stuff
    // ...
    return resolve(event, { transformPageChunk: ({ html }) => html.replace('%lang%', locale) });
}

// First handle translation, then SvelteKitAuth
export const handle: Handle = sequence(
    translation,
    SvelteKitAuth({
      providers: [GitHub({ clientId: GITHUB_ID, clientSecret: GITHUB_SECRET })],
    })
);

Re,
also need to modify src/routes/+layout.server.ts like this

import type { LayoutServerLoad } from './$types'

export const load: LayoutServerLoad = async ({ locals: { locale, LL, getSession }, route, params, url }) => {
	//console.info(LL.log({ fileName: '+layout.server.ts' }))

	// Get params of current page : permet de connaitre le route
	console.log('Get params of current page', route, params, url)

	// pass locale information from "server-context" to "shared server + client context"
	return {
		locale,
		session: await getSession(),
	}
}

as well as returning session variable in src/routes/+layout.ts like this :

import type { LayoutLoad } from './$types'
import type { Locales } from '$i18n/i18n-types'
import { loadLocaleAsync } from '$i18n/i18n-util.async'
import LL, { setLocale } from '$i18n/i18n-svelte'

import { get } from 'svelte/store'
import { browser } from '$app/environment'

export const load: LayoutLoad<{ locale: Locales }> = async ({ data: { locale, session }, url }) => {
	// 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)
	// get the translation functions value from the store
	const $LL = get(LL)
	console.info($LL.log({ fileName: '+layout.ts' }))
	//console.log(url)

	// pass locale to the "rendering context"
	return { locale, session }
}

Great to see you found the solution by yourself :) . Happy coding!

Thanks! :)