Closed onokje closed 5 years ago
@onokje i've picked up on your issue and first and foremost sorry for the late response.
From my testing i think i have a solution for you.
Below are the steps i took:
babel-preset-gatsby
, react-intl
and babel-plugin-react-intl
.babelrc
with the following content:
{
"presets": ["babel-preset-gatsby"],
"plugins": [
["react-intl", {
"messagesDir": "./dataintl/messages/"
}],
],
}
- Created a folder called `constants` and inside my locales file with the following content:
```javascript
module.exports = {
en: {
path: "en",
locale: "English",
default: true,
},
pt: {
path: "pt",
locale: "Português",
},
it: {
path: "it",
locale: "Italian",
},
}
i18n
with files for the languages above. I'm going to post only the contents of the en.json
for brevity purposes:
{
"siteTitle": "i18n with Gatsby",
"hi": "Hi!",
"welcome": "Welcome to our site.",
"about": "About us",
"aboutCopy": "This page is about us.",
"backToHomepage": "Back to the homepage"
}
src
folder i created a components
folder and inside the following components:Header.js
with the following content:
import React from "react"
import { Link } from "gatsby"
import { injectIntl, intlShape, FormattedMessage } from "react-intl"
import LocalizedLink from "./LocalizedLink"
import locales from "../constants/locales"
const Header = ({ intl: { locale } }) => (
)
export default injectIntl(Header)
- `Layout.js` with the following content:
```javascript
import React, { Fragment } 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"
import itData from "react-intl/locale-data/it"
// Messages
import en from "../i18n/en.json"
import pt from "../i18n/pt.json"
import it from '../i18n/it.json'
// Components
import Header from "./Header"
const messages = { en, pt, it }
addLocaleData([...enData, ...ptData, ...itData])
const Layout = ({ locale, children }) => (
<IntlProvider locale={locale} messages={messages[locale]}>
<Fragment>
<Header />
<div>{children}</div>
</Fragment>
</IntlProvider>
)
export default Layout
LocalizedLink.js
with the following content:
import React from "react"
import { Link } from "gatsby"
import { injectIntl, intlShape } from "react-intl"
import locales from "../constants/locales"
const LocalizedLink = ({ to, intl: { locale }, ...props }) => {
const path = locales[locale].default ? to : /${locale}${to}
return <Link {...props} to={path} /> }
export default injectIntl(LocalizedLink)
- Inside the pages folder i changed `index.js` to the following:
```javascript
import React from "react"
import { FormattedMessage } from "react-intl"
import Layout from "../components/Layout"
import LocalizedLink from "../components/LocalizedLink"
export default ({ pageContext: { locale } }) => (
<Layout locale={locale}>
<h1>
<FormattedMessage id="hi" />
</h1>
<p>
<FormattedMessage id="welcome" />
</p>
<LocalizedLink to="/about/">
<FormattedMessage id="about" />
</LocalizedLink>
</Layout>
)
about.js
, just for testing purposes with the following content:
import React from "react"
import { FormattedMessage } from "react-intl"
import Layout from "../components/Layout"
import LocalizedLink from "../components/LocalizedLink"
export default ({ pageContext: { locale } }) => (
)
- Modified `gatsby-node.js` to the following:
```javascript
const locales = require('./src/constants/locales')
exports.onCreatePage = ({ page, actions }) => {
const { createPage, deletePage } = actions
deletePage(page)
Object.keys(locales).map(lang => {
const localizedPath = locales[lang].default
? page.path
: locales[lang].path + page.path
createPage({
...page,
path: localizedPath,
context: {
locale: lang
}
})
})
gatsby develop
the build goes through and if open http://localhost:8000
and fiddle with the site internacionalization works as it should. But here's the "kicker" (pardon the bad pun), no folder build
. So i thought, ok, let me create the folder structure and see if it works, same result.
Thought ok, something might be off here. Cleaned the build with gatsby clean
and re-issued. This time i checked if something was added in .cache/babelState.json
, but nothing, the file contents was as nothing is there, only the preset was loaded and no plugins were added, gatsby-node.js
once again to "inject" the plugin from .babelrc
with the following content:
exports.onCreateBabelConfig=({actions})=>{
actions.setBabelPlugin(
{
name:`react-intl`,
options:{
messagesDir:`./build/messages/`
}
}
)
}
gatsby clean
to clean the build data and the gatsby develop
, i got a build error. I thought ok, Gatsby doesn't like that setup, so i modified it to the actual babel-plugin-react-intl
, this time no build error, the babel plugin was added, but once again no folders were created.public
folder, same result..babelrc
file not being correctly handled and more like the way that babel 7 like works.
const presets=["babel-preset-gatsby"]
const plugins=[
["react-intl", {
"messagesDir": `${__dirname}/build/messages/`
}]
]
module.exports={presets,plugins}
- Issued once more `gatsby clean && gatsby develop`, same result.
- Removed the file and moved the configuration to inside `package.json`, same result, nothing was being extracted. and no folders
- Took it even further, went back to my original setup with the `.babelrc` added `@babel-cli` and `@babel-core`, created a new script in the `package.json` with the following instructuctions:
```json
"extract-messages": "set NODE_ENV=test&& babel ./src --out-dir lib",
Ran it and now i'm presented with the following:
/dataintl/messages/src/components/Header.json
i have the following:[
{
"id": "siteTitle",
"defaultMessage": "Because it is sunny!"
}
]
The content was extracted and the messages i have were added. Key thing to take from this, a lib
folder will be created and that can be deleted, as it's basically Gatsby does "under the hood" to the components. Also add something to the defaultValues
prop or nothing will be generated.
Feel free to provide feedback, so that we can close this issue, or continue to work on it till we have a solution for you.
Thank you for taking the time to write this essay, i really appreciate it ;)
After i tried your steps, it still didn't work for me at first, until i took a good look at our code, it turns out that we didn't use defaultMessage anywhere. That is the reason I didn't get any output, but it works now.
@onopko81 no need to thank, glad i was able to help you solve your issue.
Hiya!
This issue has gone quiet. Spooky quiet. 👻
We get a lot of issues, so we currently close issues after 30 days of inactivity. It’s been at least 20 days since the last update here.
If we missed this issue or if you want to keep it open, please reply here. You can also add the label "not stale" to keep this issue open!
As a friendly reminder: the best way to see this issue, or any other, fixed is to open a Pull Request. Check out gatsby.dev/contributefor more information about opening PRs, triaging issues, and contributing!
Thanks for being a part of the Gatsby community! 💪💜
Hey again!
It’s been 30 days since anything happened on this issue, so our friendly neighborhood robot (that’s me!) is going to close it.
Please keep in mind that I’m only a robot, so if I’ve closed this issue in error, I’m HUMAN_EMOTION_SORRY
. Please feel free to reopen this issue or create a new one if you need anything else.
As a friendly reminder: the best way to see this issue, or any other, fixed is to open a Pull Request. Check out gatsby.dev/contribute for more information about opening PRs, triaging issues, and contributing!
Thanks again for being part of the Gatsby community!
does it work if the strings are put using {intl.formatMessage({ id: "online" })}
instead of <FormattedMessage id="online" />
?
You need to use defineMessages to define your messages first. And also add a default message. So like this:
const messages = defineMessages({
placeholder: {
id: 'search.bar.placeholder',
defaultMessage: 'Search for a product...',
},
});
And then where you actually want to use it:
intl.formatMessage(messages.placeholder)
Hi all, we have just begun to implement react-intl for i18n. Translations work fine, but so far we have been using a static json file with all translations.
Now i am looking for a way to extract all translation messages from all pages and components. I thought i could use babel-plugin-react-intl, but it is not working (nothing happens).
I have:
{ "presets": [ [ "babel-preset-gatsby" ] ], "plugins": [ ["react-intl", { "messagesDir": "./build/messages/" }] ] }
yarn develop works fine, but nothing is written to ./build I have various translations in my pages, for example:
<FormattedMessage id="header.account.login" />
Any idea's?