* move setLang() to a root layout

* fix: findLang only returns acceptable languages
* fix: fallback to use header x-lang if we haven't setLang yet
* fix: languageSchema, allow uppercase

Approved-by: Linus Flood
This commit is contained in:
Joakim Jäderberg
2025-02-19 09:06:37 +00:00
parent d27163a915
commit 873183ec2f
45 changed files with 159 additions and 117 deletions

View File

@@ -12,7 +12,7 @@ We have a hook called `useLang` that directly returns the `lang` parameter from
In order to not prop drill that all the way from a page we use React's `cache` in a way that resembles React`s context, but on the server side.
For this to work we must set the language with `setLang` on all root layouts and pages, including pages in parallel routes. Then we can use `getLang` in the components where we need the language.
For this to work we must set the language with `setLang` on the topmost layout
This was inspired by [server-only-context](https://github.com/manvalls/server-only-context)

View File

@@ -1,8 +1,13 @@
import "server-only"
import { headers } from "next/headers"
import { cache } from "react"
import { Lang } from "@/constants/languages"
const getRef = cache(() => ({ current: Lang.en }))
import { languageSchema } from "@/utils/languages"
const getRef = cache(() => ({ current: undefined as Lang | undefined }))
/**
* Set the language for the current request
@@ -13,12 +18,17 @@ const getRef = cache(() => ({ current: Lang.en }))
* @param newLang
*/
export function setLang(newLang: Lang) {
getRef().current = newLang
const parseResult = languageSchema.safeParse(newLang)
getRef().current = parseResult.success ? parseResult.data : Lang.en
}
/**
* Get the global language set for the current request
*/
export function getLang() {
return getRef().current
export function getLang(): Lang {
const contextLang = getRef().current
const headerLang = headers().get("x-lang") as Lang
const l = contextLang || headerLang || Lang.en
return l
}