بین المللی کردن URL های NextJs با ترجمه بعدی (قسمت 1)
URL های I18n در همه مولدهای اصلی سایت های استاتیک در دسترس بوده اند، اما به نحوی در NextJ ها کمبود دارند و این قطعاً وجود دارد. حیف 😔.
من فرانسوی هستم و همیشه وب سایت هایم را حداقل به زبان فرانسوی و انگلیسی ایجاد می کنم.
در اینجا توضیح مفصلی در مورد اینکه چگونه هر توسعه دهنده ای می تواند به این امر دست یابد آورده شده است کمتر از 10 دقیقه و در نهایت قادر به مدیریت آدرس های اینترنتی مانند
TLDR
مخزن با تمام کد منبع را می توان یافت در GitHub
پیش نیازها
این آموزش از کتابخانه عالی ترجمه بعدی استفاده می کند اما می تواند برای next-i18next سازگار شود.
- داشتن ترجمه بعدی از قبل در پروژه شما
چه کاری انجام خواهد شد
- تولید می کنند
rewrites
قوانینی که باعث می شود URL ها مطابق با زبان انتخاب شده توسط کاربر سازگار شوند - سوپرشارژ کردن
nextTranslate
تابع برای استفاده از آنهاrewrites
- سفارشی بنویس
Link
جزء که از آنها استفاده خواهد کردrewrites
برای تولید راب i18n مربوطه و استفاده از آنها برای ناوبری
روش
در تمام مراحل زیر فایل ها و توابع ایجاد شده در a قرار می گیرند modules/I18n
پوشه
این روشی است که من پس از سالها برنامهنویسی به آن دست یافتم و به جدا کردن بخشهایی از برنامهها کمک زیادی میکند (در این مورد، تمام منطق مربوط به I18n).
به زودی یک پست وبلاگ در مورد آن خواهم نوشت.
پیوندهای ثابت را مشخص کنید
اولین کاری که باید انجام شود این است که پیوندهای ثابتی را که می خواهیم استفاده کنیم مشخص کنیم.
بیایید یک را ایجاد کنیم modules/I18n/permalinks.json
{
"https://dev.to/": {
"fr": "/accueil"
}
}
توجه داشته باشید: این یک راه حل ایده آل برای من نیست زیرا صفحه واقعی (فایل jsx) را از تعریف پیوندهای ثابت آن جدا می کند و بهتر است یک export const permalinks
از داخل صفحه این مشکل در قسمت 2 این مقاله بررسی شده است (و همچنین اگر اطلاعات بیشتری می خواهید می توانید با من تماس بگیرید).
سوپرشارژ nextTranslate
تابع
هدف در اینجا این است که پیوندهای ثابتی را که ایجاد کردیم به قوانین بازنویسی تبدیل کنیم تا NextJS بتواند URL را بسته به زبان به درستی بازنویسی کند.
TLDR commit را در GitHub ببینید
ایجاد یک modules/I18n/next.config.js
با
const nextTranslate = require('next-translate-plugin');
const fs = require('fs');
const permalinks = require('./permalinks.json');
/**
*
* Transforms
{
"https://dev.to/": {
"fr": "/accueil"
}
}
* into
[
{
source: '/fr/accueil',
destination: '/fr',
locale: false
}
]
*/
const permalinksToRewriteRules = (permalinks) =>
Object.entries(permalinks).reduce(
(acc, [originalSlug, permalinks]) => [
...acc,
...Object.entries(permalinks).reduce(
(acc2, [locale, i18nSlug]) => [
...acc2,
{
source: `/${locale}${i18nSlug}`,
destination: `/${locale}${originalSlug}`,
locale: false,
},
],
[]
),
],
[]
);
module.exports = (nextConfig) => {
const nextTranslateConfig = nextTranslate(nextConfig);
return {
...nextTranslateConfig,
async rewrites() {
const existingRewrites = nextTranslateConfig.rewrites
? await nextTranslateConfig.rewrites()
: [];
return [...permalinksToRewriteRules(permalinks), ...existingRewrites];
},
};
};
و فراخوانی تابع در را جایگزین کنید next.config.js
- const nextTranslate = require('next-translate-plugin')
+ const nextTranslate = require('./src/modules/I18n/next.config');
بسیار عالی، اکنون، اگر سرور خود را مجدداً بارگذاری کنید، می توانید به آن دسترسی پیدا کنید
اکنون، بیایید مؤلفه Link را برای در نظر گرفتن این URL جدید تطبیق دهیم
مولفه پیوند را تطبیق دهید
هدف این است که بتوانیم مستقیماً به URL های خوبی که قبلاً تعریف شده است حرکت کنیم.
TLDR: به commit در GitHub مراجعه کنید
یک جدید modules/I18n
جزء نامیده می شود Link
باید ایجاد شود و تمام واردات از next/link
باید اصلاح شود
بله، این واقعاً یک نقطه دردناک است، اعتراف می کنم، اما راهی برای انجام کارهای عاقلانه دیگر پیدا نکردم.
این در واقع مشکل بزرگی نیست زیرا یک «جستجو و جایگزینی» ساده کار خواهد کرد
- import Link from 'next/link';
+ import { Link } from 'modules/I18n';
اول، permalinks
متغیر باید در قسمت جلویی قرار گیرد تا توسط آن استفاده شود Link
جزء که ایجاد خواهد شد.
در nextJ ها این کار با
return {
...nextTranslateConfig,
+ publicRuntimeConfig: {
+ ...nextTranslateConfig.publicRuntimeConfig,
+ permalinks, // add it to publicRuntimeConfig so it can be used by the Link component
+ },
async rewrites() {
...
چگونه nextJS ساخته شده است Link
کامپوننت کار می کند این است که URL را از روی می سازد href
و گذشت (یا موجود) locale
.
این به معنای پیوند به /
که در fr
منجر خواهد شد /fr
این مؤلفه نقشه ای از URL ها را برای مسیریابی مستقیم به URL صحیح مربوطه ایجاد می کند /fr/accueil
import React from 'react';
import Link from 'next/link';
import { useRouter } from 'next/router';
import getConfig from 'next/config';
const { publicRuntimeConfig } = getConfig();
const permalinks: { [key: string]: { [key: string]: string } } =
publicRuntimeConfig.permalinks || {};
/**
* Formats permalinks
{
"https://dev.to/": {
"fr": "/accueil"
}
}
* into
{
"/fr/": "/fr/accueil",
"/en/accueil": "https://dev.to/"
}
*/
export const i18nFallbackUrls: { [key: string]: string } = Object.entries(
permalinks
).reduce(
(acc, [originalSlug, permalinks]) => ({
...acc,
...Object.entries(permalinks || {}).reduce(
(acc2, [locale, permalink]) => ({
...acc2,
[`/${locale}${originalSlug}`]: `/${locale}${permalink}`,
[`/en${permalink}`]: originalSlug,
}),
{}
),
}),
{}
);
const I18nLink = ({ href, locale, ...props }: any) => {
const router = useRouter();
const wantedLocale = locale || router.locale;
let i18nProps: any = {
href,
locale,
};
if (i18nFallbackUrls[`/${wantedLocale}${href}`]) {
i18nProps = {
href: i18nFallbackUrls[`/${wantedLocale}${href}`],
locale: false,
};
}
return <Link {...i18nProps} {...props} />;
};
export default I18nLink;
و voila!. همه چیز تمام شده است و در اینجا به نظر می رسد
ارجاع
Github Repo را بررسی کنید
من کی هستم؟
نام من مارتین راتینود است و من یک مهندس ارشد نرم افزار و علاقه مند به کار از راه دور هستم، به طور مسری خوشحال و کنجکاو هستم.
من وبسایتهایی مانند این را برای قرار دادن رمزارز و بسیاری موارد دیگر ایجاد میکنم…
لینکدین من را بررسی کنید و تماس بگیرید!
همچنین دنبال کار از راه دور هستم. من را استخدام کن !