Просмотр исходного кода

Fix lang attribute in Html element to correctly reflect locale

maeshinshin 1 год назад
Родитель
Сommit
130bd54c68
2 измененных файлов с 32 добавлено и 8 удалено
  1. 21 2
      apps/app/src/pages/_document.page.tsx
  2. 11 6
      apps/app/src/pages/utils/commons.ts

+ 21 - 2
apps/app/src/pages/_document.page.tsx

@@ -1,6 +1,7 @@
 /* eslint-disable @next/next/google-font-display */
 import React from 'react';
 
+import { Lang } from '@growi/core';
 import type { DocumentContext, DocumentInitialProps } from 'next/document';
 import Document, {
   Html, Head, Main, NextScript,
@@ -8,8 +9,12 @@ import Document, {
 
 import type { GrowiPluginResourceEntries } from '~/features/growi-plugin/server/services';
 import type { CrowiRequest } from '~/interfaces/crowi-request';
+import { configManager } from '~/server/service/config-manager';
+import { detectLocaleFromBrowserAcceptLanguage } from '~/server/util/locale-utils';
 import loggerFactory from '~/utils/logger';
 
+import { getLocateAtServerSide } from './utils/commons';
+
 const logger = loggerFactory('growi:page:_document');
 
 type HeadersForGrowiPluginProps = {
@@ -41,14 +46,24 @@ interface GrowiDocumentProps {
   customCss: string | null,
   customNoscript: string | null,
   pluginResourceEntries: GrowiPluginResourceEntries;
+  locale: string;
 }
 declare type GrowiDocumentInitialProps = DocumentInitialProps & GrowiDocumentProps;
 
 class GrowiDocument extends Document<GrowiDocumentInitialProps> {
 
   static override async getInitialProps(ctx: DocumentContext): Promise<GrowiDocumentInitialProps> {
+
+    const langMap = {
+      [Lang.ja_JP]: 'ja-jp',
+      [Lang.en_US]: 'en-us',
+      [Lang.zh_CN]: 'zh-cn',
+      [Lang.fr_FR]: 'fr-fr',
+    } as const;
+
     const initialProps: DocumentInitialProps = await Document.getInitialProps(ctx);
-    const { crowi } = ctx.req as CrowiRequest;
+    const req = ctx.req as CrowiRequest;
+    const { crowi } = req;
     const { customizeService } = crowi;
 
     const { themeHref } = customizeService;
@@ -60,6 +75,8 @@ class GrowiDocument extends Document<GrowiDocumentInitialProps> {
     const growiPluginService = await import('~/features/growi-plugin/server/services').then(mod => mod.growiPluginService);
     const pluginResourceEntries = await growiPluginService.retrieveAllPluginResourceEntries();
 
+    const locale = langMap[getLocateAtServerSide(req)];
+
     return {
       ...initialProps,
       themeHref,
@@ -67,6 +84,7 @@ class GrowiDocument extends Document<GrowiDocumentInitialProps> {
       customCss,
       customNoscript,
       pluginResourceEntries,
+      locale,
     };
   }
 
@@ -95,10 +113,11 @@ class GrowiDocument extends Document<GrowiDocumentInitialProps> {
     const {
       customCss, customScript, customNoscript,
       themeHref, pluginResourceEntries,
+      locale,
     } = this.props;
 
     return (
-      <Html>
+      <Html lang={locale}>
         <Head>
           {this.renderCustomScript(customScript)}
           <link rel="stylesheet" key="link-theme" href={themeHref} />

+ 11 - 6
apps/app/src/pages/utils/commons.ts

@@ -106,6 +106,15 @@ export const getServerSideCommonProps: GetServerSideProps<CommonProps> = async(c
   return { props };
 };
 
+
+export const getLocateAtServerSide = (req: CrowiRequest): Lang => {
+  const { user, headers } = req;
+  const { configManager } = req.crowi;
+
+  return user == null ? detectLocaleFromBrowserAcceptLanguage(headers)
+    : (user.lang ?? configManager.getConfig('crowi', 'app:globalLang') as Lang ?? Lang.en_US);
+};
+
 export const getNextI18NextConfig = async(
     // 'serverSideTranslations' method should be given from Next.js Page
     //  because importing it in this file causes https://github.com/isaachinman/next-i18next/issues/1545
@@ -115,13 +124,9 @@ export const getNextI18NextConfig = async(
     context: GetServerSidePropsContext, namespacesRequired?: string[] | undefined, preloadAllLang = false,
 ): Promise<SSRConfig> => {
 
-  const req: CrowiRequest = context.req as CrowiRequest;
-  const { crowi, user, headers } = req;
-  const { configManager } = crowi;
-
   // determine language
-  const locale = user == null ? detectLocaleFromBrowserAcceptLanguage(headers)
-    : (user.lang ?? configManager.getConfig('crowi', 'app:globalLang') as Lang ?? Lang.en_US);
+  const req: CrowiRequest = context.req as CrowiRequest;
+  const locale = getLocateAtServerSide(req);
 
   const namespaces = ['commons'];
   if (namespacesRequired != null) {