Remember selected language

Closes #921
This commit is contained in:
Kalle
2022-09-25 15:55:22 +03:00
parent 9b28490450
commit 3129822c49
4 changed files with 40 additions and 20 deletions

View File

@@ -1,6 +1,6 @@
import { useTranslation } from "react-i18next";
import { languages } from "~/modules/i18n";
import { Button } from "../Button";
import { LinkButton } from "../Button";
import { GlobeIcon } from "../icons/Globe";
import { Popover } from "../Popover";
@@ -14,17 +14,17 @@ export function LanguageChanger() {
>
<div className="layout__user-popover">
{languages.map((lang) => (
<Button
<LinkButton
key={lang.code}
tiny
onClick={() => void i18n.changeLanguage(lang.code)}
variant="minimal"
className={
i18n.language !== lang.code ? "text-main-forced" : undefined
}
to={`?lng=${lang.code}`}
>
{lang.name}
</Button>
</LinkButton>
))}
</div>
</Popover>

View File

@@ -1,10 +1,20 @@
import { createCookie } from "@remix-run/node";
import Backend from "i18next-fs-backend";
import { resolve } from "node:path";
import { RemixI18Next } from "remix-i18next";
import { config } from "./config";
const TEN_YEARS_IN_SECONDS = 31_536_000 * 10;
export const i18nCookie = createCookie("i18n", {
sameSite: "lax",
path: "/",
maxAge: TEN_YEARS_IN_SECONDS,
});
export const i18next = new RemixI18Next({
detection: {
cookie: i18nCookie,
supportedLanguages: config.supportedLngs,
fallbackLanguage: config.fallbackLng,
},

View File

@@ -1,4 +1,4 @@
export { i18nLoader } from "./loader";
export { i18Instance } from "./loader.server";
export { i18next } from "./i18next.server";
export { i18next, i18nCookie } from "./i18next.server";
export { DEFAULT_LANGUAGE, languages } from "./config";

View File

@@ -25,7 +25,7 @@ import { db } from "./db";
import type { FindAllPatrons } from "./db/models/users/queries.server";
import type { UserWithPlusTier } from "./db/types";
import { getUser } from "./modules/auth";
import { DEFAULT_LANGUAGE, i18next } from "./modules/i18n";
import { DEFAULT_LANGUAGE, i18nCookie, i18next } from "./modules/i18n";
import { useChangeLanguage } from "remix-i18next";
import { useTranslation } from "react-i18next";
import { Theme, ThemeHead, useTheme, ThemeProvider } from "./modules/theme";
@@ -33,7 +33,12 @@ import { getThemeSession } from "./modules/theme/session.server";
import { COMMON_PREVIEW_IMAGE } from "./utils/urls";
import { ConditionalScrollRestoration } from "./components/ConditionalScrollRestoration";
export const unstable_shouldReload: ShouldReloadFunction = () => false;
export const unstable_shouldReload: ShouldReloadFunction = ({ url }) => {
// reload on language change so the selected language gets set into the cookie
const lang = url.searchParams.get("lng");
return Boolean(lang);
};
export const links: LinksFunction = () => {
return [
@@ -68,19 +73,24 @@ export const loader: LoaderFunction = async ({ request }) => {
const locale = await i18next.getLocale(request);
const themeSession = await getThemeSession(request);
return json<RootLoaderData>({
locale,
theme: themeSession.getTheme(),
patrons: db.users.findAllPatrons(),
user: user
? {
discordAvatar: user.discordAvatar,
discordId: user.discordId,
id: user.id,
plusTier: user.plusTier,
}
: undefined,
});
return json<RootLoaderData>(
{
locale,
theme: themeSession.getTheme(),
patrons: db.users.findAllPatrons(),
user: user
? {
discordAvatar: user.discordAvatar,
discordId: user.discordId,
id: user.id,
plusTier: user.plusTier,
}
: undefined,
},
{
headers: { "Set-Cookie": await i18nCookie.serialize(locale) },
}
);
};
export const handle = {