From d00f4fa695271a11a7c4fb4ff22f69416c51674d Mon Sep 17 00:00:00 2001 From: Cyril Date: Mon, 9 Mar 2026 10:37:00 +0100 Subject: [PATCH] =?UTF-8?q?=E2=99=BF=EF=B8=8F(frontend)=20sync=20html=20la?= =?UTF-8?q?ng=20attribute=20with=20i18n=20for=20screen=20readers?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Set document.documentElement.lang in i18n init and on languageChanged, --- CHANGELOG.md | 4 ++++ src/frontend/src/App.tsx | 3 +-- src/frontend/src/i18n/init.ts | 10 +++++++++- 3 files changed, 14 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index c80a9ebd..00a51a98 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,10 @@ and this project adheres to ## [Unreleased] +### Changed + +- ♿️(frontend) sync html lang attribute with i18n for screen readers #1111 + ## [1.10.0] - 2026-03-05 ### Fixed diff --git a/src/frontend/src/App.tsx b/src/frontend/src/App.tsx index 789f7d09..7921a2c8 100644 --- a/src/frontend/src/App.tsx +++ b/src/frontend/src/App.tsx @@ -4,7 +4,7 @@ import { Suspense } from 'react' import { ReactQueryDevtools } from '@tanstack/react-query-devtools' import { QueryClientProvider } from '@tanstack/react-query' import { useTranslation } from 'react-i18next' -import { useLang, useTitle } from 'hoofd' +import { useTitle } from 'hoofd' import { Switch, Route } from 'wouter' import { I18nProvider } from 'react-aria-components' import { Layout } from './layout/Layout' @@ -17,7 +17,6 @@ import { useIsSdkContext } from '@/features/sdk/hooks/useIsSdkContext' function App() { const { i18n } = useTranslation() - useLang(i18n.language) useTitle(import.meta.env.VITE_APP_TITLE ?? '') const isSDKContext = useIsSdkContext() diff --git a/src/frontend/src/i18n/init.ts b/src/frontend/src/i18n/init.ts index e0c38341..e0176392 100644 --- a/src/frontend/src/i18n/init.ts +++ b/src/frontend/src/i18n/init.ts @@ -3,6 +3,7 @@ import resourcesToBackend from 'i18next-resources-to-backend' import { initReactI18next } from 'react-i18next' import LanguageDetector from 'i18next-browser-languagedetector' const i18nDefaultNamespace = 'global' +const fallbackLng = 'fr' i18n.setDefaultNamespace(i18nDefaultNamespace) i18n @@ -15,7 +16,7 @@ i18n .use(LanguageDetector) .init({ supportedLngs: ['en', 'fr', 'nl', 'de'], - fallbackLng: 'fr', + fallbackLng, ns: i18nDefaultNamespace, detection: { order: ['localStorage', 'navigator'], @@ -24,3 +25,10 @@ i18n escapeValue: false, }, }) + .then(() => { + document.documentElement.setAttribute('lang', i18n.language || fallbackLng) + }) + +i18n.on('languageChanged', (lang) => { + document.documentElement.setAttribute('lang', lang) +})