Nextjs+I18n أفضل ممارسات التدويل متعدد اللغات (صديقة لمحركات البحث)
ملاحظة: تعتمد أفضل الممارسات هذه على توجيه الصفحات التالية. غير مناسب لتوجيه التطبيق.
جدول المحتويات
الفكرة الأساسية
استخدم التالي-i18next.
أضف دليل [اللغات] إلى دليل "الصفحات" ثم ضع منطق العمل الرئيسي في هذا الدليل.
يتم استخدام الصفحات مثل الفهرس الموجود في دليل الصفحات لتحديد اللغة، ثم استدعاء منطق الصفحة المترجمة المقابل.
أضف دليل اللغات إلى الدليل العام لملفات الترجمة.
ثَبَّتَ
أضف pnpm التالي-i18next رد الفعل-i18next i18nex
إعدادات
دليل الملفات
|components ..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 }
التالي-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"، الكود: "es"، iso: "es-ES"، dir: "ltr" }، { الاسم: "中文"، الكود: "zh_cn"، iso: "zh-CN"، dir: "ltr" }، { الاسم: "Deutsch"، الكود: "de"، iso: "de-DE"، dir: "ltr" }، { الاسم: "Italiano"، الكود: "it"، iso: "it-IT"، dir: "ltr" }، { الاسم: "日本语"، الكود: "ja"، iso: " ja-JP"، dir: "ltr" }، { name: "한국인"، الكود: "ko"، iso: "ko-KR"، dir: "ltr" }، { الاسم: "Português"، الكود: " pt"، iso: "pt-PT"، dir: "ltr" }, ], }, }
بالنسبة لتكوين اللغات، مع الأخذ في الاعتبار سيناريو عرض اختيار اللغة للمستخدمين، لم أتبع معظم طرق التكوين على الإنترنت.
ليب/getStatic.js
استيراد { serverSideTranslations } من "next-i18next/serverSideTranslations"؛ استيراد i18nextConfig من "@/next-i18next.config"؛ تصدير const getI18nPaths = () => i18nextConfig.i18n.locales.map((lng) => ({ params : { اللغة: lng.code,// أضف كود }, })); تصدير const getStaticPaths = () => ({ احتياطي: false, paths: getI18nPaths(), }); تصدير const getI18nProps = async (ctx, ns = ["common"]) => { const locale = ctx?.params?.locale || i18nextConfig.i18n.defaultLocale; Letprops = { ...(await serverSideTranslations(locale, ns)), }; returnprops; }; Export const makeStaticProps = (ns = []) => async (ctx) => ({props: Wait getI18nProps(ctx, ns), });
هذا هو المنطق المستخدم للحصول على ملف ترجمة اللغة وترجمته على جانب الخادم.
_app.js
استيراد { appWithTranslation } من "next-i18next"؛ استيراد التخطيط من '../components/layout' استيراد { NextPage } من 'next'؛ const MyApp = ({ Component, pageProps }) => ؛ تصدير التطبيق الافتراضيWithTranslation(MyApp);
ملحوظة: في حالة عدم الاستخدام يمكن إزالة هذه التسمية مباشرة.
_docoument.js
import i18nextConfig from "@/next-i18next.config"؛ // رمز آخر import Document, { Html, Head, Main, NextScript, } from 'next/document' class MyDocument Extends Document { render() { const currentLocale = this. الدعائم.__NEXT_DATA__.query.locale || i18nextConfig.i18n.defaultLocale; console.log(currentLocale) العودة <html lang="{currentLocale}">
<head>
<link href="/app.css" />
<link rel="shortcut icon" href="/icon.png" />
</head>
<body>
<main />
<nextscript />
</body>
</html>; } } تصدير MyDocument الافتراضي
Index.js
استيراد الصفحة الرئيسية، { getStaticProps } من "./[locale]/index"؛ تصدير الصفحة الرئيسية الافتراضية؛ تصدير { getStaticProps }؛
مجلد [اللغات]
يُستخدم لتنفيذ التوجيه الدولي المماثل لـ www.xxx.com/es
المجلد العام/اللغات
يستخدم لتخزين ملفات الترجمة.
عناصر
محدد اللغة: 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 على اللغة الحالية.
استيراد LangSwitcher من './LangSwitcher' const { i18n } = useTranslation('home');
مكون الارتباط المترجم: LocLink.js
استيراد React من "react"؛ استيراد الرابط من "next/link"؛ استيراد { useRouter } من "next/router"؛ استيراد i18nextConfig من '@/next-i18next.config' const LinkComponent = ({ children, SkipLocaleHandling, .. .rest }) => { const router = useRouter(); const locale = Rest.locale || router.query.locale || ""; console.log(router) Let href = Rest.href || router.asPath; console.log(href) if (href.indexOf("http") === 0) SkipLocaleHandling = true; if (locale && !skipLocaleHandling) { // href = href console.log(i18nextConfig.i18n.defaultLocale) console.log(href) if (href.indexOf("http") === 0) SkipLocaleHandling = true; log(locale) locale==i18nextConfig.i18n.defaultLocale ? href : router.pathname.replace("[locale]"، locale); } console.log(href) return (
<>
<link href="{href}" legacybehavior>
<a {...rest}>{أطفال}</a>
</Link>
</>
); }; تصدير LinkComponent الافتراضي؛
الحصول على ملف Markdown المترجم ومكونات العرض: MdRenderer.js
استيراد ReactMarkdown من 'react-markdown' import { useState, useEffect } من "react"؛ استيراد { useRouter } من "التالي/جهاز التوجيه" وظيفة التصدير الافتراضية MdRenderer({ path }) { const [a, setA] = useState("" ); const router = useRouter() fetch(path, { next: { revalidate: 0 } }) .then(response => Response.text()) .then(data => { setA(data) } ).catch( يخطئ=>{console.log(يخطئ)}) يعود ( {أ && ( {أ} )} ) }
تعليمات
وظيفة ر
- تقديم "استخدام الترجمة"
- تحديد ر
- استخدم {t('xxx')}، هذا كل شيء
import { useTranslation } from "next-i18next"; const { t } = useTranslation(["common"]);//common.json هو ملف الترجمة {t("xxx")}
كيفية الحصول على اللغة الحالية
استيراد { useTranslation } من "next-i18next"؛ const { i18n } = useTranslation('home'); console.log(i18n.language)
كيفية تكرار قائمة اللغات
احصل على قائمة اللغات وقم بتخصيص التنقل باللغة.
استيراد i18nextConfig من '@/next-i18next.config' {i18nextConfig.i18n.locales.map(locale => { if (locale.code === i18nextConfig.i18n.defaultLocale) return( {locale.name} ) const thehref = "/"+locale.code return ( {locale.name} ) })}
ترجمة فقرات المحتوى
إذا تم الحصول على المحتوى من الواجهة الخلفية، فلن تكون هناك حاجة لذلك.
ومع ذلك، إذا كان المحتوى موجودًا على الواجهة الأمامية، فمن الصعب جدًا تخزينه بتنسيق json، لذلك يمكن تخزينه في تخفيض السعر، ثم الحصول على ملف تخفيض السعر لإصدار اللغة المقابلة حيث يجب عرض المحتوى، و ثم تحليل وعرضه.
استيراد MdRenderer من "../../components/MdRenderer"
لخص
يتيح تعدد اللغات لموقع الويب الحصول على المزيد من الزيارات. تراعي أفضل الممارسات المتعددة اللغات في Nextjs احتياجات تحسين محركات البحث (SEO) بشكل كامل. محرك البحث ودية.
مناسبة لمحطات الأدوات ومحطات الكلمات الرئيسية ومحطات الأخبار والمحتوى.