Gatsby: Fügen Sie einen offiziellen Leitfaden für die Internationalisierung von Websites mit Gatsby hinzu

Erstellt am 4. Feb. 2018  ·  74Kommentare  ·  Quelle: gatsbyjs/gatsby

Als ich die Reaktionen auf meinen Kommentar zu einem anderen Thema sah , beschloss ich, dieses Thema zu öffnen.

Ich denke, dass i18n viel schwieriger ist, als es sein sollte. Ich konnte keine offizielle Dokumentation oder kein Plugin zur Internationalisierung von Inhalten auf von Gatsby erstellten Websites finden. Ich bin auf jsLingui gestoßen , das die meisten Probleme zu lösen scheint, aber es gibt immer noch keine Anleitungen zur Pflege von zB Markdown-Dateien/Seiten in verschiedenen Sprachen.

documentation

Hilfreichster Kommentar

Hey Leute, es ist fast ein Jahr her 😅

Ich habe vor kurzem das neue gatsby-Plugin gatsby-plugin-intl veröffentlicht , das Ihre gatsby-Website ganz einfach zu einem Internationalisierungs-Framework macht.

DEMO: https://gatsby-starter-default-intl.netlify.com

  • Out of box Internationalisierungs-Framework powered by react-intl

  • Unterstützt die automatische Weiterleitung basierend auf der bevorzugten Sprache des Benutzers im Browser

  • Unterstützt mehrsprachige URL-Routen in einer einzigen Seitenkomponente. Das bedeutet, dass Sie keine separaten Seiten wie pages/en/index.js oder pages/ko/index.js erstellen müssen.

  • Wie einige von euch oben vorgeschlagen haben, bündelt es jetzt während der Build-Zeit nur die aktuelle Sprache.

Außerdem möchte ich erwähnen, dass viele der i18n-Beispiele / -Starter tatsächlich auf der Clientseite gerendert werden. Der beste Weg, um zu überprüfen, ob die App als SSR gerendert wird, besteht darin, den Quellcode anzuzeigen und zu überprüfen, ob die lokalisierten Texte vorhanden sind. Bitte überprüfen Sie diese Angelegenheit, wenn Sie Ihre Gatsby-Website für SEO internationalisieren.

Alle 74 Kommentare

Es gibt diesen Artikel über die Verwendung von i18next mit GatsbyJS , was für mich die bisher fortschrittlichste Methode ist.

Aber ich habe nicht das Gefühl, dass i18next der "statische Weg" ist.

Zu dem Blogbeitrag hatte ich diese Fragen/Vorbehalte:
https://twitter.com/semdubois/status/930389055388508160

Es gibt https://github.com/angeloocana/gatsby-plugin-i18n, aber es hat mehrere Einschränkungen und erfährt nicht viel Aktivität/Aufmerksamkeit. Es könnte hilfreich sein, es innerhalb des Gatsby-Repositorys zu verschieben. Auch ich würde mich über eine ordentliche konsolidierte Lösung freuen.

Ich bin auch über js lingui gestolpert und es scheint vielversprechend zu sein, besonders wenn v2 gerade herausgekommen ist.

Das versuche ich auch herauszufinden. Die Verwendung der i18next-Methode für den Beitrag ist am bequemsten und fühlt sich intuitiv an, aber mir bleiben zwei Fragen....

  1. Wie kann ich verschiedene Markdown-Dateien für Sprachen wie in der gatsby-plugin-i18n-Lösung einbinden?

  2. Verzichtet dies komplett auf statisches Rendern des Inhalts?

Zur Info @angeloocana

Ich werde eine kurze Zusammenfassung schreiben, wie wir derzeit mit react-intl umgehen. Diese App ist noch nicht in Produktion, daher können wir immer noch einige Probleme mit diesem Setup finden, aber es scheint bisher gut zu funktionieren.

Wir speichern fast alle unsere Inhalte (die aus unserem Wordpress-Blog migriert wurden) in gatsby-source-contentful Plugin, um diese Daten abzurufen, aber zuvor haben wir diese Daten selbst abgerufen und in JSON-Dateien konvertiert und das gatsby-source-filesystem Plugin verwendet (wir haben eine Ordnerstruktur wie /en/blog/... , /de/blog/... ), also ist es egal, ob man Contentful verwendet oder nicht, solange jeder Knoten sein Gebietsschema kennt.

Wir haben auch einige Texte wie Schaltflächenbeschriftungen, einige Links oder statische Inhalte, die nicht von Contentful stammen, sondern stattdessen in Transifex übersetzt und mit JSON-Dateien synchronisiert werden, die im react-intl , nur weil ich sie bereits kenne und weiß, dass sie auch Datums- und Zahlenformatierungen verarbeitet. So richten wir es ein: https://github.com/gatsbyjs/gatsby/issues/3830#issuecomment -362710469. Wir verwenden dann zB intl.formatMessage beim Generieren von Meta-Tags und <FormattedMessage /> , <FormattedDate /> usw. Komponenten in Vorlagen.

@szimek Wenn ich Sie richtig verstehe, müssen Sie react-intl die Übersetzung der Komponententexte übernehmen, während sich die Beiträge in hartcodierten Routen unter dem Seitenverzeichnis befinden?

Das würde bedeuten, dass die hartcodierten Routen die einzigen sind, die statisch gerendert werden? Und die Übersetzungen zwischen den Komponenten von i18n werden dynamisch gerendert?

@deltaskelta Ich bin mir nicht sicher, ob ich deine Frage verstehe.

Wir haben derzeit kein benutzerdefiniertes clientseitiges Routing (wie zB hier beschrieben ), sondern nur statisch generierte Seiten. Beim Generieren einer post Seite (wir generieren auch länderspezifische und paginierte index und category Seiten mit einer leicht modifizierten Version des gatsby-pagination Plugins), sind wir unter Verwendung des folgenden Codes:

posts.edges.map(({ node }) => {
  const id = node.contentfulid;
  const locale = node.node_locale;

  return createPage({
    path: `/${locale}/blog/posts/${id}`,
    layout: locale,
    component: path.resolve('./src/templates/post-page.jsx'),
    context: {
      id,
      locale,
    },
  });
});

Auch wenn Sie JS deaktiviert haben, werden alle Inhalte, einschließlich der Meta-Tags, in der richtigen Sprache gerendert.

Auf unserer Seite verwenden wir i18next mit einigen Optimierungen

Die wichtigsten Prinzipien sind die folgenden:

  • Gebietsschemata sind als .json Dateien verfügbar und werden während des Builds einfach in das Verzeichnis /dist/ verschoben.
  • Wir arbeiten an einer einzigen Seite, die mit onCreatePage (in gatsby-node.js ) so viele statische Versionen erzeugt, wie wir Sprachen haben.
  • Seiteninformationen (zB Pfadname) werden in einer einzigen Datei zentralisiert.

Gebietsschemas

Übersetzungen wurden meist nach Seiten gruppiert, mit einem Namespace (= JSON-Datei) pro Seite + einer globalen Datei (für gemeinsame Texte wie Header / Footer).

|- src/
  |- locales/
    |- en/
      |- foo.json
      |- bar.json
    |- fr/
      |- foo.json
      |- bar.json

Leider gibt es kein Hot-Reloading bei Gebietsschemaänderungen 👎

i18weiter

i18next wird mit der folgenden Konfiguration initialisiert:

import i18n from "i18next";
import Backend from "i18next-xhr-backend";
import { reactI18nextModule } from "react-i18next";
import config from "config";  // Our custom configurations env-specifics

const NAMESPACES = [
  "foo",
  "bar",
  ...
];

export default function createI18n() {
  const options = {
    fallbackLng   : false,
    whitelist     : ["en", "fr"],
    ns            : NAMESPACES,
    debug         : config.debug,
    interpolation : {
      escapeValue : false
    },
    react         : {
      wait : true
    },
    backend       : {
      loadPath : `${config.pathPrefix}locales/{{lng}}/{{ns}}.json`
    },
    parseMissingKeyHandler : () => "",  // Display an empty string when missing/loading key
  };

  return i18n
    .use(Backend)
    .use(reactI18nextModule)
    .init(options);
}

Seiteninformationen

Bevor wir alle i18n-Versionen unserer Seiten generieren, müssen wir einige Informationen kennen, die wir in einer pagesInfos.js Datei zusammengefasst haben:

module.exports = {
  index : {
    id          : "index",
    namespace   : "home",
    path        : {
      fr : "/",
      en : "/en/"
    }
  },
  projects : {
    id          : "projects",
    namespace   : "projects",
    path        : {
      fr : "/nos-clients/",
      en : "/en/our-clients/"
    }
  },
  // etc...

Wobei die Schlüssel die Dateinamen der Dateinamen der

In diesem Fall:

|- src/
  |- pages/
    |- index.js
    |- projects.js
  |- locales/
    |- en/
      |- home.json
      |- projects.json
    |- fr/
      |- home.json
      |- projects.json

Und wobei Pfad die Pfadnamen unserer zukünftigen Versionen (Sprachen) unserer Seiten sind.

Seiten erstellen

Mit dem gleichen Beispiel wie oben ist unser Ziel hier, eine FR + EN-Version der Home- und Projektseiten zu erstellen.

Um dies zu ermöglichen, haben wir eine dedizierte Funktion geschaffen:

/**
 * Generate a custom page informations
 * <strong i="15">@param</strong>  {Object} defaultInfos  Default informations generated by Gatsby
 * <strong i="16">@return</strong> {Object}               Customized page object
 */
function generatePagesInfos(defaultInfos) {
  const pageId = defaultInfos.jsonName.slice(0, -5);  // NOTE: Get pageId from "pageName.json"
  const pageInfos = pagesInfos[pageId];

  const pageFR = {
    ...defaultInfos,
    context : {
      pageId      : pageInfos.id,
      namespace   : pageInfos.namespace,
      language    : "fr"
    },
    path : pageInfos.path.fr
  };

  const pageEN = {
    ...defaultInfos,
    context : {
      pageId      : pageInfos.id,
      namespace   : pageInfos.namespace,
      language    : "en"
    },
    path : pageInfos.path.en
  };

  return [pageFR, pageEN];
}

Dieser Helfer wird dann während des onCreatePage Hooks verwendet, der jede Seite über eine Regex auswählt:

exports.onCreatePage = async ({ page, boundActionCreators }) => {
  const { createPage, deletePage } = boundActionCreators;

  return new Promise((resolve, reject) => {

    if (page.path.match(page.path.match(/^\/$/))) {
      const i18nPages = generatePagesInfos(page);
      deletePage(page);                         // Remove old default page
      i18nPages.map(page => createPage(page));  // Create custom i18n pages
    }

    if (page.path.match(/^\/projects\/?$/)) {
      const i18nPages = generatePagesInfos(page);
      deletePage(page);
      i18nPages.map(page => createPage(page));
    }

    // etc...

    resolve();
  });
}

Wir haben jetzt zwei Versionen jeder Seite mit einem benutzerdefinierten Pfadnamen (aus unserer Seiteninformationsdatei). Sie haben vielleicht bemerkt, dass wir language Informationen an jede Seite über pathContext . Dieser Wert wird auf jeder Seite verwendet, um die richtige Sprache anzuzeigen.

Anzeige der richtigen Sprache

Wir verwenden die React-Klasse für Seiten, wobei der folgende Dekorator automatisch die Sprache der aktuellen Seite kennt und i18n bei Bedarf aktualisiert:

import React from "react";
import PropTypes from "prop-types";
import { i18n } from "context";    // Our custom context

/**
 * <strong i="10">@returns</strong> {React.PureComponent} Component with locales as proptypes
 */
export default function setLanguageFromPage() {

  return WrappedComponent => (
    class extends React.PureComponent {

      static propTypes = {
        pathContext : PropTypes.shape({
          language : PropTypes.string.isRequired
        })
      }

      componentDidMount() {
        const currentLanguage = i18n.language;
        const pageLanguage = this.props.pathContext.language;

        // First request
        if (!currentLanguage) {
          i18n.language = pageLanguage;
        }

        // Only update on language change
        if (currentLanguage !== pageLanguage) {
          i18n.changeLanguage(pageLanguage);
        }
      }

      render() {
        return <WrappedComponent {...this.props} />;
      }

    }
  );

}

Dann rufen Sie es auf den Seiten auf:

@setLanguageFromPage()
export default class ProjectsPage extends React.PureComponent {
// ...

Pfew, Sie müssen jetzt nur noch die Übersetzungsfunktion von i18next verwenden.

Fazit

👍 Eine einzige Quelldatei, die während des Builds so viele Versionen wie nötig generiert
👍 Einfache Seitenausgabeverwaltung
👍 Zuerst einige Anstrengungen, aber dann ist alles einfach

👎 Kein Hot-Reload für Gebietsschemas

Ich habe das Gefühl, dass es nicht wirklich die "statische Lebensweise" ist ... Aber das ist das Beste, was wir im Moment bekommen haben.

Ich würde gerne sehen, was Sie davon halten und wie Sie damit umgehen.

PS. Poke @szimek , das wollte ich euch vor ein paar Tagen zeigen :)

Ich habe https://github.com/angeloocana/gatsby-plugin-i18n + React-intl von @angeloocana verwendet und es ist nicht so kompliziert wie die obigen Methoden, aber es gibt einige Einschränkungen (siehe Repo-Probleme) und ich bin nicht so glücklich über React-intl. würde gerne https://github.com/lingui/js-lingui von @tricoder42 ausprobieren, hatte einfach keine Zeit.

@monsieurnebo was ist das Ziel, deletePage direkt vor createPage auszuführen ? Ihre Lösung gefällt mir und ich habe versucht, sie zu implementieren, aber ich habe einige Fehler.

  • Ich erhalte entweder ein falsches pathContext.language ohne deletePage

  • oder ich erhalte einen Build-Fehler, wenn ich deletePage wie in Ihrem Beispiel einfüge. (Es sagt TypeError: Cannot read property 'id' of undefined wenn der Build die Stufe run graphql queries )

Dies ist die beste Lösung, die ich bisher gesehen habe.

@deltaskelta Schön , dass es dir gefällt!

deletePage wird verwendet, um die Erstellung der Standardseite durch Gatsby abzubrechen. Wenn Sie dies nicht hinzufügen, erhalten Sie Ihre benutzerdefinierten Seiten und die Standardseiten.

Überprüfen Sie Ihr public Verzeichnis mit und ohne diese Zeile, Sie werden den Unterschied erkennen ;)

Ihre Fehler sind ohne Code schwer zu erraten. Könnten Sie mit Ihrem Code ein Repository erstellen? Ich würde es mir dann mal anschauen.

EDIT: Würde dich ein Beispiel interessieren?

Oh, es hatte nichts mit dem deletePage-Aufruf zu tun. Es war ein Problem, das Seitenobjekt nicht zu kopieren, da ich Ihr Beispiel geändert hatte. Ich stolpere immer über das Kopieren von Objekten, nachdem ich eine Weile von js weg war ;)

@monsieurnebo Ich habe mit Ihrer Lösung react-i18next HOC umschlossen sind, Javascript zu benötigen, um alles in der Komponente zu rendern...

Können Sie bestätigen, ob es bei Ihnen so funktioniert?

EDIT: Übrigens habe ich Ihre Erwähnung eines Beispiels übersehen, wenn Sie die Zeit haben, würde ich gerne ein vollständiges Beispiel sehen.

@deltaskelta Ich werde ein Beispiel machen, wenn ich etwas Freizeit habe :)

@monsieurnebo können Sie bestätigen, dass Ihre Methode die Strings nicht statisch in HTML

Yup, deshalb ist es nicht ganz der "statische Lebensstil" 😐

Ich würde mich über ein Plugin freuen, das stattdessen statischen Text generiert.

Hmm, ich verstehe. Ein statisches Rendering wäre der Weg, den ich gehen muss ...

Ich dachte, da die Kontexte für die meisten Seiten in Ihrem gatsby-node bereits mit dem Sprachnamen übergeben werden, wäre es nicht allzu schwieriger, einfach nach den Nachrichtenschlüsseln in den graphql-Abfragen für jede Seite zu fragen und übergeben Sie sie auf diese Weise, aber ich würde lieber ein i18n-Tool verwenden, wenn möglich ...

@szimek wie react-intl die Übersetzungen im Build-Schritt und verwendet keine js?

Wie bereits erwähnt, generiert Gatsby-plugin-i18n meines Wissens statischen Text. Haben Sie das Beispiel überprüft?

@deltaskelta Nun, alle Übersetzungen sind während der Build-Zeit verfügbar (deshalb verwende ich mehrere Layouts), also "funktioniert einfach" ™️ ;) Ich hoffe nur, dass es in v2 weiterhin funktioniert ... Ich kann eine Beispiel-App vorbereiten, wenn Sie wollen. Ich habe mir gatsby-plugin-i18n noch nicht wirklich angeschaut, weil ich mit Contentful arbeite, nicht mit Dateien.

Ich habe die Details nicht gelesen, aber es gibt eine Diskussion (oder eher einen Monolog) über die gatsby-plugin-i18n + Contentful Combo hier: https://github.com/angeloocana/gatsby-plugin-i18n/issues/31

@szimek Ein Beispiel würde mich sehr interessieren. @sedubois Ich weiß, dass gatsby-plugin-i18n auch statischen Text generiert, aber ich sehe nicht, wo die Magie passiert, die in i18next fehlt, um völlig statische Dateien zu generieren ....

Ich denke, ich könnte jetzt verstehen, warum ... Sie während des Renderns react-intl die Nachrichten durch pathContext in gatsby-node weiterleiten?

BEARBEITEN: Wenn dies der Fall ist (was Sinn macht), ist die verwendete i18n-Bibliothek "etwas" irrelevant, da man Nachrichten durch den Kontext weiterleitet und statisch rendert, was ein reines Gatsby-Setup ist und die i18n-Bibliothek nur Sonderfälle behandelt wie Datums- und Pluralformen mit js.

Bei weiteren Tests von i18next und react-intl scheint es, dass die Übersetzungs-HOC von i18next Javascript zum Laden benötigt. Jede Verwendung von translate HOC wird die gesamte Komponente rendern, die Javascript benötigt, um ausgeführt zu werden.

Andererseits rendert die FormattedMessage Komponente von react-intl eine Standardnachricht (die auf dem übergebenen Kontext basieren kann) und rendert beim Build statisch in den HTML-Code.

Ich würde denken, dass die natürlichere Integration von i18n mit React-intl wäre, wenn Sie statisch gerenderte Übersetzungen in HTML erzielen möchten. Wenn ich den Flow, den ihr benutzt, falsch verstanden habe, korrigiert mich bitte

@mattferderer hatte hier die richtige Idee, aber ich denke, es muss ein wenig optimiert werden. https://github.com/gatsbyjs/gatsby/issues/3830#issuecomment -362715706

Layouts werden vor Seiten gerendert, so dass es ohne das Erstellen mehrerer Layouts keine Möglichkeit gibt, Nachrichten über den Kontext von der createPages Funktion zu übergeben (korrigieren Sie mich, wenn ich mich hier irre). Um i18n am einfachsten zu machen, würde ich denken, dass das Layout einfach children() aufrufen sollte und dann die verschiedenen Layouts pro Spracheffekt dadurch erreicht werden, dass gatsby-node verschiedene Pfade pro Sprache erstellen Indexseiten von pages/index denen Nachrichten per Kontext übergeben werden können

EDIT: Entschuldigung für das Geschwafel, aber es wurde gerade alles klar und ich musste es irgendwo aufzeichnen

EDIT2: Oben liege ich definitiv falsch, Kopf- und Fußzeilen müssen in das Layout eingefügt werden, ich weiß nur nicht, wie ich die Nachrichten an sie bekomme, ohne mehrere Layouts zu erstellen. Die einzige andere Möglichkeit, die ich mir vorstellen kann, wäre das Aufteilen von URLs und das Regexing für das Gebietsschema ... aber das fühlt sich an wie eine hackige Sache

@KyleAMathews mit v2 mit nur einem Layout, wie können wir Daten wie i18n-Nachrichten über den Kontext basierend auf dem Pfad oder einem Array von Sprachschlüsseln an die Stammlayoutkomponente übergeben?

Wenn dies möglich wäre, wäre es einfach, i18n zu implementieren, aber ich kann nicht sehen, wie es geht, ohne mehrere Layouts zu erstellen

@deltaskelta Hier ist ein Beispiel dafür, was wir tun: https://github.com/szimek/gatsby-react-intl-example. Es zeigt, wie Sie einzelne Beiträge rendern, wie Sie eine Indexseite für jedes Gebietsschema erstellen, wie Sie react-intl Komponenten verwenden, wie Sie react-intl injectIntl HOC verwenden, um einen Titel festzulegen (oder alle anderen Meta-Tags) für Indexseiten mit intl.formatMessage Helper usw.

Die generierten Seiten sind:

  • /en
  • /en/hello-world
  • /pl
  • /pl/witaj-swiecie

In der echten App verwenden wir eine modifizierte Version von gatsby-pagination , da die Originalversion keine Layoutoption unterstützt. Wir setzen auch das Feld post_id für jeden Beitrag, das es uns ermöglicht, Übersetzungen desselben Beitrags zu finden, zB im Fall dieser Demo-App hätten beide Beiträge das gleiche post_id .

Übrigens. Ich habe gerade festgestellt, dass wir höchstwahrscheinlich separate Sitemaps für jede Sprache erstellen müssen, damit Swiftype (die von uns verwendete Suchmaschine) weiß, welche Seiten wir haben.

@deltaskelta Kurz Layoutkomponente pro Sprache. Hier ist eine Möglichkeit, dies zu tun.

// French
import React from 'react'
import FrenchLayout from '../components/layouts/french'
import ImportantPage from '../components/pages/important-page'

export default ({ data }) => (
  <FrenchLayout>
    <ImportantPage {...data} />
  </FrenchLayout>
)

// French query here
// English
import React from 'react'
import EnglishLayout from '../components/layouts/english'
import ImportantPage from '../components/pages/important-page'

export default ({ data }) => (
  <EnglishLayout>
    <ImportantPage {...data} />
  </EnglishLayout>
)

// English query here

@KyleAMathews Diese Dateien sind Vorlagen, oder? Bedeutet das, dass ich bei 3 Seitentypen und 7 Sprachen 21 Vorlagen benötige? :)

Das obige ist die am besten optimierte Vorgehensweise. Wenn jede Layoutkomponente nicht so unterschiedlich ist, können Sie sie zu einer Layoutkomponente kombinieren und dann das Layout je nach aktiver Sprache wechseln.

Ich habe die Details nicht gelesen, aber es gibt eine Diskussion (oder eher einen Monolog) über die gatsby-plugin-i18n + Contentful Combo hier: angeloocana/gatsby-plugin-i18n#31

@sedubois , haha, ja. Zusammenfassung: Habe es zum Laufen gebracht und gatsby-starter-contentful-i18n Starter-Repo in Gatsby-Dokumente über diese PR eingebunden: https://github.com/gatsbyjs/gatsby/pull/4138

Interessiert an der anderen Lösung oben, insbesondere im Vergleich zum Community-Plugin in Bezug auf: SEO usw.

@mccrodp Ihre Lösung sieht gatsby-plugin-i18n die Option layout nicht explizit an createPage , sondern dies für Sie erledigt hinter den Kulissen. Es verwendet jedoch immer noch mehrere Layouts ;)

Ich habe den Vorschlag von @KyleAMathews übernommen und ein components/Layout , das eine i18n-Bibliothek verwendet und meinen Gatsby-Layout-Ordner vollständig gelöscht. Auf diese Weise kann ich in gatsby-node Seiten für meine Gebietsschemata erstellen und sie haben Zugriff auf alles, worauf eine Seite Zugriff hat, einschließlich Pfade.

Ich kann dann das Gebietsschema direkt an die Layoutkomponente übergeben, die es an i18n weitergibt.

Es ist etwas unbequem, jede Komponente auf Seitenebene mit dem Layout umschließen zu müssen, aber es hat so viel Verwirrung beseitigt und meinen Code stark vereinfacht.

Hey @deltaskelta , hast du ein Beispiel für deine Lösung? Würde gerne sehen, ob man daraus etwas lernen kann, um den Upstream zum Community-i18n-Plugin zu pushen. Danke.

Mein ganzes Projekt ist gerade in einem chaotischen Zustand, aber ich denke, ich kann die Grundlagen legen ...

  1. Kein Layout - weil (wenn ich mich richtig erinnere) das Layout vor Pfaden oder etwas anderem sehr Wichtigem ins Spiel kommt, was mich daran hinderte, ihm die richtigen Nachrichtenobjekte zu geben...

  2. Füttern Sie die richtigen messages und locale im gatsby-node durch den Kontext...

exports.onCreatePage = ({ page, boundActionCreators }) => {
  const { createPage, deletePage } = boundActionCreators;

  if (page.path.includes('404')) {
    return; // no need for localized 404 pages
  }

  return new Promise(resolve => {
    // if it is not the app page then I need localized static pages
    const pages = localizedPages(page);
    deletePage(page);
    pages.map(page => createPage(page));

    resolve();
  });
};

// to be passed to the localized pages so it can calculate the matchPath
const getMatchPath = lang => {
  return `${locales[lang]['path']}/app/:path`;
};

// this is a helper function that makes pages in each language.
const localizedPages = (page, matchPathFunc) => {
  var pages = [];
  Object.keys(locales).map(lang => {
    const path = locales[lang]['path'] + page.path;

    pages.push({
      ...page,
      path: path,
      matchPath: matchPathFunc ? matchPathFunc(lang) : undefined,
      context: {
        locale: lang,
        messages: locales[lang],
        pathRegex: `/.pages${page.path}./` // so pages can match markdown in their dir
      }
    });
  });

  return pages;
};
  1. Erstellen Sie nun eine globale Layoutkomponente, die auf jeder Komponente auf Seitenebene aufgerufen werden muss...
// this is the main entrypoint for the layout to the site
const GlobalLayout = ({ locale, children, path }) => {
  const theme = getTheme();
  return (
    <MuiThemeProvider theme={theme}>
      <CssBaseline>
        <IntlProvider locale={locale} messages={locales[locale]}>
          <div>
            <Header locale={locale} messages={locales[locale]} path={path} />
            {children}
          </div>
        </IntlProvider>
      </CssBaseline>
    </MuiThemeProvider>
  );
};
  1. Rufen Sie die globale Layoutkomponente mit Ihren Komponenten auf Seitenebene auf, die das richtige Gebietsschema und die vom Kontext übergebenen Nachrichten haben
const BlogPost = ({ data, pathContext, location }) => {
  const { locale } = pathContext;
  return (
    <GlobalLayout locale={locale} path={location.pathname}>
      <FullWidth>
        <h1>{data.markdownRemark.frontmatter.title}</h1>
        <h3>{data.markdownRemark.frontmatter.date}</h3>
        <div dangerouslySetInnerHTML={{ __html: data.markdownRemark.html }} />
      </FullWidth>
    </GlobalLayout>
  );
};

Ich muss diesen Code aufräumen und neu organisieren, weil ich es nur schnell gemacht habe, um zu beweisen, dass es funktionieren könnte, und ich werde es später noch einmal besuchen ... Ich hoffe, das gibt Ihnen das Wesentliche

Ich habe einen Gatsby-Starter erstellt, der js-lingui verwendet, um Nachrichten zu übersetzen:
https://github.com/dcroitoru/gatsby-starter-i18n-lingui

In der echten App verwenden wir eine modifizierte Version von gatsby-pagination, da die Originalversion keine Layoutoption unterstützt. Wir setzen auch das Feld post_id für jeden Beitrag, das es uns ermöglicht, Übersetzungen desselben Beitrags zu finden, zB im Fall dieser Demo-App hätten beide Beiträge die gleiche post_id.

@szimek Gibt es eine Möglichkeit, dass Sie Ihre modifizierte Gatsby-Paginierung teilen können? Würde mich sehr freuen, da ich selbst ein ähnliches Problem habe.

@martynhoyer Mein Patch wurde zusammengeführt, also bin ich zurück zur Originalversion von gatsby-pagination gewechselt . Welches Problem hast du?

Hallo @sgoudie
Ich benutze dieses Tutorial: https://www.gatsbyjs.org/blog/2017-10-17-building-i18n-with-gatsby/ aber ich kann keines meiner locales/{lang}/*.json . Hat jemand eine Ahnung?
2018-04-25 12_04_13-o intermedium agora e banco inter

Meine Konfiguration:
gasbty-node.js
```javascriptexports.onPostBuild = () => {
console.log('Gebietsschemas werden kopiert')
fs.copySync(
path.join(__dirname, '/src/locales'),
path.join(__dirname, '/public/locales')
)
}

```

Hinzufügen

exports.onPostBootstrap = () => {
    console.log("Copying locales");
    fs.copySync(
        path.join(__dirname, "/src/locales"),
        path.join(__dirname, "/public/locales")
    );
};

zu gatsby-node.js

@ThiagoMiranda Ich stand vor dem gleichen Problem, als mir klar wurde, dass gatsby develop onPostBuild nicht aufruft, sondern nur gatsby build aufruft. onPostBootstrap wird jedes Mal aufgerufen.

Weiß jemand, wie man https://moz.com/learn/seo/hreflang-tag in den Layouts erstellt?

@RobinHerzog Wir erstellen sie in Vorlagen mit Helmet. Sie sind spezifisch für den Seitentyp, daher war es zumindest in unserem Fall nicht sinnvoll, sie in einem Layout zu erstellen.

@szimek danke für die Antwort. Ich verstehe, aber in meinem Fall wäre es interessant, es in den Layouts zu haben.

<link rel="alternate" href={Route['en-us'][this.props.data.prismicDocument.data.group]} hreflang="en-us" /> <link rel="alternate" href={Route['fr-fr'][this.props.data.prismicDocument.data.group]} hreflang="fr-fr" />

Kopieren Sie im Moment, wie Sie sagten, diese Zeilen in alle Vorlagen.

Ich beginne erst mit der Entwicklung mit React/JavaScript, aber alles, was ich gesehen habe, um i18n zu unterstützen, war zu komplex. Hier ist meine eigene Arbeit für den häufigsten Gebrauch: weise-starter

Live-Reload, SEO-freundlich und Standardsprachen verwenden nicht den Schlüssel in der URL.
Alle .js-Seiten werden für alle Sprachen generiert.
Alle Layouts und .md müssen für alle Sprachen erstellt werden, um Fehler zu vermeiden.
LangSelect und Link-Komponente sind i18n smart.

Wenn Sie mir helfen und mir erklären können, wie ich meinen Code und meinen Stil verbessern könnte, wäre ich Ihnen dankbar.

@Tom-Pichaud, ich glaube, da Sie Nachrichten nicht an die Seitenkomponenten weiterleiten, werden sie dort nicht statisch gerendert.

Das Markdown-i18n-Setup in gatsby-node ähnelt dem, was die Leute hier gemacht haben, aber ich bin neugierig, ob Sie statisches Rendering mit deaktiviertem Javascript für Ihre Seitenkomponenten erhalten?

Ja, ich bekomme statisches Rendering, das war sowieso mein Ziel, i18n-react macht den Trick!

@TomPichaud wäre es Ihnen möglich zu teilen, wie das von Ihnen erwähnte i18n-react besser ist als js-lingui ?

Eine Sache, die ich nicht ganz verstehe, ist die tatsächliche Notwendigkeit externer Pakete, um die übersetzten Nachrichten zu laden (außer Pluralisierung und Verwandten wahrscheinlich).

Für eine einfache Site mit statischem Inhalt dupliziere ich einfach die Seiten für jede Sprache onCreatePage und übergebe das Gebietsschema an context :

// some file with the locales
const locales = {
  en: {
    path: 'en',
    default: true,
  },
  pt: {
    path: 'pt',
  },
}
// gatsby-node.js
exports.onCreatePage = ({ page, boundActionCreators }) => {
  const { createPage, deletePage } = boundActionCreators

  return new Promise(resolve => {
    deletePage(page)

    Object.keys(locales).map(lang => {
      const localizedPath = locales[lang].default
        ? page.path
        : locales[lang].path + page.path

      return createPage({
        ...page,
        path: localizedPath,
        context: {
          locale: lang,
        },
      })
    })

    resolve()
  })
}

Dann verwende ich auf der eigentlichen Seite das Gebietsschema im Kontext, um den Inhalt mit dem Filter von graphql abzufragen.

Nehmen wir an, ich habe den Home-Inhalt in /data/home/en.js und /data/home/pt.js :

import React from 'react'

const IndexPage = ({ pathContext: { locale }, ...props }) => {
  const { childHomeJson: data } = props.data.allFile.edges[0].node

  return <div>{data.hello}</div>
}

export const query = graphql`
  query HomeContent($locale: String) {
    allFile(filter: { name: { eq: $locale } }) {
      edges {
        node {
          childHomeJson {
            hello
          }
        }
      }
    }
  }
`

export default IndexPage

funktioniert gut mit netlifyCMS (wenn auch etwas ausführlich, bis sie i18n unterstützen) und Bildern in den JSON-Dateien (obwohl wir ein neues NodeField mit dem relativen Pfad erstellen müssen, damit Gatsbys Dateisystem es bekommt)

Reicht das nicht für die meisten Fälle?

Ich teste immer noch und habe nichts davon in der Produktion verwendet, aber ich überlege, die Kontext-API von React für das Gebietsschema zu verwenden, um einige ausstehende Probleme wie lokalisierte Links zu lösen

@pbrandone Dies scheint mir ein großartiger Ansatz zu sein. Ich denke, dass etwas Ähnliches offiziell dokumentiert werden sollte.

Vielen Dank für all die Inputs, die Menge der hier diskutierten Ideen zeigt deutlich die Nachfrage nach gut dokumentierter i18n-Unterstützung.

@pbrandone Bedeutet dies, dass Sie alle Schlüssel, die von IndexPage in dieser Abfrage explizit angeben und Übersetzungen über Requisiten an alle Komponenten übergeben müssen?

Außerdem verwende ich Pluralisierungsregeln und relative Daten, daher muss ich sowieso zusätzliche länderspezifische Daten laden :/

Ich stimme jedoch zu, dass es großartig wäre, eine offizielle Dokumentation zu haben, wie man i18n ohne Bibliothek für einfache Fälle und dann mit den gängigsten Bibliotheken macht.

@szimek gut, in diesem Fall ja.

Es ist sehr einfach, response-intl (oder jede andere i18n-Bibliothek) hinzuzufügen:

// in src/components/layout/index.js

import React from 'react'
import { IntlProvider, addLocaleData } from 'react-intl'

// Locale data
import enData from 'react-intl/locale-data/en'
import ptData from 'react-intl/locale-data/pt'

// Messages
import en from '../../data/en.json'
import pt from '../../data/pt.json'

const messages = { en, pt }

addLocaleData([...enData, ...ptData])

const Layout = ({ locale, children }) => (
  <IntlProvider locale={locale} messages={messages[locale]}>
    {children}
  </IntlProvider>
)

export default Layout

und dann auf den seiten:

import React from 'react'
import { FormattedMessage } from 'react-intl'

import Layout from '../components/layouts'

const IndexPage = ({ pathContext: { locale } }) => (
  <Layout locale={locale}>
    <FormattedMessage id="hello" />
  </Layout>
)

export default IndexPage

Aber dann wären Sie nicht in der Lage, mehrere JSON-Dateien (zB pro Seite) zu verwenden oder alle CMS-Daten in diesen Dateien mit der Leistung von graphql abzufragen und zu transformieren.
Mit dem graphql-Ansatz könnten wir zum Beispiel einige Schlüssel mit Pfaden für Bilder in diesen JSON-Dateien haben, um verschiedene Bilder pro Gebietsschema zu laden und trotzdem gatsby-image zu können.
Und dann fügen Sie netlify CMS hinzu, um diese JSON-Dateien zu bearbeiten 😃

Ich habe mir gatsby v2 nicht richtig angesehen, aber anscheinend gibt es eine StaticQuery Komponente, die es uns ermöglicht, untergeordnete Komponenten abzufragen (jemand korrigiert mich, wenn ich falsch liege!)

Wenn dies der Fall ist, könnten wir einen React Context erstellen, um das Gebietsschema überall verfügbar zu machen, und dann die erforderlichen Schlüssel in jeder Komponente mit der Gebietsschemafilterung abfragen

@pbrandone Sie haben Recht, es wird statisch auf diese Weise react-intl Setup in Gatsby - Browser, wie es ohne Javascript vielleicht nicht machen scheint. Meine Lösung sieht jetzt genauso aus wie deine

@KyleAMathews Ich versuche, unsere Seite auf Gatsby auf v2 zu aktualisieren und habe ein Problem mit unseren react-intl Setup- und Graphql-Abfragen.

Ich habe zuvor erklärt, wie ich sprachspezifische Layouts verwende, um Sprachdaten in Gatsby v1 zu laden - https://github.com/szimek/gatsby-react-intl-example. In Gatsby v2 hatte ich die Idee, diese Layouts durch sprachspezifische Seitenkomponenten zu ersetzen. Ich hätte eine sprachunabhängige src/templates/Post.js Komponente und dann sprachspezifische Komponenten wie src/templates/Post.en.js , src/templates/Post.de.js , die nur Sprachdaten laden und die sprachunabhängige Komponente rendern würden.

In Ihrem vorherigen Kommentar (https://github.com/gatsbyjs/gatsby/issues/3853#issuecomment-367115380) haben Sie ein Beispiel gezeigt, in dem jede Seitenkomponente eine sprachspezifische Abfrage hat.

Das Problem dabei ist, dass ich beim Aufrufen von createPage die Namen dieser sprachspezifischen Komponenten (zB src/templates/Post.en.js ) als Option component , aber die graphql-Abfrage ist in die sprachunabhängige Komponente, weil sie __für alle Sprachen genau gleich ist__ (es hängt von locale , aber ich übergebe sie in context ). Ich möchte vermeiden, in all diesen sprachspezifischen Komponenten genau dieselbe Abfrage zu wiederholen.

Irgendwelche Ideen, wie man es löst? Kann ich diese Abfrage in eine Variable extrahieren? Als ich es ausprobiert habe, beschwert sich Gatsby darüber, dass Abfrage- und Fragmentnamen gleich sind ...

Ich habe vor kurzem einen Standard-Gatsby-Starter mit Funktionen für mehrsprachige URL-Routen und Browser-Spracherkennung hinzugefügt. (Demo)

gatsby-starter-default-intl

Merkmale:

  • Lokalisierung (mehrsprachig) bereitgestellt von React-intl .

  • Automatische Weiterleitung basierend auf der bevorzugten Sprache des Benutzers im Browser, bereitgestellt von browser-lang .

  • Unterstützt mehrsprachige URL-Routen innerhalb einer einzelnen Seitenkomponente. Das bedeutet, dass Sie keine separaten Seiten wie pages/en/index.js oder pages/ko/index.js erstellen müssen.

  • Basierend auf gatsby-starter-default mit der geringsten Änderung.

@wiziple Danke! Es sieht wirklich interessant aus. Ich hatte keine Ahnung, dass man so etwas machen kann: https://github.com/wiziple/gatsby-starter-default-intl/blob/master/src/i18n/withIntl.js#L38 ;) Hoffentlich funktioniert es noch im Webpack 4...

Ist es möglich, hier https://github.com/wiziple/gatsby-starter-default-intl/blob/master/src/i18n/withIntl.js#L6 auf die gleiche Weise Locale-Daten zu laden? Wir unterstützen 6 (bald 7 Sprachen), daher wäre es toll, wenn ich nur die Sprache laden könnte, für die ich die Seite erstelle. es ist keine große Sache, wenn es nicht möglich ist - glücklicherweise sind diese Gebietsschema-Datendateien relativ klein.

Ich muss auch mal schauen, wie man diese Seiten generiert, da in meinem Fall nicht jede Seite in alle Sprachen übersetzt wird (es gibt keine einzige "Ausgangssprache"), daher wird die Lösung mit onCreatePage wahrscheinlich nicht funktionieren in meinem Fall.

Hoffentlich wird dies mein Problem mit derselben graphql-Abfrage in jeder sprachspezifischen Seitenkomponente lösen.

@szimek
Die von mir verwaltete Website hat 14 Sprachen und jede Sprachdatei ist 12-15 KB groß. Ich bin mir ziemlich sicher, dass wir zur Erstellungszeit für jeden Sprachrouter die richtige Sprache bereitstellen müssen, um SEO-Daten zu generieren. Ich bin mir also nicht sicher, wie ich damit umgehen soll, ohne alle Sprachen bereitzustellen.

Ich verstehe, dass es manchmal schwierig ist, jede Seite in alle Sprachen übersetzt bereitzustellen. Sie können dies möglicherweise lösen, indem Sie eine Ausnahme für onCreatePage in gatsby-node.js bereitstellen. In meinem Fall habe ich es einfach gelöst, indem ich unabhängig vom Sprachrouter keine übersetzte Sprache angeboten habe. 😆 Sie können die Showcase-Website zur Produktion im Starter README.md finden und ihre Leistung überprüfen.

@wiziple Vielen Dank!

Ich habe Ihre withIntl Komponente mit dem dynamischen require Trick für Übersetzungen verwendet (ich habe keine Ahnung, ob es irgendwelche Nachteile bei der Verwendung gibt) und es scheint großartig zu funktionieren. Es löste das Problem, mit dem ich zu kämpfen hatte - wie man dieselbe graphql-Abfrage in mehreren sprachspezifischen Seitenkomponenten handhabt -, indem es eine einzige Seitenkomponente für alle Sprachen hatte.

@wiziple danke für die Repo-Freigabe. Hat mich auf den richtigen Weg gebracht 😄 🎉

lingui scheint eine bessere Alternative zu sein . Ich glaube nicht, dass @dcroitoru für ein großartiges Beispiel die richtige Anerkennung gefunden hat. Braucht nur ein wenig Liebe, um es auf Gatsby 2.0 zu bringen

Ich stimme zu, dass Lingui in der Tat wirklich nett ist, obwohl es noch einen kompletten Starter braucht, mit der neuesten Version von Gatsby aber auch Lingui. Der erwähnte Starter ist inoffiziell und es fehlten einige Funktionen, als ich das letzte Mal überprüft habe (zB die Verwendung eines Loaders, um lingui-kompilieren im laufenden Betrieb auszuführen). Linguis Autor @tricoder42 sagte, dass er eine Dokumentation bereitstellen werde, wenn Lingui v3 herauskommt (was in Kürze zu sein scheint).

NB: Ich habe festgestellt, dass mein Bedarf an einer i18n-Bibliothek nach der Integration eines CMS (DatoCMS) zurückgegangen ist, aber ich benötige Lingui immer noch für einige Strings, die ihren Platz im CMS nicht finden und auch für Pluralisierung und möglicherweise andere Dinge später, also ich definitiv möchte es in meiner Codebasis behalten.

Jedenfalls hat die Existenz von gatsby-plugin-i18n in meinem Fall die Sache ziemlich verwirrend gemacht, da es nicht gepflegt ist, einen verwirrenden Namen hat und die Aufmerksamkeit von diesen anderen wirklich netten Lösungen wie js-lingui und CMSes ablenkt, die ich dann übernommen habe während, um herauszufinden und zusammen zu montieren.

Ich habe zwei Internationalisierungsbeispiele mit der React-Intl-Integration gemacht

Das erste Beispiel konzentriert sich darauf, nur aktuelle Übersetzungen in js-Chunks zu bündeln (etwas, das ich in anderen Plugins, die ich überprüft habe, nicht finden konnte).

Das zweite Beispiel konzentriert sich auf die Verwendung dynamischer Abfragen, um nur angeforderte Übersetzungen für eine bestimmte Seiten-/Sprachkombination bereitzustellen.

Hoffentlich sind diese Beispiele für jemanden nützlich.

Habe auch einen schnellen mittleren Beitrag gemacht (und vergessen, ihn hier zu posten) mit so ziemlich dem, was in https://github.com/gatsbyjs/gatsby/issues/3853#issuecomment -395432693 steht (wenn auch etwas ausführlicher).

https://blog.significa.pt/i18n-with-gatsby-528607b4da81 für alle die es interessiert

Alte Ausgaben werden nach 30 Tagen Inaktivität geschlossen. Dieses Problem ist seit 20 Tagen still und wird als veraltet markiert. Antworten Sie hier oder fügen Sie das Label "nicht veraltet" hinzu, um dieses Problem offen zu halten!

Hey Leute, es ist fast ein Jahr her 😅

Ich habe vor kurzem das neue gatsby-Plugin gatsby-plugin-intl veröffentlicht , das Ihre gatsby-Website ganz einfach zu einem Internationalisierungs-Framework macht.

DEMO: https://gatsby-starter-default-intl.netlify.com

  • Out of box Internationalisierungs-Framework powered by react-intl

  • Unterstützt die automatische Weiterleitung basierend auf der bevorzugten Sprache des Benutzers im Browser

  • Unterstützt mehrsprachige URL-Routen in einer einzigen Seitenkomponente. Das bedeutet, dass Sie keine separaten Seiten wie pages/en/index.js oder pages/ko/index.js erstellen müssen.

  • Wie einige von euch oben vorgeschlagen haben, bündelt es jetzt während der Build-Zeit nur die aktuelle Sprache.

Außerdem möchte ich erwähnen, dass viele der i18n-Beispiele / -Starter tatsächlich auf der Clientseite gerendert werden. Der beste Weg, um zu überprüfen, ob die App als SSR gerendert wird, besteht darin, den Quellcode anzuzeigen und zu überprüfen, ob die lokalisierten Texte vorhanden sind. Bitte überprüfen Sie diese Angelegenheit, wenn Sie Ihre Gatsby-Website für SEO internationalisieren.

Hey Leute, es ist fast ein Jahr her 😅

Ich habe vor kurzem das neue gatsby-Plugin gatsby-plugin-intl veröffentlicht , das Ihre gatsby-Website ganz einfach zu einem Internationalisierungs-Framework macht.

DEMO: https://gatsby-starter-default-intl.netlify.com

  • Out of box Internationalisierungs-Framework powered by react-intl
  • Unterstützt die automatische Weiterleitung basierend auf der bevorzugten Sprache des Benutzers im Browser
  • Unterstützt mehrsprachige URL-Routen in einer einzigen Seitenkomponente. Das bedeutet, dass Sie keine separaten Seiten wie pages/en/index.js oder pages/ko/index.js erstellen müssen.
  • Wie einige von euch oben vorgeschlagen haben, bündelt es jetzt während der Build-Zeit nur die aktuelle Sprache.

Außerdem möchte ich erwähnen, dass viele der i18n-Beispiele / -Starter tatsächlich auf der Clientseite gerendert werden. Der beste Weg, um zu überprüfen, ob die App als SSR gerendert wird, besteht darin, den Quellcode anzuzeigen und zu überprüfen, ob die lokalisierten Texte vorhanden sind. Bitte überprüfen Sie diese Angelegenheit, wenn Sie Ihre Gatsby-Website für SEO internationalisieren.

Hey @wiziple vielen Dank dafür, ich war verrückt, eine Lösung für die Lokalisierung von Gatsby zu finden.
Vielleicht habe ich den Punkt nicht verstanden, aber haben Sie ALLE Zeichenfolgen einer Sprache in nur einer Datei?
Wäre es möglich, den JSON jeder Sprache in mehrere Dateien aufzuteilen, möglicherweise unter Verwendung der gleichen Komponentenstruktur?

@cant89 Ich gatsby develop oder gatsby build .
Sobald Sie alle JSON-Dateien erhalten und als verschachteltes Objekt zusammengeführt haben, können Sie es auch als Flatten-Objekt konvertieren.
https://github.com/yahoo/react-intl/wiki/Upgrade-Guide#flatten -messages-object

Wir haben ein gutes Beispiel-Setup für i18n. https://github.com/gatsbyjs/gatsby/tree/master/examples/using-i18n. Wir haben keine wirkliche Meinung zu i18n-Frameworks. Wählen Sie einfach eine nach Ihrem Geschmack aus.

Wir haben ein gutes Beispiel-Setup für i18n. https://github.com/gatsbyjs/gatsby/tree/master/examples/using-i18n. Wir haben keine wirkliche Meinung zu i18n-Frameworks. Wählen Sie einfach eine nach Ihrem Geschmack aus.

Cool, danke, ich werde es versuchen!
Wie auch immer, der Link in der Readme ist defekt, wahrscheinlich meinst du https://using-i18n.netlify.com/ ?

@wardpeet Generiert Ihr Beispiel statisch übersetzte Zeichenfolgen (zur Build-Zeit)? Oder generiert es den Text zur Laufzeit?

@monsieurnebo sieht aus wie Bauzeit

@cant89 wir aktualisieren immer noch das DNS, daher ist es vorerst bald

@monsieurnebo es ist zur Bauzeit. Es erstellt eine Kopie Ihrer Website für jede Sprache, sodass alles statisch erstellt werden kann. Dies bedeutet, dass Ihre Website schnell bleibt, da alles nur eine HTML-Datei ist.

Ich bin mir nicht sicher, wo ich das sonst fragen soll, aber ein bisschen relevant. Unterstützt eines dieser Plugins Gatsbys pathPrefix ?

i.e. 
// gatsby-config.js

modules.exports = {
    pathPrefix: 'bar'
}

https://foo.com => https://foo.com/bar

but now my language locales will now be https://foo.com/bar/de-DE/
when I think I would prefer it be https://foo.com/de-DE/bar if that makes sense.

Hmm interessant, ich denke, ersteres ist normalerweise sinnvoller, da das pathPrefix Ihre Domain zu domain.com/prefix also das Root ändern, wenn Sie Gatsby in einem Unterverzeichnis installiert haben, wenn Sie es nicht installieren ein Unterverzeichnis, das Sie nicht benötigen, wenn Sie ein Unterverzeichnis verwenden, das das Präfix so ändert, dass es durch die Sprache unterbrochen wird.

Jetzt stellt sich die Frage, warum verwenden Sie überhaupt das pathPrefix ?

Ref: pathPrefix-Dokumente

Hallo,

Die meisten Diskussionen hier drehen sich darum, wie man eine Gatsby-Site i18n kann. Aber es gibt einen Unterschied zwischen einem funktionierenden POC und einem optimierten produktionsbereiten System.

Wenn Sie mehr über Code-Splitting und i18n-Dateien erfahren möchten und warum die meisten Lösungen in diesem Thread nicht optimiert sind, finden Sie dieses Problem hilfreich

War diese Seite hilfreich?
0 / 5 - 0 Bewertungen

Verwandte Themen

magicly picture magicly  ·  3Kommentare

theduke picture theduke  ·  3Kommentare

Oppenheimer1 picture Oppenheimer1  ·  3Kommentare

andykais picture andykais  ·  3Kommentare

jimfilippou picture jimfilippou  ·  3Kommentare