Merged in feat/sw-2333-package-and-sas-i18n (pull request #2538)

feat(SW-2333): I18n for multiple apps and packages

* Set upp i18n in partner-sas

* Adapt lokalise workflow to monorepo

* Fix layout props


Approved-by: Linus Flood
This commit is contained in:
Anton Gunnarsson
2025-07-10 07:00:03 +00:00
parent 2c0e8965e2
commit 233c685e52
31 changed files with 48133 additions and 210 deletions

View File

@@ -0,0 +1,43 @@
"use client"
import { type IntlConfig, IntlProvider } from "react-intl"
import { logger } from "@scandic-hotels/common/logger"
type ClientIntlProviderProps = React.PropsWithChildren<
Pick<IntlConfig, "defaultLocale" | "locale" | "messages">
>
const logged: Record<string, boolean> = {}
export default function ClientIntlProvider({
children,
locale,
defaultLocale,
messages,
}: ClientIntlProviderProps) {
return (
<IntlProvider
locale={locale}
defaultLocale={defaultLocale}
messages={messages}
onError={(err) => {
let msg = err.message
if (err.code === "MISSING_TRANSLATION") {
const id = err.descriptor?.id
if (id) {
msg = id
}
}
if (!logged[msg]) {
logged[msg] = true
logger.warn("IntlProvider", err)
}
}}
>
{children}
</IntlProvider>
)
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,20 @@
{
"WcBpRV": [
{
"type": 1,
"value": "roomSizeMin"
},
{
"type": 0,
"value": "-"
},
{
"type": 1,
"value": "roomSizeMax"
},
{
"type": 0,
"value": " m²"
}
]
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,35 @@
import "server-only"
import { createIntl, createIntlCache } from "@formatjs/intl"
import { Lang } from "@scandic-hotels/common/constants/language"
import { getLang } from "./serverContext"
import type { IntlShape } from "react-intl"
const cache = createIntlCache()
const instances: Partial<Record<Lang, IntlShape>> = {}
export async function getMessages(lang: Lang): Promise<Record<string, string>> {
return (await import(`./dictionaries/${lang}.json`)).default
}
export async function getIntl(options?: { lang: Lang | undefined }) {
const lang = options?.lang || (await getLang())
if (!instances[lang]) {
const messages = await getMessages(lang)
instances[lang] = createIntl<React.ReactNode>(
{
defaultLocale: Lang.en,
locale: lang,
messages,
},
cache
)
}
return instances[lang]
}

View File

@@ -0,0 +1,34 @@
import "server-only"
import { headers } from "next/headers"
import { cache } from "react"
import { Lang } from "@scandic-hotels/common/constants/language"
import { languageSchema } from "@scandic-hotels/common/utils/languages"
const getRef = cache(() => ({ current: undefined as Lang | undefined }))
/**
* Set the language for the current request
*
* It works kind of like React's context,
* but on the server side, per request.
*
* @param newLang
*/
export function setLang(newLang: Lang) {
const parseResult = languageSchema.safeParse(newLang)
getRef().current = parseResult.success ? parseResult.data : Lang.en
}
/**
* Get the global language set for the current request
*/
export async function getLang(): Promise<Lang> {
const contextLang = getRef().current
const headersList = await headers()
const headerLang = headersList.get("x-lang") as Lang
const l = contextLang || headerLang || Lang.en
return l
}