Hogyan építsünk többnyelvű weboldalt Next.js-szel

A mai digitális világban egyre fontosabbá válik, hogy weboldalunk ne csak egy nyelven érje el a közönséget. Egy többnyelvű weboldal megnyitja a kapukat a globális piac felé, javítja a felhasználói élményt, és jelentősen növeli a keresőmotorokban való láthatóságot. Ha Next.js-szel fejlesztesz, szerencséd van! A Next.js kiváló támogatást nyújt a nemzetköziesítéshez (i18n), lehetővé téve, hogy könnyedén építs ki egy olyan platformot, amely különböző nyelveken is zökkenőmentesen működik.

Ebben az átfogó cikkben lépésről lépésre bemutatjuk, hogyan hozhatsz létre egy Next.js többnyelvű weboldalt, a kezdeti beállításoktól egészen a SEO optimalizálásig. Célunk, hogy egy részletes útmutatót adjunk a kezedbe, amely segít kihasználni a Next.js erejét és a globális közönség elérését.

Miért érdemes többnyelvű weboldalt építeni Next.js-szel?

Mielőtt belemerülnénk a technikai részletekbe, nézzük meg, miért is olyan értékes befektetés egy többnyelvű weboldal, és miért ideális választás ehhez a Next.js:

  • Szélesebb közönség elérése: Ha weboldalad több nyelven is elérhető, sokkal több ember számára válik hozzáférhetővé, függetlenül attól, hogy hol élnek vagy milyen nyelvet beszélnek. Ez kritikus a nemzetközi cégek és a globális elérést célzó projektek számára.
  • Javított felhasználói élmény (UX): Az emberek sokkal szívesebben böngésznek és vásárolnak egy olyan weboldalon, amely az anyanyelvükön kommunikál velük. Ez bizalmat épít és növeli az elkötelezettséget.
  • SEO előnyök: A keresőmotorok, mint a Google, értékelik a lokalizált tartalmat. A helyesen beállított i18n és a hreflang attribútumok segítségével weboldalad magasabban rangsorolhat a különböző országok keresési eredményei között.
  • Next.js erősségei: A Next.js beépített támogatást nyújt az i18n útválasztáshoz, ami nagymértékben leegyszerűsíti a folyamatot. A szerveroldali renderelés (SSR) és a statikus oldalgenerálás (SSG) biztosítja a gyors betöltődési időt és a kiváló SEO-t, még komplex, többnyelvű oldalak esetén is.

Alapvető fogalmak: i18n és lokalizáció (l10n)

Fontos megérteni a két kulcsfogalom közötti különbséget:

  • Nemzetköziesítés (i18n): Ez az a folyamat, amikor egy alkalmazást úgy tervezünk és fejlesztünk, hogy az képes legyen különböző nyelvekhez és régiókhoz alkalmazkodni anélkül, hogy a kódján változtatni kellene. Ez magában foglalja a szövegek elválasztását a kódtól, a dátumok, pénznemek és egyéb kulturális elemek kezelésének előkészítését.
  • Lokalizáció (l10n): Ez a nemzetköziesített alkalmazás adaptálása egy adott régióhoz vagy nyelvhez. Ez magában foglalja a szövegek lefordítását, a dátum- és időformátumok, pénznemek, mértékegységek és más kulturális elemek helyi standardokhoz igazítását.

A Next.js és az ehhez használt könyvtárak az i18n alapjait biztosítják, míg a tényleges fordítások elkészítése a lokalizáció részét képezi.

Next.js i18n beállítása: A kezdetek

A Next.js 10-es verziója óta beépített támogatást nyújt a nemzetköziesítéshez, ami jelentősen megkönnyíti a munkát. Nézzük meg, hogyan konfigurálhatjuk:

1. next.config.js konfiguráció

A next.config.js fájlban kell megadnunk a támogatott nyelveket (locale-okat) és az alapértelmezett nyelvet. Ez a fájl az alkalmazás gyökerében található.


// next.config.js
module.exports = {
  i18n: {
    locales: ['en', 'hu', 'de'], // Támogatott nyelvek
    defaultLocale: 'hu',       // Alapértelmezett nyelv
    localeDetection: false,    // Kikapcsolható, ha nem szeretnénk, hogy a böngésző nyelve alapján detektálja
  },
  // További Next.js konfigurációk...
};

A locales tömb tartalmazza az összes támogatott nyelv kódját (pl. ‘en’ az angol, ‘hu’ a magyar, ‘de’ a német). A defaultLocale azt a nyelvet adja meg, amelyet akkor használunk, ha a felhasználó nem ad meg nyelvet, vagy a nyelvdetektálás nem vezet eredményre.

A localeDetection beállítás alapértelmezetten true. Ha engedélyezve van, a Next.js megpróbálja detektálni a felhasználó preferred locale-ját a Accept-Language fejléc alapján, és átirányítja őket a megfelelő nyelvi útvonalra. Ezt érdemes lehet kikapcsolni, ha teljes kontrollt szeretnénk a nyelválasztás felett, és egy explicit nyelvvválasztó komponensre támaszkodunk.

2. Fordítási könyvtárak telepítése

Bár a Next.js kezeli az útválasztást, a tényleges szövegfordítások kezeléséhez szükségünk lesz egy külső könyvtárra. A next-i18next az egyik legnépszerűbb választás, mivel zökkenőmentesen integrálódik a Next.js-szel és a React ökoszisztémában elterjedt react-i18next könyvtárra épül.


npm install next-i18next react-i18next i18next
# vagy
yarn add next-i18next react-i18next i18next

3. Fordítási fájlok struktúrája

A fordítási fájlokat célszerű a public/locales/[locale]/[namespace].json formátumban tárolni. A namespace (névtér) segít a fordítások logikai csoportosításában (pl. ‘common’ az általános szövegeknek, ‘home’ a kezdőlap specifikus szövegeknek).


// public/locales/hu/common.json
{
  "greeting": "Szia, üdvözöllek!",
  "description": "Ez egy példa többnyelvű Next.js weboldal."
}

// public/locales/en/common.json
{
  "greeting": "Hello, welcome!",
  "description": "This is an example multilingual Next.js website."
}

4. next-i18next konfiguráció

Hozd létre a next-i18next.config.js fájlt az alkalmazás gyökerében (ugyanoda, ahová a next.config.js).


// next-i18next.config.js
module.exports = {
  i18n: {
    defaultLocale: 'hu',
    locales: ['en', 'hu', 'de'],
  },
  // Fordítási fájlok elérési útja
  localePath: typeof window === 'undefined' ?
    require('path').resolve('./public/locales') :
    '/locales',
};

Fontos, hogy itt is megegyezzenek a locales és defaultLocale beállítások a next.config.js fájlban lévőkkel.

5. Integrálás az _app.js-be

Az _app.js fájlban kell inicializálni a next-i18next könyvtárat, hogy az összes komponens hozzáférjen a fordításokhoz.


// pages/_app.js
import '../styles/globals.css';
import { appWithTranslation } from 'next-i18next';
import nextI18nConfig from '../next-i18next.config'; // Importáld a konfigurációt

function MyApp({ Component, pageProps }) {
  return <Component {...pageProps} />;
}

export default appWithTranslation(MyApp, nextI18nConfig);

Fordítások használata komponensekben

Most, hogy beállítottunk mindent, nézzük meg, hogyan használhatjuk a fordításokat a Next.js komponenseinkben.

1. Fordítások betöltése szerveroldalon (SSR/SSG)

Ahhoz, hogy a fordítások elérhetőek legyenek a szerveroldalon generált oldalakon (ami kritikus a SEO optimalizálás szempontjából), a getServerSideProps vagy getStaticProps függvényeket kell használnunk a serverSideTranslations segédfüggvénnyel a next-i18next könyvtárból.


// pages/index.js
import { useTranslation } from 'next-i18next';
import { serverSideTranslations } from 'next-i18next/serverSideTranslations';

export default function Home() {
  const { t } = useTranslation('common'); // A 'common' névtér használata

  return (
    <div>
      <h1>{t('greeting')}</h1>
      <p>{t('description')}</p>
    </div>
  );
}

export async function getStaticProps({ locale }) {
  return {
    props: {
      ...(await serverSideTranslations(locale, ['common'])), // Betölti a 'common' névtér fordításait
      // További propok, ha szükséges
    },
  };
}

A serverSideTranslations(locale, ['common']) függvény betölti a megadott locale-hoz tartozó ‘common’ névtér fordításait, és átadja azokat a komponensnek _nextI18Next propként, amelyet az appWithTranslation automatikusan kezel.

2. Fordítások használata kliensoldalon

Miután a fordítások betöltődtek a propokba, a useTranslation hook segítségével bármelyik komponensben hozzáférhetünk hozzájuk.


// components/MyComponent.js
import { useTranslation } from 'next-i18next';

function MyComponent() {
  const { t } = useTranslation('common'); // Specifikus névtér megadása

  return <p>{t('anotherKeyInCommon')}</p>;
}
export default MyComponent;

A t függvény egy kulcsot vár paraméterként, és visszaadja a hozzá tartozó fordított szöveget. Lehetőséget biztosít változók beillesztésére, számok és dátumok formázására is.

Nyelvváltó komponens létrehozása

A felhasználók számára elengedhetetlen, hogy könnyen válthassanak a nyelvek között. Ezt egy egyszerű nyelvválasztó komponenssel oldhatjuk meg.


// components/LanguageSwitcher.js
import { useRouter } from 'next/router';

function LanguageSwitcher() {
  const router = useRouter();
  const { locales, locale: activeLocale } = router;

  const handleLocaleChange = (e) => {
    const newLocale = e.target.value;
    router.push(router.asPath, router.asPath, { locale: newLocale });
  };

  return (
    <select onChange={handleLocaleChange} value={activeLocale}>
      {locales.map((locale) => (
        <option key={locale} value={locale}>
          {locale === 'en' ? 'English' : locale === 'hu' ? 'Magyar' : 'Deutsch'}
        </option>
      ))}
    </select>
  );
}

export default LanguageSwitcher;

Ez a komponens a Next.js useRouter hookját használja, hogy hozzáférjen az elérhető nyelvekhez (locales) és az aktuálisan aktív nyelvhez (locale). Amikor a felhasználó kiválaszt egy új nyelvet, a router.push függvény segítségével frissítjük az URL-t, átadva az új locale paramétert. A Next.js automatikusan frissíti az oldalt a kiválasztott nyelvvel.

SEO optimalizálás többnyelvű oldalakhoz

A SEO optimalizálás létfontosságú, ha azt szeretnénk, hogy a különböző nyelvi verzióinkat megtalálják a keresőmotorok. Íme a legfontosabb szempontok:

1. hreflang attribútumok

Ez az egyik legfontosabb elem a többnyelvű SEO-ban. A hreflang attribútumok jelzik a keresőmotoroknak, hogy egy adott oldalnak van más nyelven vagy más régióban célzott változata. Ezzel elkerülhető a duplikált tartalom miatti büntetés, és a felhasználók a számukra legrelevánsabb nyelvi verzióra irányítódnak.

A next-i18next és a Next.js router kombinációjával viszonylag könnyen generálhatók ezek. A _document.js fájlban tudjuk ezt a legjobban kezelni, de akár egy SEO komponensben is lehet:


// components/Seo.js (példa)
import Head from 'next/head';
import { useRouter } from 'next/router';

function Seo({ title, description }) {
  const router = useRouter();
  const { locales, locale: currentLocale, asPath } = router;

  const baseUrl = process.env.NEXT_PUBLIC_BASE_URL || 'https://yourwebsite.com'; // Alap URL

  return (
    <Head>
      <title>{title}</title>
      <meta name="description" content={description} />

      {/* Alapértelmezett hreflang az aktuális nyelvhez */}
      <link rel="alternate" hrefLang={currentLocale} href={`${baseUrl}/${currentLocale}${asPath}`} />

      {/* Egyéb nyelvi verziók */}
      {locales.map((locale) => (
        locale !== currentLocale && (
          <link
            key={locale}
            rel="alternate"
            hrefLang={locale}
            href={`${baseUrl}/${locale}${asPath}`}
          />
        )
      ))}

      {/* x-default a felhasználó preferenciájától független alapértelmezett oldalhoz */}
      <link rel="alternate" hrefLang="x-default" href={`${baseUrl}/${router.defaultLocale}${asPath}`} />
    </Head>
  );
}
export default Seo;

Ezt a Seo komponenst minden oldalon használni kell, átadva a releváns címet és leírást.

2. Canonical URL-ek

Bár a hreflang segít, a canonical tagre is szükség van. Győződj meg róla, hogy minden nyelvi verzió egy önálló, saját kanonikus URL-lel rendelkezik, amely az adott nyelvi verzióra mutat. Például az angol verzió kanonikus URL-je example.com/en/page, a magyaré pedig example.com/hu/page.

3. Nyelvenkénti sitemapek

Készíts külön sitemapet minden nyelvi verzióhoz, vagy használj egy sitemapet, amely tartalmazza az összes nyelvi verzióra mutató linket, és jelzi a hreflang információkat. A Next.js API Routes segítségével könnyedén generálhatsz dinamikus sitemapeket.

4. URL struktúra

A Next.js i18n útválasztása alapértelmezetten az al-útvonalas megközelítést használja (pl. example.com/hu/termekek, example.com/en/products). Ez a módszer általánosan elfogadott és jól kezeli a SEO. Alternatívák lehetnek az aldomainek (hu.example.com) vagy a query paraméterek (example.com/products?lang=hu), de az al-útvonal a legegyszerűbben implementálható Next.js-szel és jó SEO gyakorlatnak számít.

5. Tartalom lokalizációja

Ne csak fordítsd a szövegeket! Vedd figyelembe a kulturális különbségeket a képek, videók, pénznemek, dátumformátumok és egyéb tartalmak tekintetében. Egy valójában lokalizált weboldal sokkal hatékonyabb, mint egy egyszerűen lefordított.

További jó gyakorlatok és haladó tippek

  • CMS integráció: Ha headless CMS-t használsz (pl. Contentful, Strapi, Sanity), győződj meg róla, hogy az támogatja a többnyelvű tartalmat. A legtöbb modern CMS igen, és megfelelő API-kkal könnyedén lekérhetők a lokalizált adatok.
  • Fordítási hiányok kezelése: Gondoskodj róla, hogy mi történjen, ha egy adott kulcshoz nincs fordítás. A next-i18next alapértelmezetten a kulcsot adja vissza, ami hasznos lehet a hiányok azonosításában.
  • Performancia: A fordítási fájlok lehetnek nagyok. Fontold meg a lazy loading alkalmazását a ritkábban használt névterek vagy nyelvek esetén, hogy optimalizáld a betöltési időt.
  • Tesztelés: Alaposan teszteld az összes nyelvi verziót, beleértve a nyelvváltást, az űrlapokat, a dátum- és számformátumokat.
  • Automatizált fordítások: Bár a gépi fordítások minősége folyamatosan javul, a professzionális emberi fordítások továbbra is elengedhetetlenek a kritikus tartalmak és a márkakommunikáció szempontjából.

Összegzés

Egy Next.js többnyelvű weboldal építése rendkívül kifizetődő befektetés, amely jelentősen kibővítheti a weboldalad elérését és hatását. A Next.js beépített i18n támogatása, a next-i18next könyvtárral karöltve, robusztus és viszonylag egyszerű módot kínál a komplex fordítási rendszerek kezelésére.

Ne feledkezz meg a SEO optimalizálásról sem, különösen a hreflang attribútumok helyes beállításáról, hogy a keresőmotorok is megtalálják és indexeljék az összes nyelvi verziót. Egy gondosan megtervezett és megvalósított többnyelvű weboldallal a felhasználói élményt is maximalizálhatod, biztosítva, hogy látogatóid a világ bármely pontjáról otthon érezzék magukat az oldaladon.

Most már minden eszköz a rendelkezésedre áll, hogy elindulj a nemzetközi weboldalad kiépítésének útján. Sok sikert a fejlesztéshez!

Leave a Reply

Az e-mail címet nem tesszük közzé. A kötelező mezőket * karakterrel jelöltük