From c7a88b98bc73e7c9121fb44bedf3cbb8ae4eef44 Mon Sep 17 00:00:00 2001 From: Nevo David Date: Wed, 25 Mar 2026 14:42:00 +0700 Subject: [PATCH] feat: language switch --- apps/frontend/src/app/(app)/layout.tsx | 5 +--- apps/frontend/src/proxy.ts | 29 +------------------ .../get.translation.service.backend.ts | 10 ++----- .../src/translation/i18next.ts | 9 +++--- 4 files changed, 8 insertions(+), 45 deletions(-) diff --git a/apps/frontend/src/app/(app)/layout.tsx b/apps/frontend/src/app/(app)/layout.tsx index eb5a8834..91ff5464 100644 --- a/apps/frontend/src/app/(app)/layout.tsx +++ b/apps/frontend/src/app/(app)/layout.tsx @@ -15,8 +15,6 @@ import { PHProvider } from '@gitroom/react/helpers/posthog'; import UtmSaver from '@gitroom/helpers/utils/utm.saver'; import { DubAnalytics } from '@gitroom/frontend/components/layout/dubAnalytics'; import { FacebookComponent } from '@gitroom/frontend/components/layout/facebook.component'; -import { headers } from 'next/headers'; -import { headerName } from '@gitroom/react/translation/i18n.config'; import { HtmlComponent } from '@gitroom/frontend/components/layout/html.component'; import Script from 'next/script'; // import dynamicLoad from 'next/dynamic'; @@ -34,7 +32,6 @@ const jakartaSans = Plus_Jakarta_Sans({ }); export default async function AppLayout({ children }: { children: ReactNode }) { - const allHeaders = await headers(); const Plausible = !!process.env.STRIPE_PUBLISHABLE_KEY ? PlausibleProvider : Fragment; @@ -80,7 +77,7 @@ export default async function AppLayout({ children }: { children: ReactNode }) { disableXAnalytics={!!process.env.DISABLE_X_ANALYTICS} sentryDsn={process.env.NEXT_PUBLIC_SENTRY_DSN!} extensionId={process.env.EXTENSION_ID || ''} - language={allHeaders.get(headerName)} + language="en" transloadit={ process.env.TRANSLOADIT_AUTH && process.env.TRANSLOADIT_TEMPLATE ? [ diff --git a/apps/frontend/src/proxy.ts b/apps/frontend/src/proxy.ts index 07b9eb1c..cecc2c5e 100644 --- a/apps/frontend/src/proxy.ts +++ b/apps/frontend/src/proxy.ts @@ -2,14 +2,6 @@ import { NextResponse } from 'next/server'; import type { NextRequest } from 'next/server'; import { getCookieUrlFromDomain } from '@gitroom/helpers/subdomain/subdomain.management'; import { internalFetch } from '@gitroom/helpers/utils/internal.fetch'; -import acceptLanguage from 'accept-language'; -import { - cookieName, - fallbackLng, - headerName, - languages, -} from '@gitroom/react/translation/i18n.config'; -acceptLanguage.languages(languages); // This function can be marked `async` if using `await` inside export async function proxy(request: NextRequest) { @@ -18,27 +10,8 @@ export async function proxy(request: NextRequest) { request.cookies.get('auth') || request.headers.get('auth') || nextUrl.searchParams.get('loggedAuth'); - const lng = request.cookies.has(cookieName) - ? acceptLanguage.get(request.cookies.get(cookieName).value) - : acceptLanguage.get( - request.headers.get('Accept-Language') || - request.headers.get('accept-language') - ); - const requestHeaders = new Headers(request.headers); - if (lng) { - requestHeaders.set(headerName, lng); - } - - const topResponse = NextResponse.next({ - request: { - headers: requestHeaders, - }, - }); - - if (lng) { - topResponse.headers.set(cookieName, lng); - } + const topResponse = NextResponse.next(); if (nextUrl.pathname.startsWith('/modal/') && !authCookie) { return NextResponse.redirect(new URL(`/auth/login-required`, nextUrl.href)); diff --git a/libraries/react-shared-libraries/src/translation/get.translation.service.backend.ts b/libraries/react-shared-libraries/src/translation/get.translation.service.backend.ts index b9001196..372fe9f5 100644 --- a/libraries/react-shared-libraries/src/translation/get.translation.service.backend.ts +++ b/libraries/react-shared-libraries/src/translation/get.translation.service.backend.ts @@ -1,17 +1,11 @@ import i18next from './i18next'; -import { headerName } from './i18n.config'; -import { headers } from 'next/headers'; +import { fallbackLng } from './i18n.config'; export async function getT(ns?: string, options?: any) { - const headerList = await headers(); - const lng = headerList.get(headerName); - if (lng && i18next.resolvedLanguage !== lng) { - await i18next.changeLanguage(lng); - } if (ns && !i18next.hasLoadedNamespace(ns)) { await i18next.loadNamespaces(ns); } return i18next.getFixedT( - lng ?? i18next.resolvedLanguage, + i18next.resolvedLanguage || fallbackLng, Array.isArray(ns) ? ns[0] : ns, options?.keyPrefix ); diff --git a/libraries/react-shared-libraries/src/translation/i18next.ts b/libraries/react-shared-libraries/src/translation/i18next.ts index f81706a0..8660120f 100644 --- a/libraries/react-shared-libraries/src/translation/i18next.ts +++ b/libraries/react-shared-libraries/src/translation/i18next.ts @@ -2,7 +2,7 @@ import i18next from 'i18next'; import LanguageDetector from 'i18next-browser-languagedetector'; import resourcesToBackend from 'i18next-resources-to-backend'; import { initReactI18next } from 'react-i18next/initReactI18next'; -import { fallbackLng, languages, defaultNS } from './i18n.config'; +import { fallbackLng, languages, defaultNS, cookieName } from './i18n.config'; const runsOnServerSide = typeof window === 'undefined'; i18next @@ -14,15 +14,14 @@ i18next }) ) .init({ - // debug: true, supportedLngs: languages, fallbackLng, - lng: undefined, - // let detect the language on client side + lng: runsOnServerSide ? fallbackLng : undefined, fallbackNS: defaultNS, defaultNS, detection: { - order: runsOnServerSide ? ['cookie', 'header'] : ['cookie'], + order: ['cookie'], + lookupCookie: cookieName, caches: ['cookie'], }, preload: runsOnServerSide ? languages : [],