🐛 Fix locale detection (#1631)

This commit is contained in:
Luke Vella 2025-03-14 11:23:46 +00:00 committed by GitHub
parent d826f57050
commit 7ff2661048
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
11 changed files with 45 additions and 46 deletions

View file

@ -20,7 +20,6 @@
"@rallly/utils": "*",
"@svgr/webpack": "^6.5.1",
"@vercel/analytics": "^0.1.8",
"accept-language-parser": "^1.5.0",
"dayjs": "^1.11.10",
"gray-matter": "^4.0.3",
"i18next": "^24.2.2",

View file

@ -1,17 +1,8 @@
import { supportedLngs } from "@rallly/languages";
import languageParser from "accept-language-parser";
import { getPreferredLocale } from "@rallly/languages/get-preferred-locale";
import type { NextRequest } from "next/server";
import { NextResponse } from "next/server";
export async function getLocaleFromHeader(req: NextRequest) {
const headers = req.headers;
const acceptLanguageHeader = headers.get("accept-language");
const localeFromHeader = acceptLanguageHeader
? languageParser.pick(supportedLngs, acceptLanguageHeader)
: null;
return localeFromHeader ?? "en";
}
export async function middleware(request: NextRequest) {
const { pathname } = request.nextUrl;
const localeInPath = supportedLngs.find(
@ -28,7 +19,7 @@ export async function middleware(request: NextRequest) {
return;
}
const locale = await getLocaleFromHeader(request);
const locale = await getPreferredLocale(request);
request.nextUrl.pathname = `/${locale}${pathname}`;
if (locale === "en") {

View file

@ -47,7 +47,6 @@
"@upstash/ratelimit": "^1.2.1",
"@vercel/functions": "^1.5.2",
"@vercel/kv": "^2.0.0",
"accept-language-parser": "^1.5.0",
"ai": "^4.1.50",
"autoprefixer": "^10.4.13",
"calendar-link": "^2.6.0",
@ -88,7 +87,6 @@
"@playwright/test": "^1.49.1",
"@rallly/eslint-config": "*",
"@rallly/tsconfig": "*",
"@types/accept-language-parser": "^1.5.3",
"@types/color-hash": "^1.0.2",
"@types/lodash": "^4.14.178",
"@types/react-big-calendar": "^1.8.8",

View file

@ -1,9 +1,9 @@
import { getPreferredLocale } from "@rallly/languages/get-preferred-locale";
import * as Sentry from "@sentry/nextjs";
import { fetchRequestHandler } from "@trpc/server/adapters/fetch";
import { ipAddress } from "@vercel/functions";
import type { NextRequest } from "next/server";
import { getLocaleFromHeader } from "@/app/guest";
import { auth } from "@/next-auth";
import type { TRPCContext } from "@/trpc/context";
import { appRouter } from "@/trpc/routers";
@ -19,7 +19,7 @@ const handler = async (req: NextRequest) => {
req,
router: appRouter,
createContext: async () => {
const locale = await getLocaleFromHeader(req);
const locale = await getPreferredLocale(req);
const user = session?.user
? {
id: session.user.id,

View file

@ -1,15 +0,0 @@
import languages from "@rallly/languages";
import languageParser from "accept-language-parser";
import type { NextRequest } from "next/server";
const supportedLocales = Object.keys(languages);
export async function getLocaleFromHeader(req: NextRequest) {
// Check if locale is specified in header
const headers = req.headers;
const acceptLanguageHeader = headers.get("accept-language");
const localeFromHeader = acceptLanguageHeader
? languageParser.pick(supportedLocales, acceptLanguageHeader)
: null;
return localeFromHeader ?? "en";
}

View file

@ -1,8 +1,8 @@
import languages from "@rallly/languages";
import { getPreferredLocale } from "@rallly/languages/get-preferred-locale";
import { withPostHog } from "@rallly/posthog/next/middleware";
import { NextResponse } from "next/server";
import { getLocaleFromHeader } from "@/app/guest";
import { withAuth } from "@/auth/edge";
const supportedLocales = Object.keys(languages);
@ -25,7 +25,7 @@ export const middleware = withAuth(async (req) => {
newUrl.pathname = `/${locale}${newUrl.pathname}`;
} else {
// Check if locale is specified in header
locale = await getLocaleFromHeader(req);
locale = await getPreferredLocale(req);
newUrl.pathname = `/${locale}${newUrl.pathname}`;
}

View file

@ -2,6 +2,15 @@
"name": "@rallly/languages",
"version": "0.0.0",
"private": true,
"main": "index.ts",
"types": "index.ts"
"exports": {
".": "./src/index.ts",
"./*": "./src/*.ts"
},
"dependencies": {
"@formatjs/intl-localematcher": "^0.6.0",
"negotiator": "^1.0.0"
},
"devDependencies": {
"@types/negotiator": "^0.6.3"
}
}

View file

@ -0,0 +1,17 @@
import languages, { defaultLocale } from "./index";
import Negotiator from "negotiator";
import { match } from "@formatjs/intl-localematcher";
import type { NextRequest } from "next/server";
const locales = Object.keys(languages);
export async function getPreferredLocale(req: NextRequest) {
const preferredLanguages = new Negotiator({
headers: {
"accept-language": req.headers.get("accept-language") ?? "",
},
}).languages();
const locale = match(preferredLanguages, locales, defaultLocale);
return locale;
}

View file

@ -2892,7 +2892,7 @@
"@formatjs/ecma402-abstract" "2.3.3"
tslib "2"
"@formatjs/intl-localematcher@0.6.0":
"@formatjs/intl-localematcher@0.6.0", "@formatjs/intl-localematcher@^0.6.0":
version "0.6.0"
resolved "https://registry.yarnpkg.com/@formatjs/intl-localematcher/-/intl-localematcher-0.6.0.tgz#33cf0d33279572c990e02ab75a93122569878082"
integrity sha512-4rB4g+3hESy1bHSBG3tDFaMY2CH67iT7yne1e+0CLTsGLDcmoEWWpJjjpWVaYgYfYuohIRuo0E+N536gd2ZHZA==
@ -6267,11 +6267,6 @@
resolved "https://registry.yarnpkg.com/@tsconfig/strictest/-/strictest-2.0.2.tgz#97167bf99c03d0a010d9946ae8a702c4f62e2783"
integrity sha512-jt4jIsWKvUvuY6adJnQJlb/UR7DdjC8CjHI/OaSQruj2yX9/K6+KOvDt/vD6udqos/FUk5Op66CvYT7TBLYO5Q==
"@types/accept-language-parser@^1.5.3":
version "1.5.3"
resolved "https://registry.npmjs.org/@types/accept-language-parser/-/accept-language-parser-1.5.3.tgz"
integrity sha512-S8oM29O6nnRC3/+rwYV7GBYIIgNIZ52PCxqBG7OuItq9oATnYWy8FfeLKwvq5F7pIYjeeBSCI7y+l+Z9UEQpVQ==
"@types/accepts@*":
version "1.3.5"
resolved "https://registry.npmjs.org/@types/accepts/-/accepts-1.3.5.tgz"
@ -6510,6 +6505,11 @@
dependencies:
"@types/node" "*"
"@types/negotiator@^0.6.3":
version "0.6.3"
resolved "https://registry.yarnpkg.com/@types/negotiator/-/negotiator-0.6.3.tgz#29e8fce64e35f57f6fe9c624f8e4ed304357745a"
integrity sha512-JkXTOdKs5MF086b/pt8C3+yVp3iDUwG635L7oCH6HvJvvr6lSUU5oe/gLXnPEfYRROHjJIPgCV6cuAg8gGkntQ==
"@types/node@*":
version "20.8.9"
resolved "https://registry.npmjs.org/@types/node/-/node-20.8.9.tgz"
@ -7081,11 +7081,6 @@ abbrev@^2.0.0:
resolved "https://registry.yarnpkg.com/abbrev/-/abbrev-2.0.0.tgz#cf59829b8b4f03f89dda2771cb7f3653828c89bf"
integrity sha512-6/mh1E2u2YgEsCHdY0Yx5oW+61gZU+1vXaoiHHrpKeuRNNgFvS+/jrwHiQhB5apAf5oB7UB7E19ol2R2LKH8hQ==
accept-language-parser@^1.5.0:
version "1.5.0"
resolved "https://registry.npmjs.org/accept-language-parser/-/accept-language-parser-1.5.0.tgz"
integrity sha512-QhyTbMLYo0BBGg1aWbeMG4ekWtds/31BrEU+DONOg/7ax23vxpL03Pb7/zBmha2v7vdD3AyzZVWBVGEZxKOXWw==
accepts@~1.3.4:
version "1.3.8"
resolved "https://registry.yarnpkg.com/accepts/-/accepts-1.3.8.tgz#0bf0be125b67014adcb0b0921e62db7bffe16b2e"
@ -11625,6 +11620,11 @@ negotiator@0.6.3:
resolved "https://registry.yarnpkg.com/negotiator/-/negotiator-0.6.3.tgz#58e323a72fedc0d6f9cd4d31fe49f51479590ccd"
integrity sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==
negotiator@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/negotiator/-/negotiator-1.0.0.tgz#b6c91bb47172d69f93cfd7c357bbb529019b5f6a"
integrity sha512-8Ofs/AUQh8MaEcrlq5xOX0CQ9ypTF5dl78mjlMNfOK08fzpgTHQRQPBxcPlEtIw0yRpws+Zo/3r+5WRby7u3Gg==
neo-async@^2.6.2:
version "2.6.2"
resolved "https://registry.yarnpkg.com/neo-async/-/neo-async-2.6.2.tgz#b4aafb93e3aeb2d8174ca53cf163ab7d7308305f"