GithubHelp home page GithubHelp logo

wiziple / gatsby-plugin-intl Goto Github PK

View Code? Open in Web Editor NEW
323.0 8.0 178.0 8.01 MB

Gatsby plugin that turns your website into an internationalization-framework out of the box.

Home Page: http://gatsby-starter-default-intl.netlify.com

JavaScript 100.00%
gatsbyjs intl i18n localization gatsby-plugin gatsby-plugin-intl react-intl gatsby-starter seo

gatsby-plugin-intl's Introduction

gatsby-plugin-intl

Internationalize your Gatsby site.

Features

  • Turn your gatsby site into an internationalization-framework out of the box powered by react-intl.

  • Support automatic redirection based on the user's preferred language in browser provided by browser-lang.

  • Support multi-language url routes in a single page component. This means you don't have to create separate pages such as pages/en/index.js or pages/ko/index.js.

Why?

When you build multilingual sites, Google recommends using different URLs for each language version of a page rather than using cookies or browser settings to adjust the content language on the page. (read more)

Starters

Demo: http://gatsby-starter-default-intl.netlify.com

Source: https://github.com/wiziple/gatsby-plugin-intl/tree/master/examples/gatsby-starter-default-intl

Showcase

Feel free to send us PR to add your project.

How to use

Install package

npm install --save gatsby-plugin-intl

Add a plugin to your gatsby-config.js

// In your gatsby-config.js
plugins: [
  {
    resolve: `gatsby-plugin-intl`,
    options: {
      // language JSON resource path
      path: `${__dirname}/src/intl`,
      // supported language
      languages: [`en`, `ko`, `de`],
      // language file path
      defaultLanguage: `ko`,
      // option to redirect to `/ko` when connecting `/`
      redirect: true,
    },
  },
]

You'll also need to add language JSON resources to the project.

For example,

language resource file language
src/intl/en.json English
src/intl/ko.json Korean
src/intl/de.json German

Change your components

You can use injectIntl HOC on any react components including page components.

import React from "react"
import { injectIntl, Link, FormattedMessage } from "gatsby-plugin-intl"

const IndexPage = ({ intl }) => {
  return (
    <Layout>
      <SEO
        title={intl.formatMessage({ id: "title" })}
      />
      <Link to="/page-2/">
        {intl.formatMessage({ id: "go_page2" })}
        {/* OR <FormattedMessage id="go_page2" /> */}
      </Link>
    </Layout>
  )
}
export default injectIntl(IndexPage)

Or you can use the new useIntl hook.

import React from "react"
import { useIntl, Link, FormattedMessage } from "gatsby-plugin-intl"

const IndexPage = () => {
  const intl = useIntl()
  return (
    <Layout>
      <SEO
        title={intl.formatMessage({ id: "title" })}
      />
      <Link to="/page-2/">
        {intl.formatMessage({ id: "go_page2" })}
        {/* OR <FormattedMessage id="go_page2" /> */}
      </Link>
    </Layout>
  )
}
export default IndexPage

How It Works

Let's say you have two pages (index.js and page-2.js) in your pages directory. The plugin will create static pages for every language.

file English Korean German Default*
src/pages/index.js /en /ko /de /
src/pages/page-2.js /en/page-2 /ko/page-2 /de/page-2 /page-2

Default Pages and Redirection

If redirect option is true, / or /page-2 will be redirected to the user's preferred language router. e.g) /ko or /ko/page-2. Otherwise, the pages will render defaultLangugage language. You can also specify additional component to be rendered on redirection page by adding redirectComponent option.

Plugin Options

Option Type Description
path string language JSON resource path
languages string[] supported language keys
defaultLanguage string default language when visiting /page instead of ko/page
redirect boolean if the value is true, / or /page-2 will be redirected to the user's preferred language router. e.g) /ko or /ko/page-2. Otherwise, the pages will render defaultLangugage language.
redirectComponent string (optional) additional component file path to be rendered on with a redirection component for SEO.

Components

To make it easy to handle i18n with multi-language url routes, the plugin provides several components.

To use it, simply import it from gatsby-plugin-intl.

Component Type Description
Link component This is a wrapper around @gatsby’s Link component that adds useful enhancements for multi-language routes. All props are passed through to @gatsby’s Link component.
navigate function This is a wrapper around @gatsby’s navigate function that adds useful enhancements for multi-language routes. All options are passed through to @gatsby’s navigate function.
changeLocale function A function that replaces your locale. changeLocale(locale, to = null)
IntlContextConsumer component A context component to get plugin configuration on the component level.
injectIntl component https://github.com/yahoo/react-intl/wiki/API#injection-api
FormattedMessage component https://github.com/yahoo/react-intl/wiki/Components#string-formatting-components
and more... https://github.com/yahoo/react-intl/wiki/Components

License

MIT © Daewoong Moon

gatsby-plugin-intl's People

Contributors

0xshynn avatar angrypie avatar chrsep avatar dependabot[bot] avatar dianakhuang avatar dsoaress avatar emilkarl avatar fabianrios avatar fujikky avatar gandreadis avatar hoangbaovu avatar jhoffmcd avatar judithhartmann avatar kije avatar lejard-h avatar olegshilov avatar onestopjs avatar samajammin avatar shicholas avatar talensjr avatar theemattoliver avatar themattcode avatar wiziple avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

gatsby-plugin-intl's Issues

Loading translations dynamically from REST API

Here's what I'm trying to accomplish:

Rather than storing my translations in src/18n/locales/*.js, I need to get them from a third party REST API. I'm doing that via sourceNodes in /gatsby-node.js as per this example.

My difficulty is in getting the data from GraphQL to react-intl. Specifically, I can't manage to set messages in the withIntl component, since Gatsby only executes queries in page and layouts components and I was not able to export a fragment from withIntl that Gatsby could find.

I suspect that I cannot accomplish what I'm trying to do with this setup and will instead have to move some of the implementation in withIntl into a layout component that I can provide it with data from GraphQL.

However, before embarking down that road, I thought I'd see if anyone had a better idea.

Thanks very much @wiziple for the awesome starter.

Auto Redirection Option Breaks Client Only Routes

In the case where the plugin option for redirection is set to true, client-only routes for things like authenticated pages do not load, but instead, get redirected to the base route because the routed value comes back false for these client routes.

/en-us/account <--- routes properly
/en-us/account/profile <--- redirects back to the account page, preventing the account page client router from acting on the "profile" slug

Note I was only even able to get here after nullifying the 404 matchPaths that the plugin sets here. Match path sorting may be broken in the current release, see gatsbyjs/gatsby#16098

Value for intl.Locale is Incorrect on Build (SSR)

After the latest update, I noticed that on SSR builds yarn build the value for intl.locale is incorrect.

CodeSandbox
https://codesandbox.io/s/gatsby-starter-default-fx5gw?fontsize=14

The setup is I have two languages: [en-us, es-es]. The default language is set to en-us. Everything works as expected in development mode yarn develop. However, running yarn build and logging out the value of intl.locale from either useIntl or injectIntl shows that durring the SSR pass on the build, the value is incorrect.

Expected

intl.locale value is: en-us
intl.locale value is: es-es

Actual

intl.locale value is: en-us
intl.locale value is: en

It's worth noting that the new version of react-intl sets a defaultLocale if one is not created. See related PR #80

Different format for content possible?

It seems that content is split up based on language. My content team does not work this way at all, and would make it difficult to work with them on content and translations this way:

Rather then this (Please support yaml as well, please):

en:
  title: English words

vn:
  title: Vietnamese words

they prefer to work like this:

title:
  en: English words
  vn: Vietnamese words

...where the separation of concerns is based on the content, rather than the language.

It makes sense to me as well, being a react developer, since I don't separate html, css and js, but rather combine them together and make separations based on the idea of a component, rather than arbitrary languages.

I hope that makes sense, and that it might be possible to do so :-)

Any thoughts on this @wiziple? Do you think this is something that could be doable, or would it be really hard to impossible?

Does this plugin work with Gatsby-plugin-layout?

I am using gatsby-plugin-layout in my web app to avoid unnecessary re-loads and to give the user a better experience animated route transitions, etc. I am noticing that after installing gatsby-plugin-intl all my routes are now fully re-loading, breaking the experience.

Does this plugin not work with gatsby-plugin-layout?

Do I need to do anything special to make it work?

Huge bundle size

Hi, I tried to launch your gatsby-starter-default-intl demo with added gatsby-plugin-webpack-bundle-analyzer. Despite only languages: ['en', 'ko', 'de'], being enabled, all of the locales are bundled with the app (this adds quite a significant amount of extra bundle size):

image

Seeing error 'WebpackError: Cannot find react-intl/locale-data/en'

When running [email protected], [email protected], and [email protected], I'm seeing this error on both the development server and the static build.

I played around with versions and did not see this with [email protected].

I am also aware of the fact that there are still issues with [email protected], but this doesn't seem related.

  36 |   if (!localeData) {
> 37 |     throw new Error("Cannot find react-intl/locale-data/" + language);
     | ^
  38 |   }
  39 |
  40 |   _reactIntl.addLocaleData.apply(void 0, localeData);


  WebpackError: Cannot find react-intl/locale-data/en

  - wrap-page.js:37 addLocaleDataForGatsby
    node_modules/gatsby-plugin-intl/wrap-page.js:37:1

  - wrap-page.js:106 Object._default [as wrapPageElement]
    node_modules/gatsby-plugin-intl/wrap-page.js:106:1


  - gatsby-ssr.js:13 Module.replaceRenderer

gatsby-config.js

    {
      resolve: 'gatsby-plugin-intl',
      options: {
        // language JSON resource path
        path: `${__dirname}/src/i18n/messages`,
        // supported language
        languages: ['es'],
        defaultLanguage: 'en',
        // if true, redirect to `/en` when connecting `/`
        redirect: false,
      },
    },

Gatsby Info:


  System:
    OS: Linux 4.9 Debian GNU/Linux 9 (stretch) 9 (stretch)
    CPU: (6) x64 Intel(R) Core(TM) i7-8750H CPU @ 2.20GHz
    Shell: 4.4.12 - /bin/bash
  Binaries:
    Node: 10.15.3 - /usr/local/bin/node
    Yarn: 1.13.0 - /usr/local/bin/yarn
    npm: 6.4.1 - /usr/local/bin/npm
  Languages:
    Python: 2.7.13 - /usr/bin/python
  npmPackages:
    gatsby: 2.10.4 => 2.10.4
    gatsby-cli: ^2.4.15 => 2.7.2
    gatsby-image: ^2.0.33 => 2.2.3
    gatsby-link: ^2.0.16 => 2.2.0
    gatsby-node-helpers: ^0.3.0 => 0.3.0
    gatsby-plugin-intl: 0.2.4 => 0.2.4
    gatsby-plugin-netlify: ^2.0.12 => 2.1.0
    gatsby-plugin-netlify-cms: ^3.0.14 => 3.0.18
    gatsby-plugin-purgecss: ^4.0.0 => 4.0.0
    gatsby-plugin-react-axe: ^0.2.2 => 0.2.2
    gatsby-plugin-react-helmet: ^3.0.9 => 3.1.0
    gatsby-plugin-react-svg: ^2.1.1 => 2.1.1
    gatsby-plugin-sass: ^2.0.11 => 2.1.0
    gatsby-plugin-segment-js: ^3.0.1 => 3.0.1
    gatsby-plugin-sharp: ^2.0.28 => 2.2.1
    gatsby-plugin-web-font-loader: ^1.0.4 => 1.0.4
    gatsby-plugin-webpack-bundle-analyser-v2: ^1.1.0 => 1.1.1
    gatsby-source-filesystem: ^2.0.25 => 2.1.1
    gatsby-transformer-json: ^2.1.10 => 2.2.0
    gatsby-transformer-remark: ^2.3.3 => 2.5.0
  npmGlobalPackages:
    gatsby: 2.4.2

Support for YAML files

Hey there! This is a really nice gatsby plugin. Thank you! My team translated our entire site using it to support english and german.

Currently you are using JSON for the language files. I just tested the readability of our translation files as I converted them to YAML. I find that YAML seems very suited for this kind of content files.

Do you have any plan on supporting it as a second option?

Sources / GraphQL

This would be more useful if it was adapted to work with source plugins (e.g. gatsby-source-contentful) rather than relying on outdated, hardcoded translation files. It seems unrealistic that a majority of Gatsby websites would forgo GraphQL querying in order to support translations.

Build is blank

Hi, thank you for working on this, I have been using this to i18n a Gatbsy site. Everything works in the development server, but when I build, the page is blank.
Viewing the source shows some content but I don't understand why this is happening.

This happens building the gatsby-starter-default-intl in your example folder with no changes.

Splitting language files

Hey.

Is it possible to split language files? So instead of having en.json and de.json a structure like this:

intl
- de
-- index.json
-- services
--- index.json
--- react.json
--- ...
- en
-- index.json
-- services
--- index.json
--- react.json
--- ...

[enhancement] Add tag to next releases

Hi! First, congrats for your work, I use it and it works really well. I faced an issue to which I made a pull request just to later on realise someone else already did it, which is great!, but it is merged on the versions/0.2.7 branch and I need to use it now, so I installed your package referencing that specific branch.
It would be cool if you can just add a "next" label (or tag) to that branch, so we can just install it as yarn add gatsby-plugin-intl@next
Thanks!

Reload translations

I seem to have to gatsby clean && gatsby develop in order to get changes to my translation files (`*.json) to be picked up - is that expected, or am I doing it wrong?

Narrowing it down slightly, instead of gatsby clean I can do rm .cache/redux.state followed by a restart of gatsby develop

Proper links in language switcher

In the example starter, you have an anchor link without an href attribute in the language switcher.

const Language = () => {
  return (
    <div>
      <IntlContextConsumer>
        {({ languages, language: currentLocale }) =>
          languages.map(language => (
            <a
              key={language}
              onClick={() => changeLocale(language)}
            >
              {languageName[language]}
            </a>
          ))
        }
      </IntlContextConsumer>
    </div>
  )
}

This is problematic for a number of reasons, including accessibility and SEO, since there is no proper link to the other language version. How would I go about rewriting this to create a proper link (perhaps by using the Link component)?

Issue with automatic redirect

Hi, first of all thanks for this plugin, I like the fact that allows a single page pull data rather than one page for each language.

Overall it works very well, creating pages for each language, but I'm having issues with the automatic redirect, as always goes to the default language, although I can change it later.

I'm looking for an automatic, non changeable option where it only shows the language based on the browser language like:

<script>
      let language = window.navigator.language;
      if (language == "es") {
        window.location.href = "/es";
      }
      if (language == "en") {
        window.location.href = "/en";
      }
    </script>

As adding the previous snippet to the helmet causes a load loop, is there a way to achieve it?

Thanks!

Repo: https://github.com/lewislbr/lewis-llobera-photography-gatsby

HMR for Locale JSON Files

Doing some research on i18n for Gatsby and this so far has been the best plugin available. Thank you for this plugin!

Any chance that there will be an update to allow HMR for the locale files? For example changing a locale string in fr.json requires a restart of the gastbsy develop.

Suggestion: Make path to locale.json files optional

Dear @wiziple,

Would you consider making the language JSON resource path of the plugin optional?; for instance, I source the data, for each page, from markdown files; each .md file contains a title and metaDescription for each page.

This can be achieved by using injectIntl, graphql magic and component props that access the intl property.

What do you guys think?

Best,
Alexandros

Add type declarations

We are using typescript in our project. Can't import methods/components from gatsby-plugin-intl because it doesn't have a type declarations. Can you please add a type declarations?

Default route

Hi, thanks for sharing this starter.

I have been trying to add a default language route that goes to url.com/* rather than url.com/en/* etc
I managed to get it half working with some ternary expressions but I haven't been able to do it without breaking the language detection in the redirect.js file and I am a bit stumped. Where would be the best place to start with this?

Default route would be a great feature to implement.

how to handle reversed locale name (eg. us-en instead of en-us)

I have a use case where I need to revamp a landing page that was on wordpress to Gatsby which is well reference in Google and all but with a wrong locale name (site.com/us-en/some-route-url) instead of (site.com/en-us/some-route-url).

The issue is that in my config file if I do

    {
      resolve: `gatsby-plugin-intl`,
      options: {
        path: `${__dirname}/src/intl`,
        languages: [`us-en`, `ma-ar`],
        defaultLanguage: `us-en`,
        redirect: true,
      },
    },

it gives error of can't find locale "us-en" in react-inlt/locale-data. and when I just reverse it to

    languages: [`en-us`, `ar-ma`],

it works, but I need the first use case of us-en to work to maintain the SEO of the landing page, because changing this will ruin my SEO which I worked for, for years.

How can I achieve this with the plugin please ?

Allow translation of URLS

Hi @wiziple, thanks for this nice plugin. I was wondering if you plan to add url slug's translations too, which is a feature I haven't seen yet in the various gatsby i18n plugins.
So, to make it more clear, I mean if you plan to allow this:

en/about
it/chi-siamo (instead of it/about)

same page with two different slugs.
I guess is not easy to manage the link routing, but I think it's possible to build a sort of routes map during the createPages step and pass it to the pages inside the intl context. The link component can then use the to prop as a key that would match this routes map.
Some super pseudo code:

in src/pages/about/index.en.md

url: /about

in src/pages/about/index.it.md

url: /chi-siamo

Then we would have a routes map in page contexts like:

intl = {
  ...,
  routes: {
    'about': {
      en: '/about',
      it: '/chi-siamo'
    }
  }
}

And the Link component would do

intl => (
  Link = ({ to, ... }) => {
    const toRoute = intl.routes[to][intl.language]
  }

I am curious to see what you think of this approach or if you have any other idea in this regard.
Let me know if all this is a bit unclear!

Guide on how to switch languages?

I can't seem to figure out how to set up buttons to switch from one language to another. I tried to copy and paste the setup you have going on from the language.js file in the example, but it doesn't seem to be working at all in any way for me. It might be nice to add an example in the readme file on how to go about doing this for us new to the plugin.

Currently Doing this inside my persistent sidebar:

<Locales>
  <IntlContextConsumer>
    {({ languages, language: currentLocale }) =>
      languages.map(language => (
        <a
          key={language}
          onClick={() => changeLocale(language)}
        >
          {languageName[language]}
        </a>
       ))
     }
   </IntlContextConsumer>
 </Locales>

Thanks!

Link component error: "Cannot read property 'language' of undefined"

Hi!

I'm trying to use Link component from gatsby-plugin-intl and got an error:

  • The above error occurred in the <LocationProvider> component
  • Cannot read property 'language' of undefined

image

I cloned repo with example and everything works fine, but not in my project :(

Could it be a conflict with other libraries?

Thank you!

props.intl.formatMessage values not found

en.json: {'home.title': 'xxxx {br} xxxx',}

component:

import React from 'react';
import { injectIntl } from 'gatsby-plugin-intl';

const Home = ({ intl }) => {
  return (
    <div>{intl.formatMessage({ id: 'home_title' }, { br: <br /> })}</div>
  );
};

export default injectIntl(Home);

Expected behavior:

xxxx
xxxx

Current behavior:
xxxx [object Object] xxxx

[React Intl] Error formatting message: "home.title" for locale: "en"
Error: The intl string context variable 'br' was not provided to the string 'xxxx {br} xxxx'

accessing the intl object in graphql

right now intl is an object passed to context on the creating page loop
return { ...page, path: newPath, context: { ...page.context, intl: { language, languages, messages, routed, originalPath: page.path, redirect, }, }, }

so if I want to access it later on as part of the context is not possible unless we create some sort of intl Type for graphql that allow us to do so, something like this:

const Intl = new GraphQLObjectType({ name: 'Intl', fields: { language: { type: GraphQLString }, languages: { type: GraphQLList }, messages: { type: GraphQLString }, routed: { type: GraphQLString }, originalPath: { type: GraphQLString }, redirect: { type: GraphQLString }, } });

this will be usefull to create pages which can pull the language dynamically from graphql

HTML in json translation files

Hello!
Thank you for this great plugin, it helped me a lot!
Is there a way to use HTML in json translation? For example "message" : "hello <strong>awesome</strong> world" will be output like hello <strong>awesome</strong> world. And i want it to be like "hello awesome world". Is it possible to achieve?

SEO Improvements

Dear @wiziple,

As per Google, here, there are 3 ways to indicate the localization of the content of a page; for Gatsby, the Html Tag is used. However, when navigating to a localized page the html lang tag stays the same.

image

I can see that, the showcase page, krashna.nl has achieved this successfully; can this functionality be implemented as a showcase in the gatsby-starter-default-intl example?

Best,
Alexandros

TypeError: Cannot read property 'language' of undefined

(anonymous function)
node_modules/gatsby-plugin-intl/link.js:27

24 | onClick = _ref.onClick,
25 | rest = (0, _objectWithoutPropertiesLoose2.default)(_ref, ["to", "language", "children", "onClick"]);
26 | return _react.default.createElement(_intlContext.IntlContextConsumer, null, function (intl) {

27 | var languageLink = language || intl.language;
28 | var link = intl.routed || language ? "/" + languageLink + to : "" + to;
29 |
30 | var handleClick = function handleClick(e) {

Option to have defaultLanguage redirect to root

When I have a defaultLanguage set, I'd like an option to have that redirects all pages for that language to the root, instead of /<lang>. This applies mostly to <Link> and changeLocale()

E.g. I have en and is and is is the default language. If I call changeLocale('is') on /en/about I'd like to go to /about not /is/about.

gatsby link reloads page

Hi thanks for your help, using the lang switcher the page switch smoothly, but for the Links in my nav when clicking one the page seems to do a reload. Is there a way to change this?

This is an example of a link on my website:

<Link to="/"><img src={logo} width="145" height="39" className="img-fluid"/></Link>

switching languages seems to not stay on the same route and scroll position...

Hi Everybody,

In an app I'm working on I have two languages and buttons that switch between them. But what seems to be happening now is that when I switch languages the site redirects to the homepage and scrolls to top, rather than staying on the same page and keeping the same scroll position, which is the desired behavior.

Any ideas why this might be the case?

This is the code for my language switching buttons:

const Language = () => {
  return (
    <>
      <IntlContextConsumer>
        {({ languages, language: currentLocale }) =>
          languages.map(language => (
            <LocaleButton
              key={language}
              onClick={() => changeLocale(language)}
            >
              {languageName[language]}
            </LocaleButton>
          ))
        }
      </IntlContextConsumer>
    </>
  )
}

The <LocaleButton> is just a few basic visual styles.

Provide defaultLocale to IntlProvider

I'm pretty sure this was a side effect of the react-intl update. If you don't set a defaultLocale on the provider component, it defaults to en. This should probably default to what our config value for defaultLanguage otherwise it causes unexpected behavior if performing evaluations on intl.locale.

https://github.com/formatjs/react-intl/blob/master/src/utils.ts#L93

Expected: intl.defaultLocale matches the value set in our plugin config.
Actual: intl.defaultLocale defaults to en always.

Issue: Links using the `Link` component from this plugin do not reset scroll position for new route.

Hi @wiziple!

I am having this issue where links using the Link component from this plugin do not reset scroll position to the top of the next page, but rather persist the scroll position of the current page, which is breaking the usability of the app. I'm thinking it's this plugins Link component, because when I use the regular Gatsby Link component the new page resets scroll position upon the new route. I am also using gatsby-plugin-layout to achieve a single page application where the navigation and certain elements on the page do not reload, to allow for animated route transitions, and a smoother, better user experience. I do not know if maybe the combination of both plugins might be the issue, but in any case, if you have any thoughts as to why this might be happening, please share.

This is the repo, if you have the time or energy to take a look:

https://github.com/arrowgtp/alma

Anyway, thanks again :-)

Whenever I switch locale, I'm shown index.js

Description

Hello, I have used the plug in properly I believe (similar to the example given) however when I switch language I get redirected to the main page. For example if I am at localhost:8000/en/page-2 and I switch language to fr I got redirected to localhost:8000/fr/ instead of localhost:8000/fr/page-2

These are the most important files

//gatsby-config.js
module.exports = {
  siteMetadata: {
    title: `CcLàQ`,
    description: `Page officiel de la Chambre de commerce Latinoamèriquenne à Québec`,
    author: `@davidneios`,
    siteUrl: `https://cclaq.netlify.com/`,
  },
  plugins: [
    `gatsby-plugin-react-helmet`,
    {
      resolve: `gatsby-source-filesystem`,
      options: {
        name: `images`,
        path: `${__dirname}/src/images`,
      },
    },
    `gatsby-transformer-sharp`,
    `gatsby-plugin-sharp`,
    {
      resolve: `gatsby-plugin-manifest`,
      options: {
        name: `gatsby-starter-default`,
        short_name: `starter`,
        start_url: `/`,
        background_color: `#663399`,
        theme_color: `#663399`,
        display: `minimal-ui`,
        icon: `src/images/cclaq_logo.png`, // This path is relative to the root of the site.
      },
    },
    `gatsby-plugin-offline`,
    {
      resolve: `gatsby-plugin-intl`,
      options: {
        path: `${__dirname}/src/intl`,
        languages: [`en`, `es`, `fr`],
        defaultLanguage: `fr`,
        redirect: true,
      },
    },
    `gatsby-plugin-sitemap`,
    `gatsby-plugin-robots-txt`,
    // this (optional) plugin enables Progressive Web App + Offline functionality
    // To learn more, visit: https://gatsby.dev/offline
    // `gatsby-plugin-offline`,
  ],
}
// src/components/languageSwitcher.js
import React from "react"
import { Helmet } from "react-helmet"
import Dropdown from "react-bootstrap/Dropdown"

const languageNames = {
  en: "English",
  fr: "Francais",
  es: "Espanol",
}
const LanguageSwitcher = () => (
  <IntlContextConsumer>
    {({ languages, language: currentLocale }) => (
      <>
        <Helmet>
          <html lang={currentLocale} />
        </Helmet>
        <Dropdown>
          <Dropdown.Toggle variant="dark" id="dropdown-basic">
            langue
          </Dropdown.Toggle>
          <Dropdown.Menu>
            {languages.map(lng => (
              <Dropdown.Item
                key={lng}
                onSelect={() => {
                  changeLocale(lng)
                }}
                as="button"
              >
                {languageNames[lng]}
              </Dropdown.Item>
            ))}
          </Dropdown.Menu>
        </Dropdown>
      </>
    )}
  </IntlContextConsumer>
)

export default injectIntl(LanguageSwitcher)

CSS

For the css I am using Bootstrap

Live

You can see the project live here

I hope you can help, thanks!

Fails with IntlProvider error when using injectIntl wrapper method

Dear wiziple,

The plugin worked great up to the point where I wrapped all of my pages with withIntl(...). I was able to get the routing going and all, yet, when I use the injectIntl(...) method around my class components and some of my ES6 functional components it breaks.

The following error is given:

[React Intl] Could not find required intl object. <IntlProvider> needs to exist in the component ancestry.

Any ideas?

Best,
Alexandros

The run is blocked during the createPagesStatefully

When I add the plug-in run gatsby develop is blocked at this stage createPagesStatefully.Finally, throw Allocation failed

> gatsby develop

success open and validate gatsby-configs - 0.024 s
success load plugins - 0.460 s
success onPreInit - 0.024 s
success initialize cache - 0.516 s
success copy gatsby files - 2.455 s
success onPreBootstrap - 0.067 s
success source and transform nodes - 0.072 s
success building schema - 1.529 s
success createPages - 0.005 s
⠙ createPagesStatefully

<--- Last few GCs --->

[19280:000002901D5C17D0]   343097 ms: Scavenge 1305.9 (1423.7) -> 1305.1 (1424.2) MB, 4.5 / 0.0 ms  (average mu = 0.284, curre
nt mu = 0.248) allocation failure
[19280:000002901D5C17D0]   343104 ms: Scavenge 1306.3 (1424.9) -> 1305.9 (1425.4) MB, 3.7 / 0.0 ms  (average mu = 0.284, curre
nt mu = 0.248) allocation failure
[19280:000002901D5C17D0]   343117 ms: Scavenge 1306.7 (1425.4) -> 1306.0 (1425.9) MB, 4.6 / 0.0 ms  (average mu = 0.284, curre
nt mu = 0.248) allocation failure


<--- JS stacktrace --->

==== JS stack trace =========================================

    0: ExitFrame [pc: 000000229A05C5C1]
Security context: 0x03efa411e6e1 <JSObject>
    1: map [000003EFA4106E59](this=0x002bd8606059 <JSArray[49144]>,0x002bd8606079 <JSFunction (sfi = 000002BAE60D19D1)>)
    2: /* anonymous */(aka /* anonymous */) [000001A856FA8849] [C:\Users\yeming\Desktop\work\madecare-website\node_modules\gat
sby\dist\redux\index.js:~72] [pc=000000229A3594C5](this=0x03c6fd8826f1 <undefined>)
    3: _callee$(aka _callee...

FATAL ERROR: Ineffective mark-compacts near heap limit Allocation failed - JavaScript heap out of memory
 1: 00007FF74DADECE5
 2: 00007FF74DAB8196
 3: 00007FF74DAB8BA0
 4: 00007FF74DD48D5E
 5: 00007FF74DD48C8F
 6: 00007FF74E2869D4
 7: 00007FF74E27D137
 8: 00007FF74E27B6AC
 9: 00007FF74E284627
10: 00007FF74E2846A6
11: 00007FF74DE27767
12: 00007FF74DEBF44A
13: 000000229A05C5C1
npm ERR! code ELIFECYCLE
npm ERR! errno 134
npm ERR! [email protected] develop: `gatsby develop`
npm ERR! Exit status 134
npm ERR!
npm ERR! Failed at the [email protected] develop script.
npm ERR! This is probably not a problem with npm. There is likely additional logging output above.

npm ERR! A complete log of this run can be found in:
npm ERR!     C:\Users\yeming\AppData\Roaming\npm-cache\_logs\2019-07-01T04_59_34_996Z-debug.log
error Command failed with exit code 134.
info Visit https://yarnpkg.com/en/docs/cli/run for documentation about this command.

gatsby-config.js

module.exports = {
  /* Your site config here */
  plugins:[
    'gatsby-plugin-sass',
    'gatsby-plugin-layout',
    {
      resolve:'gatsby-plugin-intl',
      options:{
        path:`${__dirname}/src/intl`,
        languages:['en','zh'],
        defaultLanguage:'zh',
      }
    }
  ]
}

package.json

{
  "name": "gatsby-starter-hello-world",
  "private": true,
  "description": "A simplified bare-bones starter for Gatsby",
  "version": "0.1.0",
  "license": "MIT",
  "scripts": {
    "build": "gatsby build",
    "develop": "gatsby develop",
    "format": "prettier --write src/**/*.{js,jsx}",
    "start": "npm run develop",
    "serve": "gatsby serve",
    "test": "echo \"Write tests! -> https://gatsby.dev/unit-testing\""
  },
  "dependencies": {
    "gatsby": "^2.10.4",
    "gatsby-plugin-intl": "^0.2.0",
    "react": "^16.8.6",
    "react-dom": "^16.8.6"
  },
  "devDependencies": {
    "@babel/plugin-proposal-decorators": "^7.4.4",
    "babel-preset-gatsby": "^0.2.0",
    "gatsby-plugin-layout": "^1.1.0",
    "gatsby-plugin-react-css-modules": "^2.1.0",
    "gatsby-plugin-sass": "^2.1.0",
    "node-sass": "^4.12.0",
    "prettier": "^1.18.2",
    "sass-loader": "^7.1.0"
  },
  "repository": {
    "type": "git",
    "url": "https://github.com/gatsbyjs/gatsby-starter-hello-world"
  },
  "bugs": {
    "url": "https://github.com/gatsbyjs/gatsby/issues"
  }
}

gatsby-node.js

const replacePath = path => (path === `/` ? path.toLowerCase() : path.replace(/\/$/, ``).toLowerCase())

// Implement the Gatsby API “onCreatePage”. This is
// called after every page is created.
exports.onCreatePage = ({ page, actions }) => {
  const { createPage, deletePage } = actions

  const oldPage = Object.assign({}, page);
  // Remove trailing slash unless page is /
  page.path = replacePath(page.path);
  //是否生成新页面
  let createNews = false;
  if (page.path !== oldPage.path) {
    // Replace new page with old page
    deletePage(oldPage);
    createNews = true;
  }
  //设置不一样的状态
  if (page.path.match(/solution/)) {
    page.context.layout = 'solution';
    createNews = true;
  }
  createNews && createPage(page);
}

gatsby v2.0 migration

Hello,
are there any plans for migration to Gatsby v2.0?

I am trying to get it to work, but I am having some problems regarding context (since it was deprecated in react and it should use ContextProvider now instead)

createPages according to the translation set in the CMS

Hey.

I have gatsby-plugin-intl along with gatsby-sourcre-directus7, which already comes with a translation interface for dynamic content.

Now the problem is, that when doing createPages for a single blog post, I would end up having the same URLs.

Example:

  1. Post 1 has a custom slug in the translations
  2. When starting up createPages will be executed
  3. URLs will be generated as followed: /blog/10-tips-to-manage-your-finances /blog/10-tipps-wie-sie-ihre-finanzen-verwalten
  4. Visit the page and go to /en/blog/10-tips-to-manage-your-finances
  5. Visit the page and go to /de/blog/10-tips-to-manage-your-finances
  6. Both end up having the same results and not the translated slug

My gatsby-node.js file looks as followed:

const path = require('path')

exports.createPages = async ({ actions, graphql }) => {
  const { createPage } = actions

  // GET Posts and create URL
  try {
    const result = await graphql(`
      {
        allDirectusArticle {
          edges {
            node {
              translations {
                article {
                  directusId
                }
                language
                title
                slug
              }
            }
          }
        }
      }
    `)

    result.data.allDirectusArticle.edges.map(({ node }) => {
      node.translations.map(a => {
        try {
          const url = `blog/${a.slug}`

          createPage({
            path: url,
            component: path.resolve('src/templates/blog/post.js'),
            context: {
              id: a.article.directusId,
            },
          })

          console.log(`Generated url '${a.title}' to path '/${url}'`)
        } catch (error) {
          console.error(`Failed to generate url: ${error}`)
        }
      })
    })
  } catch (error) {
    console.error(`GraphQL query returned error: ${error}`)
  }
}

The JSON returned from the above GraphQL request:

{
  "data": {
    "allDirectusArticle": {
      "edges": [
        {
          "node": {
            "translations": [
              {
                "title": "10 tips to manage your finances",
                "slug": "10-tips-to-manage-your-finances",
                "language": "en",
                "article": {
                  "directusId": 1
                }
              },
              {
                "title": "10 Tipps, wie Sie Ihre Finanzen verwalten können",
                "slug": "10-tipps-wie-sie-ihre-finanzen-verwalten-konnen",
                "language": "de",
                "article": {
                  "directusId": 1
                }
              }
            ]
          }
        },
        {
          "node": {
            "translations": [
              {
                "title": "Non modo carum sibi quemque, verum etiam vehementer carum esse?",
                "slug": "non-modo-carum-sibi-quemque-verum-etiam-vehementer-carum-esse",
                "language": "en",
                "article": {
                  "directusId": 2
                }
              }
            ]
          }
        }
      ]
    }
  }
}

I already did try to add ${a.language} to the url, but this resulted in having /en/en/ or /de/de/. Is there something I'm missing out here?

Contentful content.

How does one use this plugin while having all contents stored in a contentful CMS? How will it be possible to query the preferred locale based on the user's language selection?

md/mdx multilingual blog support?

Got the plugin working on my site for the most part XD

The last issue I'm having is figuring out how to use the plugin for the blog/news section of the site, in which the posts are written in MDX and are multilingual as well.

Any thoughts on how to do this with the plugin?

Thank you @wiziple XD

Handle possible missing forward slash in url in `changeLocale`

To ensure language changes work when the url does not contain for forward slash, would it be possible to add a check such as this (seems there is a TODO for this):

 if (allSitePage.includes(link) || allSitePage.includes(`${link}/`)) {
    gatsbyNavigate(link)
  } else {
    gatsbyNavigate(`/${language}/`)
  }

If you are just starting out with this this plugin it can be a bit of a head-scratcher at first why language changes do not work as intended.

Is it possible to generate independent separate builds for different locales?

This is not an issue but a question. It's the first time I am using Gatsby and this plugin gatsby-plugin-intl. My site consists of only static pages and I am using the config to support two locales en and ja.

My requirement is to generate separate builds and host them on separate domains. For example ja.example.com should serve the Japanese site and en.example.com should serve the English site. Is it possible to tweak the build process of Gatsby to generate independent builds for both?

Like instead of public directory, I want to generate two separate directories, public-en and public-ja and then use those builds for my deployment.

[bug]: gatsby-plugin-intl and gatsby-plugin-remote-trailing-slashes do not play together nicely

Description

Both slash stripper and internationalization plugins need to mash up so as to meet both common SEO and multilingual requirements. The ordering of the plugins in this case is important. If trailing slashes is first the browser URL is more correct but SEO is potentially dinged.

For best results, internationalization should follow stripper. Did not realize that the plugins were order sensitive in gatsby-config.js. As long as the URL has at least two levels, this is fairly close but may still have the trailing slash.

Steps to reproduce

  1. Begin with the "my-blog-starter"
gatsby new my-blog-starter https://github.com/gatsbyjs/gatsby-starter-blog
cd my-blog-starter
  1. Install the "gatsby-plugin-remote-trailing-slashes"
npm install --require gatsby-plugin-remove-trailing-slashes
  1. Update gatsby-config.js
'gatsby-plugin-remove-trailing-slashes',
{
      resolve: `gatsby-plugin-intl`,
      options: {
        // language JSON resource path
        path: `${__dirname}/src/intl`,
        // supported language
        languages: [`en`, `ko`, `de`],
        // language file path
        defaultLanguage: `en`,
        // option to redirect to `/en` when connecting `/`
        redirect: true,
      },
  1. Add translation files de.json, en.json, and ko.json to src/intl directory taking from these file at the following URL:
https://github.com/wiziple/gatsby-plugin-intl/tree/master/examples/gatsby-starter-default-intl/src/intl.
  1. Update the main project's index.js file as follows to include international text:
import React from "react"
// TKTKTK
// import { Link, graphql } from "gatsby"
import { graphql } from "gatsby"
import { FormattedMessage, Link, injectIntl } from "gatsby-plugin-intl"

import Bio from "../components/bio"
import Layout from "../components/layout"
import SEO from "../components/seo"
import { rhythm } from "../utils/typography"

class BlogIndex extends React.Component {
  render() {
    const { data } = this.props
    const siteTitle = data.site.siteMetadata.title
    const posts = data.allMarkdownRemark.edges

    // TKTKTK
    const intl = this.props.intl
    const intlTitle = intl.formatMessage({ id: "welcome" });

    return (
      <Layout location={this.props.location} title={siteTitle}>
        <SEO title="All posts" />

        <h1>{intlTitle}</h1>
        <h1><FormattedMessage id="title" /></h1>
        <h1><FormattedMessage id="hello" /></h1>

        <Bio />
        {posts.map(({ node }) => {
          const title = node.frontmatter.title || node.fields.slug
          return (
            <div key={node.fields.slug}>
              <h3
                style={{
                  marginBottom: rhythm(1 / 4),
                }}
              >
                <Link style={{ boxShadow: `none` }} to={node.fields.slug}>
                  {title}
                </Link>
              </h3>
              <small>{node.frontmatter.date}</small>
              <p
                dangerouslySetInnerHTML={{
                  __html: node.frontmatter.description || node.excerpt,
                }}
              />
            </div>
          )
        })}
      </Layout>
    )
  }
}

// TKTKTK
// export default BlogIndex
export default injectIntl(BlogIndex)

export const pageQuery = graphql`
  query {
    site {
      siteMetadata {
        title
      }
    }
    allMarkdownRemark(sort: { fields: [frontmatter___date], order: DESC }) {
      edges {
        node {
          excerpt
          fields {
            slug
          }
          frontmatter {
            date(formatString: "MMMM DD, YYYY")
            title
            description
          }
        }
      }
    }
  }
`
  1. Update the main project's blog-post.js file as follows to include international text:
import React from "react"
// TKTKTK
// import { Link, graphql } from "gatsby"
import { graphql } from "gatsby"
import { FormattedMessage, Link, injectIntl } from "gatsby-plugin-intl"

import Bio from "../components/bio"
import Layout from "../components/layout"
import SEO from "../components/seo"
import { rhythm, scale } from "../utils/typography"

class BlogPostTemplate extends React.Component {
  render() {
    const post = this.props.data.markdownRemark
    const siteTitle = this.props.data.site.siteMetadata.title
    const { previous, next } = this.props.pageContext

    // TKTKTK
    const intl = this.props.intl
    const intlTitle = intl.formatMessage({ id: "welcome" });
    // const intlTitle = 'fubar'

    return (
      <Layout location={this.props.location} title={siteTitle}>
        <SEO
          title={post.frontmatter.title}
          description={post.frontmatter.description || post.excerpt}
        />

        <h1>{intlTitle}</h1>
        <h1><FormattedMessage id="title" /></h1>
        <h1><FormattedMessage id="hello" /></h1>

        <h1>{post.frontmatter.title}</h1>
        <p
          style={{
            ...scale(-1 / 5),
            display: `block`,
            marginBottom: rhythm(1),
            marginTop: rhythm(-1),
          }}
        >
          {post.frontmatter.date}
        </p>
        <div dangerouslySetInnerHTML={{ __html: post.html }} />
        <hr
          style={{
            marginBottom: rhythm(1),
          }}
        />
        <Bio />

        <ul
          style={{
            display: `flex`,
            flexWrap: `wrap`,
            justifyContent: `space-between`,
            listStyle: `none`,
            padding: 0,
          }}
        >
          <li>
            {previous && (
              <Link to={previous.fields.slug} rel="prev">{previous.frontmatter.title}
              </Link>
            )}
          </li>
          <li>
            {next && (
              <Link to={next.fields.slug} rel="next">
                {next.frontmatter.title}</Link>
            )}
          </li>
        </ul>
      </Layout>
    )
  }
}

// TKTKTK
// export default BlogPostTemplate
export default injectIntl(BlogPostTemplate)

export const pageQuery = graphql`
  query BlogPostBySlug($slug: String!) {
    site {
      siteMetadata {
        title
        author
      }
    }
    markdownRemark(fields: { slug: { eq: $slug } }) {
      id
      excerpt(pruneLength: 160)
      html
      frontmatter {
        title
        date(formatString: "MMMM DD, YYYY")
        description
      }
    }
  }
`
  1. From the main project directory, execute the following command to start Gatsby:
clear && rm -rf .cache public &&  gatsby develop

Expected and Actual result

When order in gatsby-config.js:

  1. gatsby-plugin-intl
  2. gatsby-plugin-remove-trailing-slashes

http://localhost ==>
http://localhost/en/ ==>
Actual: http://localhost/en/en/ with English text
Expected: http://localhost/en with English text

http://localhost/ ==>
http://localhost/en/ ==>
Actual: http://localhost/en/en/ with English text
Expected: http://localhost/en with English text

http://localhost/de ==>
Actual: http://localhost/en/de with English text
Expected: http://localhost/de with German text

http://localhost/de/ ==>
Actual: http://localhost/en/de/ with English text
Expected: http://localhost/de with German text

http://localhost/my-second-post ==>
Actual: http://localhost/en/en/my-second-post with English text
Expected: http://localhost/en/my-second-post English text

http://localhost/my-second-post/ ==>
Actual: http://localhost/en/en/my-second-post/ with English text
Expected: http://localhost/en/my-second-post with English text

http://localhost/de/my-second-post ==>
Actual: http://localhost/en/de/my-second-post with English text
Expected: http://localhost/de/my-second-post with German text

http://localhost/de/my-second-post/ ==>
Actual: http://localhost/en/de/my-second-post/ with English text
Expected: http://localhost/de/my-second-post with German text

When order in gatsby-config.js:

  1. gatsby-plugin-remove-trailing-slashes
  2. gatsby-plugin-intl

http://localhost ==>
http://localhost/en/ ==>
Actual: http://localhost/en/en/ with English text
Expected: http://localhost/en with English text

http://localhost/ ==>
http://localhost/en/ ==>
Actual: http://localhost/en/en/ with English text
Expected: http://localhost/en with English text

http://localhost/de ==>
Actual: http://localhost/en/de with English text
Expected: http://localhost/de with German text

http://localhost/de/ ==>
Actual: http://localhost/en/de/ with English text
Expected: http://localhost/de with German text

http://localhost/my-second-post ==>
Actual: http://localhost/en/my-second-post with English text
Expected: Successful URL with English text

http://localhost/my-second-post/ ==>
Actual: http://localhost/en/my-second-post/ with English text
Expected: http://localhost/en/my-second-post with English text

http://localhost/de/my-second-post ==>
Actual: http://localhost/de/my-second-post with German text
Expected: Successful URL with German text

http://localhost/de/my-second-post/ ==>
Actual: http://localhost/de/my-second-post/ with German text
Expected: http://localhost/de/my-second-post with German text

Only gatsby-plugin-intl enabled in gatsby-config.js:

http://localhost ==>
Actual: http://localhost/en/ with English text
Expected: Successful URL with English text

http://localhost/ ==>
Actual: http://localhost/en/ with English text
Expected: Successful URL with English text

http://localhost/de ==>
Actual: http://localhost/de with German text
Expected: Successful URL with German text

http://localhost/de/ ==>
Actual: http://localhost/de/ with German text
Expected: Successful URL with German text

http://localhost/my-second-post ==>
Actual: http://localhost/en/my-second-post with English text
Expected: Successful URL with English text

http://localhost/my-second-post/ ==>
Actual: http://localhost/en/my-second-post/ with English text
Expected: Successful URL with English text

http://localhost/de/my-second-post ==>
Actual: http://localhost/de/my-second-post with German text
Expected: Successful URL with German text

http://localhost/de/my-second-post/ ==>
Actual: http://localhost/de/my-second-post/ with German text
Expected: Successful URL with German text

Errata

Maybe these two plugins would benefit from being combined together. The addition of the stripping slashes feature into international would seem pretty straight forward and might result in better performance.

Tomorrow, I plan to run the tests with just international. I will update with my findings. Updated.

Environment

System:
OS: macOS 10.14.5
CPU: (8) x64 Intel(R) Core(TM) i7-7920HQ CPU @ 3.10GHz
Shell: 5.0.2 - /usr/local/bin/bash
Binaries:
Node: 10.15.2 - /usr/local/bin/node
Yarn: 1.15.2 - ~/.yarn/bin/yarn
npm: 6.9.0 - /usr/local/bin/npm
Languages:
Python: 2.7.10 - /usr/bin/python
Browsers:
Chrome: 74.0.3729.169
Safari: 12.1.1
npmPackages:
gatsby: ^2.7.5 => 2.7.5
gatsby-image: ^2.1.2 => 2.1.2
gatsby-plugin-feed: ^2.2.1 => 2.2.1
gatsby-plugin-google-analytics: ^2.0.20 => 2.0.20
gatsby-plugin-intl: ^0.1.7 => 0.1.7
gatsby-plugin-manifest: ^2.1.1 => 2.1.1
gatsby-plugin-offline: ^2.1.1 => 2.1.1
gatsby-plugin-react-helmet: ^3.0.12 => 3.0.12
gatsby-plugin-remove-trailing-slashes: ^2.0.11 => 2.0.11
gatsby-plugin-sharp: ^2.1.2 => 2.1.2
gatsby-plugin-typography: ^2.2.13 => 2.2.13
gatsby-remark-copy-linked-files: ^2.0.13 => 2.0.13
gatsby-remark-images: ^3.0.14 => 3.0.14
gatsby-remark-prismjs: ^3.2.9 => 3.2.9
gatsby-remark-responsive-iframe: ^2.1.1 => 2.1.1
gatsby-remark-smartypants: ^2.0.9 => 2.0.9
gatsby-source-filesystem: ^2.0.37 => 2.0.37
gatsby-transformer-remark: ^2.3.12 => 2.3.12
gatsby-transformer-sharp: ^2.1.20 => 2.1.20
npmGlobalPackages:
gatsby-cli: 2.6.3

AdvThanksance!!!

Missing message even tho it's defined

Somehow the plugin is not able to find the messages defined.

I have the following setup.

gatsby-config.js

module.exports = {
  siteMetadata: {
    title: `XXX`,
    description: `XXX`,
    author: `XXX`,
  },
  plugins: [
    `gatsby-plugin-flow`,
    `gatsby-plugin-react-helmet`,
    `gatsby-plugin-styled-components`,
    {
      resolve: `gatsby-source-filesystem`,
      options: {
        name: `images`,
        path: `${__dirname}/src/assets`,
      },
    },
    `gatsby-transformer-sharp`,
    `gatsby-plugin-sharp`,
    {
      resolve: `gatsby-plugin-manifest`,
      options: {
        name: `gatsby-starter-default`,
        short_name: `starter`,
        start_url: `/`,
        background_color: `#663399`,
        theme_color: `#663399`,
        display: `minimal-ui`,
      },
    },
    {
      resolve: `gatsby-plugin-module-resolver`,
      options: {
        root: `./src`,
        aliases: {
          components: `./components`,
          constants: `./constants`,
          i18n: `./i18n`,
          pages: `./pages`,
          utils: `./utils`,
          assets: `./assets`,
          static: {
            root: `./public`,
            alias: `./static`,
          },
        },
      },
    },
    {
      resolve: `gatsby-plugin-intl`,
      options: {
        path: `${__dirname}/src/i18n`,
        languages: [`en`, `de`],
        defaultLanguage: `en`,
        redirect: true,
      },
    },
  ],
}

i18n/en.json

{
  "navigation": {
    "sprints": "Sprints & Processes",
    "company": "Company",
    "learning": "Blog"
  }
}

i18n/de.json

{
  "navigation": {
    "sprints": "Sprints & Prozesse",
    "company": "Unternehmen",
    "learning": "Blog"
  }
}

When using the FormattedMessage component like so <FormattedMessage id={navigation.${item.title}} /> I get the following error in the console back:

10:41:58.156
[React Intl] Missing message: "navigation.sprints" for locale: "en"

10:41:58.157
[React Intl] Cannot format message: "navigation.sprints", using message id as fallback.

10:41:58.160
[React Intl] Missing message: "navigation.company" for locale: "en"

10:41:58.160
[React Intl] Cannot format message: "navigation.company", using message id as fallback.

10:41:58.164
[React Intl] Missing message: "navigation.learning" for locale: "en"

10:41:58.164
[React Intl] Cannot format message: "navigation.learning", using message id as fallback.

injectIntl is being used on the component that renders the Navigation. Full code example of components/Navigation:

// @flow
import React from 'react'
import { Container } from 'styled-bootstrap-grid'
import { injectIntl, FormattedMessage } from 'gatsby-plugin-intl'

import ITEMS from 'constants/menu'

import {
  Wrapper,
  Item,
  Link,
  SubMenu,
  SubMenuFooter,
  SubMenuLink,
  Product,
  ProductLogo,
  ProductContent,
  MobileProduct,
  MobileProductLogo,
  MobileProductContent,
  Toggle,
  MobileWrapper,
  MobileContent,
  MobileItem,
  MobileFooter,
  MobileFooterLink,
} from './styles'

const Navigation = ({ intl }) => (
  <Wrapper>
    {ITEMS.map((item, index) => (
      <Item key={index.toString()}>
        <Link to={item.link} activeClassName="active">
          <FormattedMessage id={`navigation.${item.title}`} />
        </Link>
      </Item>
    ))}
  </Wrapper>
)

export default injectIntl(Navigation)

Any ideas on what's causing this issue?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.