0
Fork 0
mirror of https://github.com/logto-io/logto.git synced 2024-12-30 20:33:54 -05:00

refactor: set lang attribute for html tag (#6536)

* refactor: set `lang` attribute for html tag

* refactor: use shared i18next instance

* refactor: align html attr usage
This commit is contained in:
Gao Sun 2024-09-09 17:10:39 +08:00 committed by GitHub
parent b837efead6
commit 3b9714b993
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
7 changed files with 46 additions and 4 deletions

View file

@ -0,0 +1,7 @@
---
"@logto/experience": patch
"@logto/demo-app": patch
"@logto/console": patch
---
set `lang` attribute for `<html>`

View file

@ -7,6 +7,7 @@ import {
TenantScope, TenantScope,
} from '@logto/schemas'; } from '@logto/schemas';
import { conditionalArray } from '@silverhand/essentials'; import { conditionalArray } from '@silverhand/essentials';
import i18next from 'i18next';
import { useContext, useMemo } from 'react'; import { useContext, useMemo } from 'react';
import { Helmet } from 'react-helmet'; import { Helmet } from 'react-helmet';
import { createBrowserRouter, RouterProvider } from 'react-router-dom'; import { createBrowserRouter, RouterProvider } from 'react-router-dom';
@ -114,7 +115,16 @@ function Providers() {
}} }}
> >
<AppThemeProvider> <AppThemeProvider>
<Helmet titleTemplate={`%s - ${mainTitle}`} defaultTitle={mainTitle} /> <Helmet
titleTemplate={`%s - ${mainTitle}`}
defaultTitle={mainTitle}
htmlAttributes={{
// We intentionally use the imported i18next instance instead of the hook, since the
// hook will cause a re-render following some bugs here. This still works for the
// initial render, so we're good for now. Consider refactoring this in the future.
lang: i18next.language,
}}
/>
<Toast /> <Toast />
<AppConfirmModalProvider> <AppConfirmModalProvider>
<ErrorBoundary> <ErrorBoundary>

View file

@ -31,6 +31,7 @@
"@silverhand/ts-config-react": "6.0.0", "@silverhand/ts-config-react": "6.0.0",
"@types/react": "^18.3.3", "@types/react": "^18.3.3",
"@types/react-dom": "^18.3.0", "@types/react-dom": "^18.3.0",
"@types/react-helmet": "^6.1.6",
"@vitejs/plugin-react": "^4.3.1", "@vitejs/plugin-react": "^4.3.1",
"eslint": "^8.56.0", "eslint": "^8.56.0",
"i18next": "^22.4.15", "i18next": "^22.4.15",
@ -40,6 +41,7 @@
"prettier": "^3.0.0", "prettier": "^3.0.0",
"react": "^18.3.1", "react": "^18.3.1",
"react-dom": "^18.3.1", "react-dom": "^18.3.1",
"react-helmet": "^6.1.0",
"react-i18next": "^12.3.1", "react-i18next": "^12.3.1",
"stylelint": "^15.0.0", "stylelint": "^15.0.0",
"typescript": "^5.5.3", "typescript": "^5.5.3",

View file

@ -1,6 +1,8 @@
import { type IdTokenClaims, LogtoProvider, useLogto, type Prompt } from '@logto/react'; import { type IdTokenClaims, LogtoProvider, useLogto, type Prompt } from '@logto/react';
import { demoAppApplicationId } from '@logto/schemas'; import { demoAppApplicationId } from '@logto/schemas';
import i18next from 'i18next';
import { useCallback, useEffect, useState } from 'react'; import { useCallback, useEffect, useState } from 'react';
import { Helmet } from 'react-helmet';
import { useTranslation } from 'react-i18next'; import { useTranslation } from 'react-i18next';
import '@/scss/normalized.scss'; import '@/scss/normalized.scss';
@ -121,6 +123,14 @@ const Main = () => {
return ( return (
<div className={styles.app}> <div className={styles.app}>
<Helmet
htmlAttributes={{
// We intentionally use the imported i18next instance instead of the hook, since the hook
// will cause a re-render following some bugs here. This still works for the initial
// render, so we're good for now. Consider refactoring this in the future.
lang: i18next.language,
}}
/>
{showDevPanel && <DevPanel />} {showDevPanel && <DevPanel />}
<div className={[styles.card, styles.congrats].join(' ')}> <div className={[styles.card, styles.congrats].join(' ')}>
{congratsIcon && <img src={congratsIcon} alt="Congrats" />} {congratsIcon && <img src={congratsIcon} alt="Congrats" />}

View file

@ -1,4 +1,6 @@
import { MfaFactor, experience } from '@logto/schemas'; import { MfaFactor, experience } from '@logto/schemas';
import i18next from 'i18next';
import { Helmet } from 'react-helmet';
import { Route, Routes, BrowserRouter } from 'react-router-dom'; import { Route, Routes, BrowserRouter } from 'react-router-dom';
import AppLayout from './Layout/AppLayout'; import AppLayout from './Layout/AppLayout';
@ -39,7 +41,6 @@ import Springboard from './pages/Springboard';
import VerificationCode from './pages/VerificationCode'; import VerificationCode from './pages/VerificationCode';
import { UserMfaFlow } from './types'; import { UserMfaFlow } from './types';
import { handleSearchParametersData } from './utils/search-parameters'; import { handleSearchParametersData } from './utils/search-parameters';
import './scss/normalized.scss'; import './scss/normalized.scss';
handleSearchParametersData(); handleSearchParametersData();
@ -47,6 +48,14 @@ handleSearchParametersData();
const App = () => { const App = () => {
return ( return (
<BrowserRouter> <BrowserRouter>
<Helmet
htmlAttributes={{
// We intentionally use the imported i18next instance instead of the hook, since the hook
// will cause a re-render following some bugs here. This still works for the initial
// render, so we're good for now. Consider refactoring this in the future.
lang: i18next.language,
}}
/>
<PageContextProvider> <PageContextProvider>
<SettingsProvider> <SettingsProvider>
<UserInteractionContextProvider> <UserInteractionContextProvider>

View file

@ -1,7 +1,6 @@
import { Theme } from '@logto/schemas'; import { Theme } from '@logto/schemas';
import { conditionalString } from '@silverhand/essentials'; import { conditionalString } from '@silverhand/essentials';
import classNames from 'classnames'; import classNames from 'classnames';
import i18next from 'i18next';
import { useContext } from 'react'; import { useContext } from 'react';
import { Helmet } from 'react-helmet'; import { Helmet } from 'react-helmet';
@ -38,7 +37,6 @@ const AppMeta = () => {
return ( return (
<Helmet> <Helmet>
<html lang={i18next.language} data-theme={theme} />
<link rel="shortcut icon" href={favicon ?? defaultFavicon} /> <link rel="shortcut icon" href={favicon ?? defaultFavicon} />
<link rel="apple-touch-icon" href={favicon ?? defaultAppleTouchLogo} sizes="180x180" /> <link rel="apple-touch-icon" href={favicon ?? defaultAppleTouchLogo} sizes="180x180" />
{experienceSettings?.customCss && <style>{experienceSettings.customCss}</style>} {experienceSettings?.customCss && <style>{experienceSettings.customCss}</style>}

View file

@ -3213,6 +3213,9 @@ importers:
'@types/react-dom': '@types/react-dom':
specifier: ^18.3.0 specifier: ^18.3.0
version: 18.3.0 version: 18.3.0
'@types/react-helmet':
specifier: ^6.1.6
version: 6.1.6
'@vitejs/plugin-react': '@vitejs/plugin-react':
specifier: ^4.3.1 specifier: ^4.3.1
version: 4.3.1(vite@5.3.4(@types/node@20.12.7)(lightningcss@1.25.1)(sass@1.77.8)) version: 4.3.1(vite@5.3.4(@types/node@20.12.7)(lightningcss@1.25.1)(sass@1.77.8))
@ -3240,6 +3243,9 @@ importers:
react-dom: react-dom:
specifier: ^18.3.1 specifier: ^18.3.1
version: 18.3.1(react@18.3.1) version: 18.3.1(react@18.3.1)
react-helmet:
specifier: ^6.1.0
version: 6.1.0(react@18.3.1)
react-i18next: react-i18next:
specifier: ^12.3.1 specifier: ^12.3.1
version: 12.3.1(i18next@22.4.15)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) version: 12.3.1(i18next@22.4.15)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)