Mudah i18n untuk next.js +10
Plugin Berikutnya + I18N API
Catatan
Kami bekerja dengan versi 3.0.0 dari translate berikutnya. Dalam beberapa bulan terakhir kami sangat fokus pada Brisa . Jadi sudah lama sejak rilis terakhir, tetapi kami belum lupa tentang translasi berikutnya. Kami sedang mengerjakan versi baru yang akan membawa banyak perbaikan dan fitur baru. Kami sangat senang membagikannya kepada Anda semua.

Tujuan utama dari perpustakaan ini adalah untuk menjaga terjemahan sesederhana mungkin di lingkungan Next.js.
Next-Translate memiliki dua bagian: plugin Next.js + i18n API .
Fitur

Di file konfigurasi, Anda menentukan setiap halaman yang dibutuhkan namespaces:
i18n.json
{
"pages" : {
"*" : [ "common" ] ,
"/" : [ "home" ] ,
"/cart" : [ "cart" ] ,
"/content/[slug]" : [ "content" ] ,
"rgx:^/account" : [ "account" ]
}
// rest of config here...
}Baca di sini tentang cara menambahkan file namespaces json.
Translate selanjutnya memastikan bahwa setiap halaman hanya memiliki ruang nama dengan bahasa saat ini. Jadi jika kita memiliki 100 lokal, hanya 1 yang akan dimuat.
Untuk melakukan ini, kami menggunakan loader webpack yang memuat file terjemahan yang diperlukan di dalam metode berikutnya.js ( getStaticProps , getServerSideprops atau getInitialprops ). Jika Anda sudah memiliki salah satu metode ini di halaman Anda, loader webpack akan menggunakan metode Anda sendiri, tetapi default yang akan digunakannya adalah:
getStaticProps . Ini adalah metode default yang digunakan pada sebagian besar halaman , kecuali jika itu adalah halaman yang ditentukan dalam dua poin berikutnya. Ini untuk kinerja, jadi perhitungannya dilakukan dalam waktu pembangunan alih -alih waktu permintaan.getServerSideProps . Ini adalah metode default untuk halaman dinamis seperti [slug].js atau [...catchall].js . Ini karena untuk halaman -halaman ini perlu untuk mendefinisikan getStaticPaths dan tidak ada pengetahuan tentang bagaimana siput seharusnya untuk setiap lokal. Demikian juga, bagaimana ini secara default, hanya saja Anda menulis GetStaticPaths maka itu sudah akan menggunakan GetStaticProps untuk memuat terjemahan.getInitialProps . Ini adalah metode default untuk halaman -halaman ini yang menggunakan hoc . Ini untuk menghindari konflik karena Hoc dapat menimpa getInitialProps . Seluruh proses ini transparan , jadi di halaman Anda, Anda dapat secara langsung mengonsumsi kait useTranslation untuk menggunakan ruang nama, dan Anda tidak perlu melakukan hal lain.
Jika karena alasan tertentu Anda menggunakan getInitialProps di file _app.js Anda, maka terjemahannya hanya akan dimuat ke getInitialProps Anda dari _app.js . Kami merekomendasikan bahwa untuk alasan optimisasi Anda tidak menggunakan pendekatan ini kecuali itu mutlak diperlukan.
yarn add next-translate next-translate-plugin adalah alat yang memungkinkan pengembang untuk menangani terjemahan secara efisien berdasarkan halaman demi halaman selama proses pembangunan. Ini berbeda dari paket next-translate , yang memungkinkan pengembang untuk mengakses terjemahan dalam kode tempat yang dibutuhkan. Plugin berfungsi dengan parsing semua halaman, mencari terjemahan dan menulis ulang file halaman menambahkan terjemahan ke dalamnya. Ini membuat plugin solusi yang lebih efisien dan fleksibel untuk menangani terjemahan dalam aplikasi Next.js. Disarankan untuk menginstal plugin sebagai ketergantungan devdependency.
yarn add next-translate-plugin -DDi file next.config.js Anda:
const nextTranslate = require ( 'next-translate-plugin' )
module . exports = nextTranslate ( ) Atau jika Anda sudah memiliki file next.config.js dan ingin menyimpan perubahan di dalamnya, berikan objek konfigurasi ke nextTranslate() . Misalnya untuk webpack Anda bisa melakukannya seperti ini:
const nextTranslate = require ( 'next-translate-plugin' )
module . exports = nextTranslate ( {
webpack : ( config , { isServer , webpack } ) => {
return config ;
}
} ) Tambahkan file konfigurasi i18n.json (atau i18n.js dengan module.exports ) di root proyek. Setiap halaman harus memiliki ruang nama. Lihatlah di bagian konfigurasi untuk lebih jelasnya.
{
"locales" : [ " en " , " ca " , " es " ],
"defaultLocale" : " en " ,
"pages" : {
"*" : [ " common " ],
"/" : [ " home " , " example " ],
"/about" : [ " about " ]
}
}Dalam file konfigurasi Anda dapat menggunakan konfigurasi yang kami tentukan di sini dan fitur sendiri tentang internasionalisasi Next.js 10.
Secara default namespaces ditentukan pada direktori root /lokal dengan cara ini:
/lokal
.
├── ca
│ ├── common.json
│ └── home.json
├── en
│ ├── common.json
│ └── home.json
└── es
├── common.json
└── home.json Setiap nama file cocok dengan namespace yang ditentukan pada Properti Konfigurasi pages , sementara setiap konten file harus serupa dengan ini:
{
"title" : " Hello world " ,
"variable-example" : " Using a variable {{count}} "
}Namun, Anda dapat menggunakan tujuan lain untuk menyimpan file namespaces Anda menggunakan properti konfigurasi LoadLocalefrom:
i18n.js
{
// ...rest of config
"loadLocaleFrom" : ( lang , ns ) =>
// You can use a dynamic import, fetch, whatever. You should
// return a Promise with the JSON file.
import ( `./myTranslationsFiles/ ${ lang } / ${ ns } .json` ) . then ( ( m ) => m . default ) ,
}Kemudian, gunakan terjemahan di halaman dan komponennya:
halaman/contoh.js
import useTranslation from 'next-translate/useTranslation'
export default function ExamplePage ( ) {
const { t , lang } = useTranslation ( 'common' )
const example = t ( 'variable-example' , { count : 42 } )
return < div > { example } </ div > // <div>Using a variable 42</div>
}Anda dapat mengkonsumsi terjemahan langsung di halaman Anda, Anda tidak perlu khawatir memuat file namespaces secara manual di setiap halaman. Plugin translate berikutnya hanya memuat ruang nama yang dibutuhkan halaman dan hanya dengan bahasa saat ini.
Dalam file konfigurasi Anda dapat menggunakan konfigurasi yang kami tentukan di sini dan fitur sendiri tentang internasionalisasi Next.js 10.
| Pilihan | Keterangan | Jenis | Bawaan |
|---|---|---|---|
defaultLocale | ISO dari lokal default ("en" sebagai default). | string | "en" |
locales | Array dengan semua bahasa untuk digunakan dalam proyek. | string[] | [] |
loadLocaleFrom | Ubah cara Anda memuat ruang nama. | function yang mengembalikan Promise dengan JSON . | Secara default memuat ruang nama dari Direktori Root Locales . |
pages | Objek yang mendefinisikan ruang nama yang digunakan di setiap halaman. Contoh objek: {"/": ["home", "example"]} . Untuk menambahkan namespaces ke semua halaman Anda harus menggunakan kunci "*" , mis: {"*": ["common"]} . Dimungkinkan juga untuk menggunakan regex menggunakan rgx: di depan: {"rgx:/form$": ["form"]} . Anda juga dapat menggunakan fungsi sebagai pengganti array, untuk menyediakan beberapa namespaces tergantung pada beberapa aturan, mis: { "/": ({ req, query }) => query.type === 'example' ? ['example'] : []} | Object<string[] or function> | {} |
logger | Fungsi untuk mencatat kunci yang hilang dalam pengembangan dan produksi. Jika Anda menggunakan i18n.json sebagai file konfigurasi, Anda harus mengubahnya menjadi i18n.js | function | Secara default, logger adalah fungsi yang melakukan console.warn Hanya dalam pengembangan. |
loggerEnvironment | String untuk menentukan apakah logger harus berjalan di browser, di node atau keduanya | "node" | "browser" | "both" | "browser" |
logBuild | Setiap halaman memiliki log yang menunjukkan: namespaces, bahasa saat ini dan metode yang digunakan untuk memuat namespaces. Dengan ini Anda bisa menonaktifkannya. | Boolean | true |
loader | Jika Anda ingin menonaktifkan loader webpack dan secara manual memuat ruang nama pada setiap halaman, kami memberi Anda kesempatan untuk melakukannya dengan menonaktifkan opsi ini. | Boolean | true |
interpolation | Ubah pembatas yang digunakan untuk interpolasi. | {prefix: string; suffix: string, formatter: function } | {prefix: '{{', suffix: '}}'} |
keySeparator | Ubah pemisah yang digunakan untuk kunci bersarang. Setel ke false untuk menonaktifkan tombol bersarang di file terjemahan JSON. Dapat bermanfaat jika Anda ingin menggunakan teks alami sebagai kunci. | string | false | '.' |
nsSeparator | Char untuk membagi namespace dari kunci. Anda harus mengaturnya menjadi false jika Anda ingin menggunakan teks alami sebagai kunci. | string | false | ':' |
defaultNS | Default namespace digunakan jika tidak diteruskan ke useTranslation atau di kunci terjemahan. | string | undefined |
staticsHoc | HOC yang kami miliki di API kami (AppWithI18N), jangan gunakan hoist-non-react-statics agar tidak memasukkan lebih banyak KB daripada yang diperlukan (nilai statis berbeda dari getInitialprops di halaman jarang digunakan) . Jika Anda memiliki konflik dengan statika, Anda dapat menambahkan hoist-non-react-statics (atau alternatif lainnya) di sini. Lihat contoh. | Function | null |
extensionsRgx | Ubah Regex yang digunakan oleh Webpack Loader untuk menemukan halaman Next.js. | Regex | /.(tsx|ts|js|mjs|jsx)$/ |
revalidate | Jika Anda ingin memiliki revalidasi default pada setiap halaman, kami memberi Anda kesempatan untuk melakukannya dengan memberikan nomor untuk merevalidasi. Anda masih dapat mendefinisikan GetStaticProps pada halaman dengan jumlah revalidate yang berbeda dan mengesampingkan override default ini. | Number | Jika Anda tidak mendefinisikannya, secara default halaman tidak akan memiliki revalidasi. |
pagesInDir | Jika Anda menjalankan next ./my-app untuk mengubah di mana halaman Anda berada, Anda dapat mendefinisikan my-app/pages sehingga translate berikutnya dapat menebak di mana mereka berada. | String | Jika Anda tidak mendefinisikannya, secara default halaman akan dicari di tempat -tempat klasik seperti pages dan src/pages . |
localesToIgnore | Tunjukkan lokal ini untuk diabaikan saat Anda diawali dengan lokal default menggunakan middleware (di Next +12, pelajari cara melakukannya) | Array<string> | ['default'] |
allowEmptyStrings | Ubah bagaimana string kosong yang diterjemahkan harus ditangani. Jika dihilangkan atau dilewatkan sebagai benar, ia mengembalikan string kosong. Jika dilewatkan sebagai false, kembalikan nama kunci itu sendiri (termasuk NS). | Boolean | true |
Ukuran : ~ 150b?
Kait ini adalah cara yang disarankan untuk menggunakan terjemahan di halaman / komponen Anda.
Contoh:
import React from 'react'
import useTranslation from 'next-translate/useTranslation'
export default function Description ( ) {
const { t , lang } = useTranslation ( 'ns1' ) // default namespace (optional)
const title = t ( 'title' )
const titleFromOtherNamespace = t ( 'ns2:title' )
const description = t `description` // also works as template string
const example = t ( 'ns2:example' , { count : 3 } ) // and with query params
const exampleDefault = t ( 'ns:example' , { count : 3 } , { default : "The count is: {{count}}." } ) // and with default translation
return (
< >
< h1 > { title } </ h1 >
< p > { description } </ p >
< p > { example } </ p >
< >
)
} Fungsi t :
i18nKey . Mirip dengan useTranslation tetapi tanpa menjadi kait. Pembantu ini hanya berfungsi di App Dir .
const { t , lang } = createTranslation ( 'ns1' ) // default namespace (optional)
const title = t ( 'title' )Ukuran : ~ 560b?
Ini adalah alternatif untuk hook useTranslation , tetapi dalam hoc untuk komponen-komponen ini yang tidak berfungsi. (Tidak disarankan, lebih baik menggunakan hook useTranslation .) .
Hoc withTranslation mengembalikan komponen dengan prop tambahan bernama i18n (objek {t: function, lang: string}).
Contoh:
import React from 'react'
import withTranslation from 'next-translate/withTranslation'
class Description extends React . Component {
render ( ) {
const { t , lang } = this . props . i18n
const description = t ( 'common:description' )
return < p > { description } </ p >
}
}
export default withTranslation ( NoFunctionalComponent ) Mirip dengan useTranslation("common") yang dapat Anda sebut dengan withTranslation dengan parameter kedua yang mendefinisikan namespace default untuk digunakan:
export default withTranslation(NoFunctionalComponent, "common")
Ukuran : ~ 1.4kb?
Kadang -kadang kita perlu melakukan beberapa terjemahan dengan HTML di dalam teks (tebal, tautan, dll), komponen Trans adalah persis apa yang Anda butuhkan untuk ini. Kami merekomendasikan untuk menggunakan komponen ini hanya dalam kasus ini, untuk kasus lain kami sangat merekomendasikan penggunaan hook useTranslation sebagai gantinya.
Contoh:
// The defined dictionary entry is like:
// "example": "<0>The number is <1>{{count}}</1></0>",
< Trans
i18nKey = "common:example"
components = { [ < Component /> , < b className = "red" /> ] }
values = { { count : 42 } }
/> Atau menggunakan components prop sebagai objek:
// The defined dictionary entry is like:
// "example": "<component>The number is <b>{{count}}</b></component>",
< Trans
i18nKey = "common:example"
components = { {
component : < Component /> ,
b : < b className = "red" /> ,
} }
values = { { count : 42 } }
defaultTrans = "<component>The number is <b>{{count}}</b></component>"
/>i18nKey - String - Kunci entri i18n (namespace: Key)components - Array | Objek - Dalam hal array, setiap indeks sesuai dengan tag yang ditentukan <0> / <1> . Dalam kasus objek, setiap kunci sesuai dengan tag yang ditentukan <example> .values - Objek - Param Queryfallback - String | String [] - Opsional. Fallback i18nkey Jika i18nkey tidak cocok.defaultTrans - String - Terjemahan default untuk kunci. Jika tombol fallback digunakan, itu akan digunakan hanya setelah melelahkan semua fallback.ns - namespace untuk digunakan saat tidak ada yang tertanam di i18nKeyreturnObjects - Boolean - Dapatkan bagian dari JSON dengan semua terjemahan. Lihat lebih banyak. Dalam kasus di mana kami memerlukan fungsionalitas komponen Trans , tetapi membutuhkan string untuk diinterpolasi, daripada output dari fungsi t(props.i18nKey) , ada juga komponen TransText , yang mengambil prop text alih -alih i18nKey .
text - String - String yang (opsional) berisi tag yang membutuhkan interpolasicomponents - Array | Objek - Ini berperilaku persis sama dengan Trans (lihat di atas). Ini sangat berguna saat memetakan output t() dengan returnObjects: true :
// The defined dictionary entry is like:
// "content-list": ["List of <link>things</link>", "with <em>tags</em>"]
const contentList = t ( 'someNamespace:content-list' , { } , { returnObjects : true } ) ;
{ contentList . map ( ( listItem : string ) => (
< TransText
text = { listItem }
components = { {
link : < a href = "some-url" /> ,
em : < em /> ,
} }
/>
) }Ukuran : ~ 1.5kb?
Komponen DynamicNamespaces berguna untuk memuat ruang nama dinamis, misalnya, dalam modal.
Contoh:
import React from 'react'
import Trans from 'next-translate/Trans'
import DynamicNamespaces from 'next-translate/DynamicNamespaces'
export default function ExampleWithDynamicNamespace ( ) {
return (
< DynamicNamespaces namespaces = { [ 'dynamic' ] } fallback = "Loading..." >
{ /* ALSO IS POSSIBLE TO USE NAMESPACES FROM THE PAGE */ }
< h1 >
< Trans i18nKey = "common:title" />
</ h1 >
{ /* USING DYNAMIC NAMESPACE */ }
< Trans i18nKey = "dynamic:example-of-dynamic-translation" />
</ DynamicNamespaces >
)
} Ingatlah bahwa ['dynamic'] namespace tidak boleh terdaftar pada konfigurasi pages :
pages: {
'/my-page' : [ 'common' ] , // only common namespace
}namespaces - String [] - Daftar namespaces dinamis untuk diunduh - Diperlukan .fallback - ReactNode - Fallback untuk ditampilkan sementara itu namespaces dimuat. - Opsional .dynamic - Function - Secara default ia menggunakan LoadLocalefrom dalam konfigurasi untuk memuat namespaces, tetapi Anda dapat menentukan tujuan lain. - Opsional .Ukuran : ~ 1.3kb?
Fungsi asinkron untuk memuat fungsi t luar / halaman. Ini bekerja di sisi server dan sisi klien.
Berbeda dengan hook yang diterjemahkan, kita dapat menggunakan di sini namespace apa pun, itu tidak harus menjadi namespace yang ditentukan dalam konfigurasi "halaman". Ini mengunduh namespace yang ditunjukkan sebagai parameter pada runtime.
Anda dapat memuat beberapa ruang nama dengan memberikan array sebagai parameter, dalam hal ini namespace default akan menjadi tinju.
Contoh di dalam getStaticProps :
import getT from 'next-translate/getT'
// ...
export async function getStaticProps ( { locale } ) {
const t = await getT ( locale , 'common' )
const title = t ( 'title' )
return { props : { title } }
}Contoh di dalam rute API:
import getT from 'next-translate/getT'
export default async function handler ( req , res ) {
const t = await getT ( req . query . __nextLocale , 'common' )
const title = t ( 'title' )
res . statusCode = 200
res . setHeader ( 'Content-Type' , 'application/json' )
res . end ( JSON . stringify ( { title } ) )
}Contoh memuat beberapa ruang nama:
import getT from 'next-translate/getT'
export default async function handler ( req , res ) {
const t = await getT ( req . query . __nextLocale , [ 'common' , 'errors' ] )
const title = t ( 'title' ) // The default namespace is the first one.
const errorMessage = t ( 'errors:app_error' ) // The default namespace is the first one.
res . statusCode = 200
res . setHeader ( 'Content-Type' , 'application/json' )
res . end ( JSON . stringify ( { title } ) )
}Ukuran : ~ 3KB?
I18nProvider adalah penyedia konteks yang digunakan secara internal oleh translate berikutnya untuk menyediakan lang saat ini dan halaman nama halaman. Jadi mungkin Anda tidak akan pernah membutuhkan ini .
Namun, itu terpapar API karena dapat berguna dalam beberapa kasus. Misalnya, untuk menggunakan terjemahan multi-bahasa dalam satu halaman.
I18nProvider mengumpulkan ruang nama, sehingga Anda dapat mengganti nama yang baru untuk menjaga yang lama.
import React from 'react'
import I18nProvider from 'next-translate/I18nProvider'
import useTranslation from 'next-translate/useTranslation'
// Import English common.json
import commonEN from '../../locales/en/common.json'
function PageContent ( ) {
const { t , lang } = useTranslation ( )
console . log ( lang ) // -> current language
return (
< div >
< p > { t ( 'common:example' ) /* Current language */ } </ p >
< p > { t ( 'commonEN:example' ) /* Force English */ } </ p >
</ div >
)
}
export default function Page ( ) {
const { lang } = useTranslation ( )
return (
< I18nProvider lang = { lang } namespaces = { { commonEN } } >
< PageContent />
</ I18nProvider >
)
}Ukuran : ~ 3.7kb?
appWithI18n digunakan secara internal oleh translate berikutnya. Jadi mungkin Anda tidak akan pernah membutuhkan ini . Namun, kami mengeksposnya di API jika Anda menonaktifkan opsi loader webpack dan memutuskan untuk memuat ruang nama secara manual.
Jika Anda tidak ingin menggunakan Webpack Loader, maka Anda harus memasukkannya ke dalam file _app.js Anda (dan membuat file _app.js jika Anda tidak memilikinya).
Contoh:
_app.js
import appWithI18n from 'next-translate/appWithI18n'
import i18nConfig from '../i18n'
function MyApp ( { Component , pageProps } ) {
return < Component { ... pageProps } />
}
// Wrapping your _app.js
export default appWithI18n ( MyApp , {
... i18nConfig ,
// Set to false if you want to load all the namespaces on _app.js getInitialProps
skipInitialProps : true ,
} ) Jika skipInitialProps=true , maka Anda juga harus menggunakan helper loadnamespaces untuk memuat ruang nama secara manual pada setiap halaman.
Ukuran : ~ 1.9kb?
loadNamespaces digunakan secara internal oleh translate berikutnya. Jadi mungkin Anda tidak akan pernah membutuhkan ini . Namun, kami mengeksposnya di API jika Anda menonaktifkan opsi loader webpack dan memutuskan untuk memuat ruang nama secara manual.
Untuk memuat ruang nama, Anda harus kembali di halaman Anda, alat peraga yang disediakan oleh penolong.
import loadNamespaces from 'next-translate/loadNamespaces'
export function getStaticProps ( { locale } ) {
return {
props : {
... ( await loadNamespaces ( { locale , pathname : '/about' } ) ) ,
}
}
} Untuk bekerja dengan baik, perlu bahwa _app.js Anda akan dibungkus dengan AppWithI18n. Juga, properti konfigurasi loadLocaleFrom wajib untuk mendefinisikannya.
Kami mendukung 6 bentuk jamak (diambil dari halaman plural cldr) dengan menambahkan ke kunci akhiran ini (atau bersarang di bawah kunci tanpa _ awalan):
_zero_one (tunggal)_two (ganda)_few (paucal)_many (juga digunakan untuk pecahan jika mereka memiliki kelas terpisah)_other (wajib - bentuk jamak umum - juga digunakan jika bahasa hanya memiliki satu bentuk)Lihat info lebih lanjut tentang bentuk jamak di sini .
Hanya yang terakhir, _other , diperlukan karena itu satu -satunya bentuk jamak umum yang digunakan di semua lokal.
Semua bentuk jamak lainnya tergantung pada lokal. Misalnya bahasa Inggris hanya memiliki dua: _one dan _other (1 kucing vs 2 kucing). Beberapa bahasa memiliki lebih banyak, seperti Rusia dan Arab.
Selain itu, kami juga mendukung kecocokan yang tepat dengan menentukan angka ( _0 , _999 ) dan ini berfungsi untuk semua lokal. Inilah contohnya:
Kode:
// **Note**: Only works if the name of the variable is {{count}}.
t ( 'cart-message' , { count } )Namespace:
{
"cart-message_0" : "The cart is empty" , // when count === 0
"cart-message_one" : "The cart has only {{count}} product" , // singular
"cart-message_other" : "The cart has {{count}} products" , // plural
"cart-message_999" : "The cart is full" , // when count === 999
}atau
{
"cart-message" : {
"0" : "The cart is empty" , // when count === 0
"one" : "The cart has only {{count}} product" , // singular
"other" : "The cart has {{count}} products" , // plural
"999" : "The cart is full" , // when count === 999
}
}Intl.pluralrules API hanya tersedia untuk browser modern , jika Anda ingin menggunakannya di browser lama, Anda harus menambahkan polyfill.
Anda dapat mendefinisikan HTML di dalam terjemahan dengan cara ini:
{
"example-with-html" : " <0>This is an example <1>using HTML</1> inside the translation</0> "
}Contoh:
import Trans from 'next-translate/Trans'
// ...
const Component = ( props ) => < p { ... props } />
// ...
< Trans
i18nKey = "namespace:example-with-html"
components = { [ < Component /> , < b className = "red" /> ] }
/ >Hasil yang diberikan:
< p > This is an example < b class =" red " > using HTML </ b > inside the translation </ p > Setiap indeks components array sesuai dengan <index></index> dari definisi.
Dalam array components , tidak perlu melewati anak -anak dari setiap elemen. Anak -anak akan dihitung.
Di namespace, dimungkinkan untuk mendefinisikan kunci bersarang seperti ini:
{
"nested-example" : {
"very-nested" : {
"nested" : " Nested example! "
}
}
}Untuk menggunakannya, Anda harus menggunakan "." Sebagai pemisah ID:
t `namespace:nested-example.very-nested.nested`Juga dimungkinkan untuk digunakan sebagai array:
{
"array-example" : [
{ "example" : " Example {{count}} " },
{ "another-example" : " Another example {{count}} " }
]
} Dan dapatkan semua terjemahan array dengan opsi returnObjects :
t ( 'namespace:array-example' , { count : 1 } , { returnObjects : true } )
/*
[
{ "example": "Example 1" },
{ "another-example": "Another example 1" }
]
*/ Juga dimungkinkan untuk mendapatkan semua terjemahan dengan menggunakan Keyseparator sebagai kunci, default adalah '.' :
t ( 'namespace:.' , { count : 1 } , { returnObjects : true } )
/*
{
"array-example": [
{ "example": "Example 1" },
{ "another-example": "Another example 1" }
]
}
*/ Jika tidak ada terjemahan, Anda dapat mendefinisikan Fallbacks ( string|string[] ) untuk mencari terjemahan lainnya:
const { t } = useTranslation ( )
const textOrFallback = t (
'ns:text' ,
{ count : 1 } ,
{
fallback : 'ns:fallback' ,
}
)Daftar Fallbacks:
const { t } = useTranslation ( )
const textOrFallback = t (
'ns:text' ,
{ count : 42 } ,
{
fallback : [ 'ns:fallback1' , 'ns:fallback2' ] ,
}
)Dalam komponen trans:
< Trans
i18nKey = "ns:example"
components = { [ < Component /> , < b className = "red" /> ] }
values = { { count : 42 } }
fallback = { [ 'ns:fallback1' , 'ns:fallback2' ] } // or string with just 1 fallback
/> Anda dapat memformat params menggunakan fungsi konfigurasi interpolation.format .
di i18n.js :
const formatters = {
es : new Intl . NumberFormat ( "es-ES" ) ,
en : new Intl . NumberFormat ( "en-EN" ) ,
}
return {
// ...
interpolation : {
format : ( value , format , lang ) => {
if ( format === 'number' ) return formatters [ lang ] . format ( value )
return value
}
}
}Dalam namespace bahasa Inggris:
{
"example" : " The number is {{count, number}} "
}Dalam namespace Spanyol:
{
"example" : " El número es {{count, number}} "
}Menggunakan:
t ( 'example' , { count : 33.5 } )Kembali:
The number is 33.5El número es 33,5 Untuk mengubah bahasa saat ini, Anda dapat menggunakan navigasi selanjutnya.js (tautan dan router) melewati prop locale .
Contoh komponen ChangeLanguage yang mungkin menggunakan kait useRouter dari Next.js :
import React from 'react'
import Link from 'next/link'
import useTranslation from 'next-translate/useTranslation'
import i18nConfig from '../i18n.json'
const { locales } = i18nConfig
export default function ChangeLanguage ( ) {
const { t , lang } = useTranslation ( )
return locales . map ( ( lng ) => {
if ( lng === lang ) return null
return (
< Link href = "/" locale = { lng } key = { lng } >
{ t ( `layout:language-name- ${ lng } ` ) }
</ Link >
)
} )
} Anda juga dapat menggunakan setLanguage untuk mengubah bahasa sambil menjaga halaman yang sama.
import React from 'react'
import setLanguage from 'next-translate/setLanguage'
export default function ChangeLanguage ( ) {
return (
< button onClick = { async ( ) => await setLanguage ( 'en' ) } > EN </ button >
)
} Cara lain untuk mengakses daftar locales untuk mengubah bahasa adalah menggunakan Next.js router . Daftar locales dapat diakses menggunakan hook userouter next.js.
Anda dapat mengatur cookie bernama NEXT_LOCALE dengan bahasa yang ditentukan pengguna sebagai nilai, dengan cara ini lokal dapat dipaksakan.
Contoh Hook:
import { useRouter } from 'next/router'
// ...
function usePersistLocaleCookie ( ) {
const { locale , defaultLocale } = useRouter ( )
useEffect ( persistLocaleCookie , [ locale , defaultLocale ] )
function persistLocaleCookie ( ) {
if ( locale !== defaultLocale ) {
const date = new Date ( )
const expireMs = 100 * 24 * 60 * 60 * 1000 // 100 days
date . setTime ( date . getTime ( ) + expireMs )
document . cookie = `NEXT_LOCALE= ${ locale } ;expires= ${ date . toUTCString ( ) } ;path=/`
}
}
} Dalam beberapa kasus, ketika halaman berada dalam bahasa saat ini, Anda mungkin ingin melakukan beberapa pengecualian yang menampilkan beberapa teks dalam bahasa lain.
Dalam hal ini, Anda dapat mencapai ini dengan menggunakan I18nProvider .
Pelajari cara melakukannya di sini.
Next-Translate Penggunaan Secara default Direktori kerja saat ini dari proses Node.js ( process.cwd() ).
Jika Anda ingin mengubahnya, Anda dapat menggunakan:
NEXT_TRANSLATE_PATH . Itu mendukung jalur relatif dan absolutprocess.chdir(PATH_TO_NEXT_TRANSLATE) untuk memindahkan process.cwd() Ketika datang ke komponen server dan komponen klien, bisa menjadi tantangan untuk memuat hal yang sama pada halaman yang berbeda. Untuk menyederhanakan proses ini, kami telah mengekstraksi semua kompleksitas menggunakan next-translate-plugin .
Jika Anda tertarik untuk mempelajari lebih lanjut tentang bagaimana Translate berikutnya bekerja dengan paradigma Dir App. JS 13 yang baru, lihat artikel ini untuk penjelasan terperinci.
Jika Anda menggunakan folder "aplikasi" alih-alih folder "halaman", next-translate-plugin akan secara otomatis mendeteksi perubahan, dan Anda tidak perlu menyentuh konfigurasi translasi berikutnya. Satu -satunya perbedaan adalah bahwa properti konfigurasi "halaman" akan merujuk halaman yang terletak di dalam folder "aplikasi".
i18n.js
module . exports = {
locales : [ 'en' , 'ca' , 'es' ] ,
defaultLocale : 'en' ,
pages : {
'*' : [ 'common' ] ,
'/' : [ 'home' ] , // app/page.tsx
'/second-page' : [ 'home' ] , // app/second-page/page.tsx
} ,
} Dengan hanya mengubah folder "halaman" menjadi "aplikasi," Anda dapat mengkonsumsi terjemahan di dalam halaman Anda menggunakan hook useTranslation atau komponen Trans . Anda masih akan melihat log (jika diaktifkan) untuk mengetahui ruang nama mana yang dimuat pada setiap halaman, dan yang lainnya harus sama.
? Halaman/Komponen Server (+0KB): app/page.js :
import useTranslation from 'next-translate/useTranslation'
export default function HomePage ( ) {
const { t , lang } = useTranslation ( 'home' )
return < h1 > { t ( 'title' ) } </ h1 >
} ? ️ halaman/komponen klien (+498b): app/checkout/page.js
"use client"
import useTranslation from 'next-translate/useTranslation'
export default function CheckoutPage ( ) {
const { t , lang } = useTranslation ( 'checkout' )
return < h1 > { t ( 'title' ) } </ h1 >
} Next.js 10 memperkenalkan dukungan perutean I18N, memungkinkan halaman diterjemahkan dengan menavigasi ke /es/page-name , di mana pages/page-name.js diakses menggunakan kait useRouter untuk mendapatkan locale .
Namun, karena halaman -halaman telah dipindahkan dari pages Dir ke App Dir , perutean I18N ini tidak lagi berfungsi dengan benar .
Di Translate berikutnya, kami telah memilih untuk tidak mengimplementasikan kembali fungsi ini, karena kami bertujuan untuk menjadi perpustakaan untuk menerjemahkan halaman, daripada merutekannya. Kami berharap bahwa di masa depan, fitur ini akan diimplementasikan di direktori app .
Kami merekomendasikan yang berikut:
[lang] ke tingkat pertama. Artinya, semua halaman Anda akan ada di dalam /app/[lang] .i18n.(js|json) untuk berisi /[lang] di awal. module.exports = {
locales: ['en', 'ca', 'es'],
defaultLocale: 'en',
pages: {
'*': ['common'],
- '/': ['home'],
+ '/[lang]': ['home'],
- '/second-page': ['home'],
+ '/[lang]/second-page': ['home'],
},
} Pada level translate berikutnya kami sudah mendeteksi bahasa secara otomatis menurut searchParams.get('lang') dan params.lang . Jadi, Anda tidak perlu mengonfigurasinya untuk setiap halaman , Anda dapat menggunakan next-translate seperti biasa di dalam halaman/komponen server/klien:
import useTranslation from 'next-translate/useTranslation'
import Trans from 'next-translate/Trans'
export default function Page ( ) {
const { t , lang } = useTranslation ( 'common' )
return (
< >
< h1 > { t `title` } </ h1 >
< Trans i18nKey = "common:another-text" components = { [ < b /> ] } />
</ >
)
} Ada demo next-translate di repo berikutnya.js:
Untuk menggunakannya:
npx create-next-app --example with-next-translate with-next-translate-app
# or
yarn create next-app --example with-next-translate with-next-translate-appDemo ini ada di repositori ini:
git clone [email protected]:aralroca/next-translate.gitcd next-translateyarn && yarn example:basicMirip dengan demo dasar tetapi dengan beberapa tambahan: TypeScript, Webpack 5, MDX, dengan _App.js di atas, halaman yang terletak di folder SRC/halaman, memuat lokal dari SRC/terjemahan dengan struktur yang berbeda.
Demo ini ada di repositori ini:
git clone [email protected]:aralroca/next-translate.gitcd next-translateyarn && yarn example:complex Mirip dengan demo kompleks tetapi dengan beberapa folder ekstra: alih -alih pages , kami menggunakan folder aplikasi Next.js +13 dengan sistem tata letak baru.
Demo ini ada di repositori ini:
git clone [email protected]:aralroca/next-translate.gitcd next-translateyarn && yarn example:with-app-directoryMirip dengan contoh dasar tetapi memuat halaman nama halaman secara manual menonaktifkan loader webpack di file konfigurasi i18n.json.
Kami tidak merekomendasikan bahwa itu digunakan dengan cara ini. Namun kami memberikan kesempatan bagi siapa pun untuk melakukannya jika mereka tidak nyaman dengan loader webpack kami.
Demo ini ada di repositori ini:
git clone [email protected]:aralroca/next-translate.gitcd next-translateyarn && yarn example:without-loader Terima kasih kepada orang -orang yang luar biasa ini (Kunci Emoji):
Aral Roca Gomez ? | Vincent Ducorps | Björn rave | Justin | Pol ? | Ademílson F. Tonato | Faul |
Bickmaev5 | Pierre Grimaud | Roman Minchyn | Egor | Darren | Giovanni Giordano | Eugene |
Andrew Chung | Thanh Minh | Crouton | Patrick | Vantroy | Joey | Gurkerl83 |
Teemu Perämäki | Luis Serrano | J-Schumann | Andre Hsu | Slevy85 | Bernd Artmüller | Rihards Ščeredins |
n4n5 | Rubén Moya | Tom Esterez | Dan Needham | Bruno Antunes | Kaan Atakan | Romain |
Arnau Jiménez | Edwin Veldhuizen | Duc Ngo Viet | Billel Helali | Wuif | Michał Bar | Wuif |
Marces Engel | Michał Bar | Dragate | Marces Engel | Vasco Silva | Vsevolod Volkov | Felix Yan |
Muhammad Al Ziqri | Marcelo Oliveira | Zack Sunderland | Oven Andrew | Dani | Mateusz Lesiak | Curetix |
Honza ? | Hardikbandhiya | Tim O. Peters | Li Ming | Fernando García Hernández | Hichem Fantar | Huseyin Onal |
Jesse Martin |
Proyek ini mengikuti spesifikasi semua-kontributor. Kontribusi apa pun yang baik!