I'm trying to add react-intl to my project and when I run gatsby build static pages are generated correctly, but when I load them in the browser, intl object is messed up in template components, i.e. it has incorrect locale and intl.messages object is empty.
My current setup looks like this:
// src/layouts/de.js
import React from 'react';
import Layout from './index';
import messages from '../../data/translations/de.json';
export default (props) => <Layout {...props} locale="de" messages={messages} />;
IntlProvider in index layout:// src/layouts/index.js
import React from 'react';
import { IntlProvider } from 'react-intl';
function TemplateWrapper({ children, locale, messages }) {
return (
<IntlProvider locale={locale} messages={messages}>
<div>{children()}</div>
</IntlProvider>
);
}
export default TemplateWrapper;
FormattedMessage and injectIntl.I've added console.log at each step to see where it gets messed up.
Here are logs when running gatsby build for /de/blog page:
Rendering "de" layout...
path /de/blog
Rendering "index" layout...
path /de/blog
locale de
messages Datenschutz
Rendering "index" page...
locale de
messages Datenschutz
Here are logs when opening /de/blog page in a browser:
component---src-layouts-de-jsx-48cc900e186c41daf6ff.js:3 Rendering "de" layout...
component---src-layouts-de-jsx-48cc900e186c41daf6ff.js:3 path /de/blog/
component---src-layouts-de-jsx-48cc900e186c41daf6ff.js:3 messages Datenschutz
component---src-layouts-de-jsx-48cc900e186c41daf6ff.js:3 Rendering "index" layout...
component---src-layouts-de-jsx-48cc900e186c41daf6ff.js:3 path /de/blog/
component---src-layouts-de-jsx-48cc900e186c41daf6ff.js:3 locale de
component---src-layouts-de-jsx-48cc900e186c41daf6ff.js:3 messages Datenschutz
component---src-templates-index-jsx-66713dbb6ea96235f9fd.js:2 Rendering "index" page...
component---src-templates-index-jsx-66713dbb6ea96235f9fd.js:2 locale en
component---src-templates-index-jsx-66713dbb6ea96235f9fd.js:2 messages undefined
As you can see in the template the data is different when running it in a browser, than in the generated static page.
Any idea how to set it up properly?
Turns out it had nothing to do with Gatsby and I was simply missing
import { addLocaleData } from 'react-intl';
import localeData from 'react-intl/locale-data/de';
addLocaleData(localeData);
in my layouts 🤦♂️
how do you polyfill Intl for older browsers like IE10?
@antoinerousseau I'm using https://polyfill.io. It doesn't always work correctly, as I still sometimes get notifications about missing Intl in older and less common browsers like Samsung Internet 3.x or UC Browser, but it might also be some bug in my code.
I've got the following code in gatsby-browser.js:
exports.onClientEntry = () => {
/*
* Polyfills via polyfill.io
*/
return new Promise((resolve, reject) => {
// Global callback for polyfill.io script
// eslint-disable-next-line no-underscore-dangle
window.__polyfillio__ = () => {
resolve();
};
const features = [];
if (!('Intl' in window)) {
const locale = getLocaleFromPath(window.location.pathname);
features.push(`Intl.~locale.${locale}`);
}
if (!('fetch' in window)) {
features.push('fetch');
}
if (!('URL' in window && 'URLSearchParams' in window)) {
features.push('URL');
}
// Use 'always' flag to download polyfills regardless of user agent.
// We add features to the list only if they are not supported.
if (features.length) {
const s = document.createElement('script');
s.src = `https://cdn.polyfill.io/v2/polyfill.min.js?features=${features.join(
',',
)}&rum=1&flags=always&callback=__polyfillio__`;
s.async = true;
s.onerror = reject;
document.head.appendChild(s);
} else {
resolve();
}
});
};
thanks @szimek for sharing your code.
isn't fetch already polyfilled by gatsby?
@antoinerousseau I'm not sure. We had this code before we migrated to Gatsby v2.
But it looks like it might not be: https://github.com/zloirock/core-js/issues/25.
Most helpful comment
Turns out it had nothing to do with Gatsby and I was simply missing
in my layouts 🤦♂️