️(frontend) sync html lang attribute with i18n for screen readers

Set document.documentElement.lang in i18n init and on languageChanged,
This commit is contained in:
Cyril
2026-03-09 10:37:00 +01:00
committed by aleb_the_flash
parent fd36469fc2
commit d00f4fa695
3 changed files with 14 additions and 3 deletions
+4
View File
@@ -8,6 +8,10 @@ and this project adheres to
## [Unreleased] ## [Unreleased]
### Changed
- ♿️(frontend) sync html lang attribute with i18n for screen readers #1111
## [1.10.0] - 2026-03-05 ## [1.10.0] - 2026-03-05
### Fixed ### Fixed
+1 -2
View File
@@ -4,7 +4,7 @@ import { Suspense } from 'react'
import { ReactQueryDevtools } from '@tanstack/react-query-devtools' import { ReactQueryDevtools } from '@tanstack/react-query-devtools'
import { QueryClientProvider } from '@tanstack/react-query' import { QueryClientProvider } from '@tanstack/react-query'
import { useTranslation } from 'react-i18next' import { useTranslation } from 'react-i18next'
import { useLang, useTitle } from 'hoofd' import { useTitle } from 'hoofd'
import { Switch, Route } from 'wouter' import { Switch, Route } from 'wouter'
import { I18nProvider } from 'react-aria-components' import { I18nProvider } from 'react-aria-components'
import { Layout } from './layout/Layout' import { Layout } from './layout/Layout'
@@ -17,7 +17,6 @@ import { useIsSdkContext } from '@/features/sdk/hooks/useIsSdkContext'
function App() { function App() {
const { i18n } = useTranslation() const { i18n } = useTranslation()
useLang(i18n.language)
useTitle(import.meta.env.VITE_APP_TITLE ?? '') useTitle(import.meta.env.VITE_APP_TITLE ?? '')
const isSDKContext = useIsSdkContext() const isSDKContext = useIsSdkContext()
+9 -1
View File
@@ -3,6 +3,7 @@ import resourcesToBackend from 'i18next-resources-to-backend'
import { initReactI18next } from 'react-i18next' import { initReactI18next } from 'react-i18next'
import LanguageDetector from 'i18next-browser-languagedetector' import LanguageDetector from 'i18next-browser-languagedetector'
const i18nDefaultNamespace = 'global' const i18nDefaultNamespace = 'global'
const fallbackLng = 'fr'
i18n.setDefaultNamespace(i18nDefaultNamespace) i18n.setDefaultNamespace(i18nDefaultNamespace)
i18n i18n
@@ -15,7 +16,7 @@ i18n
.use(LanguageDetector) .use(LanguageDetector)
.init({ .init({
supportedLngs: ['en', 'fr', 'nl', 'de'], supportedLngs: ['en', 'fr', 'nl', 'de'],
fallbackLng: 'fr', fallbackLng,
ns: i18nDefaultNamespace, ns: i18nDefaultNamespace,
detection: { detection: {
order: ['localStorage', 'navigator'], order: ['localStorage', 'navigator'],
@@ -24,3 +25,10 @@ i18n
escapeValue: false, escapeValue: false,
}, },
}) })
.then(() => {
document.documentElement.setAttribute('lang', i18n.language || fallbackLng)
})
i18n.on('languageChanged', (lang) => {
document.documentElement.setAttribute('lang', lang)
})