ログイン

Nextjs+I18n 多言語国際化のベスト プラクティス (検索エンジンに優しい)

著者:ネオヤン 時間:2024/01/13 読む: 10213
注: このベスト プラクティスは、次のページのルーティングに基づいています。アプリのルーティングには適していません。ディレクトリの基本的な考え方は next-i18next を使用します。 [locales] ディレクトリを「pages」ディレクトリに追加し、メインのビジネス ロジックをこのディレクトリに配置します。私はページディレクトリにあります[…]

注: このベスト プラクティスは、次のページのルーティングに基づいています。アプリのルーティングには適していません。

目次

基本的な考え方

next-i18next を使用します。

[locales] ディレクトリを「pages」ディレクトリに追加し、メインのビジネス ロジックをこのディレクトリに配置します。

ページ ディレクトリ内のインデックスなどのページは、言語を決定するために使用され、対応するローカライズされたページ ロジックを呼び出します。

ロケール ディレクトリを翻訳ファイルのパブリック ディレクトリに追加します。

インストール

pnpm add next-i18next 反応-i18next i18nex

構成

ファイルディレクトリ

|コンポーネント ..LangSwitcher.js ..LocLink.js ..MdRenderer.js |lib ..getStatic.js |ページ ..[ロケール] ....index.js .._app.js .._document.js .. Index.js |public ..locales ....en ...common.json ...index.md ....es ...common.json ..... .index.md |next-i18next。 config.js |next.config.js

next.config.js

const { i18n } = require('./next-i18next.config'); const nextConfig = { i18n }

next-i18next.config.js

module.exports = { 'development', i18n: {defaultLocale: 'en', // locales: [ 'en', 'de', 'es',"cn"], locales: [ { name: "English",コード: "en", iso: "en-US", dir: "ltr" }, { name: "español",code: "es", iso: "es-ES", dir: "ltr" }, {名前: "中文"、コード: "zh_cn"、iso: "zh-CN"、ディレクトリ: "ltr" }、{ 名前: "Deutsch"、コード: "de"、iso: "de-DE"、ディレクトリ: "ltr" }, { name: "Italiano",code: "it", iso: "it-IT", dir: "ltr" }, { name: "日本语",code: "ja", iso: " ja-JP", dir: "ltr" }, { name: "한국인",code: "ko", iso: "ko-KR", dir: "ltr" }, { name: "Português",code: " pt"、iso: "pt-PT"、ディレクトリ: "ltr" }, ], }, }

ロケールの構成については、ユーザーに言語選択を表示するシナリオを考慮して、インターネット上のほとんどの構成方法には従いませんでした。

lib/getStatic.js

import {serverSideTranslations } from "next-i18next/serverSideTranslations"; import i18nextConfig from "@/next-i18next.config"; import const getI18nPaths = () => i18nextConfig.i18n.locales.map((lng) => ({ params : { ロケール: lng.code,//コードを追加 }, })); エクスポート const getStaticPaths = () => ({ フォールバック: false, パス: getI18nPaths(), }); エクスポート const getI18nProps = async (ctx, ns = ["common"]) => { const locale = ctx?.params?.locale || i18nextConfig.i18n.defaultLocale; let props = { ...(await serverSideTranslations(locale, ns)), }; return props; }; エクスポート const makeStaticProps = (ns = []) => async (ctx) => ({ props: await getI18nProps(ctx, ns), });

これは、言語翻訳ファイルを取得してサーバー側で翻訳するために使用されるロジックです。

_app.js

import { appWithTranslation } from "next-i18next"; import Layout from '../components/layout' import { NextPage } from 'next'; const MyApp = ({ Component, pageProps }) => ; デフォルトの appWithTranslation(MyApp) をエクスポートします。

注: 使用しない場合は、このラベルは直接剥がすことができます。

_document.js

import i18nextConfig from &quot;@/next-i18next.config&quot;; // その他のコード import Document, { Html, Head, Main, NextScript, } from &#039;next/document&#039; class MyDocument extends Document { render() { const currentLocale = this. props.__NEXT_DATA__.query.locale || i18nextConfig.i18n.defaultLocale; console.log(currentLocale) return <html lang="{currentLocale}">
      <head>

        <link href="/app.css" />
        <link rel="shortcut icon" href="/icon.png" />
      </head>
      <body>
        <main />
        <nextscript />
      </body>


    </html>; } } デフォルトの MyDocument をエクスポート

インデックス.js

import Home, { getStaticProps } from "./[locale]/index"; デフォルトの Home をエクスポート; export { getStaticProps }; 

[ロケール]フォルダー

www.xxx.com/es と同様の国際ルーティングを実装するために使用されます。

public/locales フォルダー

翻訳ファイルを保存するために使用されます。

コンポーネント

言語セレクター: LangSwitcher.js

コード


'use client'
import React from "react";
import { useRouter } from "next/router"
import i18nextConfig from '@/next-i18next.config'
console.log(i18nextConfig.i18n.defaultLocale)
 

const LangSwitcher = ({ lang, ...rest}) => {

        const router = useRouter();

const  GetHref=(locale)=> {

    console.log(locale)

    let href = rest.href || router.asPath
    let pName = router.pathname
    Object.keys(router.query).forEach(k => {
      if (k === 'locale') {
        pName = pName.replace(`[${k}]`, locale)
        return
      }
      pName = pName.replace(`[${k}]`, router.query[k])
    })
    if (locale == i18nextConfig.i18n.defaultLocale) {

      if (pName == '/' + i18nextConfig.i18n.defaultLocale) {
        href = '/'
      } else {
        href = `${href}`

      }

    } else {
      if (locale) {
        href = rest.href ? `/${locale}${rest.href}` : pName
      }
      if (href.indexOf(`/${locale}`) < 0) {
        href = `/${locale}${href}`
      }
    }
    return href
  }

  const LocalChanged = (value) => {
    const thehref = GetHref(value)
    router.push(thehref)
  }

  

  return (

    <div>
      🌐
      <select onChange={(e) => LocalChanged(e.target.value)} defaultValue={lang} className="h-8 m-2 p-1 rounded border-current">

        <option value={lang} > {GetLangData(lang).name}</option>

        {i18nextConfig.i18n.locales.map(locale => {
          if (locale.code === lang) return null
          return (<option value={locale.code} key={locale.code}> {locale.name}</option>)
        })}

      </select>
    </div>
  )
}
 //export 

 export function GetLangData(lang) {
    var res = {}
    {
      i18nextConfig.i18n.locales.map(locale => {
        if (locale.code === lang) {
          console.log(locale)
          res = locale
        }
      })
    }
    return res

  }

export default LangSwitcher

説明書:

コンポーネントを導入して直接使用する、lang パラメータは現在の言語に設定されます。

import LangSwitcher from './LangSwitcher' const { i18n } = useTranslation('home');

ローカライズされたリンク コンポーネント: LocLink.js

import React from &quot;react&quot;; import Link from &quot;next/link&quot;; import { useRouter } from &quot;next/router&quot;; import i18nextConfig from &#039;@/next-i18next.config&#039; const LinkComponent = ({ Children, SkipLocaleHandling, .. .rest }) =&gt; { const router = useRouter(); const locale =rest.locale || router.query.locale || &quot;&quot;; console.log(router) let href =rest.href || router.asPath; console.log(href) if (href.indexOf(&quot;http&quot;) === 0) SkipLocaleHandling = true; if (locale &amp;&amp; !skipLocaleHandling) { // href = href console.log(i18nextConfig.i18n.defaultLocale) コンソール。 log(locale) locale==i18nextConfig.i18n.defaultLocale ? href : router.pathname.replace(&quot;[locale]&quot;, locale); } console.log(href) return (
    <>
      <link href="{href}" legacybehavior>
        <a {...rest}>{子供たち}</a>
      </Link>
    </>
  ); }; デフォルトの LinkComponent をエクスポートします。

ローカライズされた Markdown ファイルの取得およびレンダリング コンポーネント: MdRenderer.js

import ReactMarkdown from 'react-markdown' import { useState, useEffect } from "react"; import { useRouter } from "next/router" export デフォルト関数 MdRenderer({ path }) { const [a, setA] = useState("" ); const router = useRouter() fetch(path, { next: { revalidate: 0 } }) .then(response => response.text()) .then(data => { setA(data) } ).catch( err=>{console.log(err)}) return (
{a && ( {a} )}
) }

説明書

t関数

  • 「useTranslation」のご紹介
  • tを定義する
  • {t('xxx')} を使用するだけです
import { useTranslation } from "next-i18next"; const { t } = useTranslation(["common"]);//common.json は翻訳ファイル {t("xxx")}

現在の言語を取得する方法

import { useTranslation } from "next-i18next"; const { i18n } = useTranslation('home'); console.log(i18n. language)

言語のリストをループする方法

言語リストを取得し、言語ナビゲーションをカスタマイズします。

import i18nextConfig from '@/next-i18next.config' {i18nextConfig.i18n.locales.map(locale => { if (locale.code === i18nextConfig.i18n.defaultLocale) return( {ロケール.名前} ) const thehref="/"+locale.code return ( {ロケール.名前} ) })} 

コンテンツ段落の翻訳

コンテンツがバックエンドから取得される場合、これは必要ありません。

ただし、フロントエンドにコンテンツが存在する場合、jsonに保存するのは非常に面倒なので、マークダウンに保存しておき、コンテンツを表示したい対応言語バージョンのマークダウンファイルを取得し、それを解析して表示します。

「../../components/MdRenderer」から MdRenderer をインポートします 

要約する

多言語により、Web サイトはより多くのトラフィックを獲得できるようになります。この nextjs の多言語のベスト プラクティスでは、SEO のニーズが十分に考慮されています。検索エンジンに優しい。

ツールステーション、キーワードステーション、ニュースおよびコンテンツステーションに適しています。



著作権 © www.lyustu.com 全著作権所有。
テーマ: TheMoon V3.0 著者:neo yang