Closed flavioalves closed 6 years ago
Just can guess (as i'm not to deep into gatsby. So from guess i would say the translations were not loaded when doing SSR -> turn off javascript in debug console to verify. (And really just guessing)
@jamuhl Seems that something is going wrong on server. Take a look at what I did:
I change my i18next init options adding:
backend : {
loadPath : '/locales/{{lng}}/{{ns}}.json'
}
Add some console logs on my gatsby-ssr.js
to see the i18n.loadNamespaces
function running, so I got the following log on server:
5:00:29 PM: >>> Copying locales - production mode
5:00:49 PM: success Building CSS — 20.131 s
5:01:21 PM: success Building production JavaScript bundles — 31.960 s
5:01:33 PM: >>> gatsby-ssr - replaceRenderer
5:01:33 PM: i18next::backendConnector: loading namespace translation for language en failed failed parsing /locales/en/translation.json to json
5:01:33 PM: i18next::backendConnector: loading namespace aboutUs for language en failed failed parsing /locales/en/aboutUs.json to json
...
5:01:34 PM: >>> gatsby-ssr - loadNamespaces
5:01:34 PM: i18next: languageChanged en
5:01:34 PM: i18next: initialized { debug: true,
...
So we can see that:
replaceRenderer in gatsby-ssr.js
ran correctlyfailed parsing
messages when the locale files was loaded in i18n.loadNamespaces
As the debugger option is enabled in i18next we can see the files loaded correctly in chrome console:i18next::backendConnector: loaded namespace translation for language en {lang: "en", seo: {…}}
VM129 component---src-layouts-framed-layout-js-e77b096dcada2d96febc.js:2 i18next: languageChanged en
VM129 component---src-layouts-framed-layout-js-e77b096dcada2d96febc.js:2 i18next: initialized {debug: true, initImmediate: true, ns: Array(4), defaultNS: "translation", fallbackLng: Array(1), …}
VM129 component---src-layouts-framed-layout-js-e77b096dcada2d96febc.js:2 i18next::backendConnector: loaded namespace Menu for language en {services: "Services", projects: "Projects", about-us: "About us", blog: "Our blog", phone: "say hello", …}
I published a public version of this PR at this link. As you can see, the locales are available if you try to access by the URL /locale/en/translation.json.
You guys have any guess about what is happening and how can I fix it?
https://fix-seo--novatics.netlify.com/locales/en/translation.json for me that url works...seems you already fixed it...i guess an invalid json file
I read about this possibility on another issue related to this "failed parsing" message and I read about the JSON format on i18next docs.
But, I couldn't find any error on my JSON files. Even using different JSON validators or trying the v1, v2 or v3 possibilities on. :'-(
I can see the JSON object on my browser console when i18next debug mode is enabled, they seem to be correctly loaded. The language switcher is working on my website as well. The problem is just with the meta tags that are supposed to work on SSR.
Here goes a example of my JSON:
{
"lang": "pt",
"seo": {
"title": "foo",
"description": "potato",
"propKey": "bar",
"prop-key": "is supported too"
}
}
Have I committed some mistake on my JSON structure? Can I use propKey and/or prop-key?
JSON looks ok...so it's "only" a problem with setting meta tags on serverside render...how are those set?
@jamuhl I'm using Helmet to do it. I encapsulate Helmet in a React component.
Here goes a piece of my component "seo.js"
:
<Helmet>
<title>{props.title}</title>
<link rel="canonical" href={seoURL(props.path)} />
<link rel="icon" type="image/png" sizes="32x32" href={favicon32} />
<link rel="shortcut icon" href={faviconICO} />
<meta name="description" content={props.description} />
...
</Helmet>
Here is an example of my component been used:
<SEO
title={t('seo.title')}
description={t('seo.description')}
...
/>
did you check if eg.: t('seo.title')
returns the expected value while rendering on server? Or could it be those to get a translation missing
(not yet loaded?)
FYI: I run into the exact same issue (react-helmet
+ react-i18next
). I'm pre-rendering static pages, then hydrating using react-snap, so this allows me to see the HTML output for everything.
The issue was precisely as described here. The whole page renders w/ all the translations, save the <head/>
content, which just has the keys. I was using a component to simplify the boiler plate, e.g.:
export interface HeadContentProps {
pageKey: string
}
const HeadContent = ({pageKey}: HeadContentProps) => (
<I18n>
{(t) => (
<Helmet>
<title>{t(`${pageKey}.head.title`)}</title>
<meta name="description" content={t(`${pageKey}.head.description`)}/>
</Helmet>
)}
</I18n>
);
Thus:
export const FooPage = () => (
<>
<HeadContent pageKey={'fooKey'} />
<FooStuff/>
</>
);
I found that just inlining HeadContent
into FooPage
fixes this. I have no clue why. I've been using React for fewer than 10 days, so I'm not well-versed on the inner workings. This adds an uncomfortable level of boilerplate, so I'll continue doing some searching tomorrow to see if there's some explanation for the discrepancy.
Interestingly, if I pre-define <HeadContent>
, it works:
const HEAD_CONTENT = <HeadContent pageKey={'fooKey'}/>;
export const FooPage = () => (
<>
{HEAD_CONTENT}
<FooStuff/>
</>
);
Still don't know why.
closing this for now...if you get new insights please share them here
Description
I'm building a multi-language website using gatsby-plugin-react-helmet, react-helmet, and react-i18next.
I created the same structure of this official blog post and I've got the things apparently working well.
But, the strange part is that my "SEO metadata" isn't been found by SEO analyzers and link previews, as it is supposed to do.
When I check on my browser inspect I can found the meta tags, but seems that it is loaded on the client side and not on SSR.
Steps to reproduce
I create a SEO component following the same idea of the exemple listed here.
My i18n component (same idea of the post)
Loading all namespaces before render:
And gatsby-plugin-react-helmet should handle the SSR aspects.
I tested with fixed data (not loaded from a locale file) and it works well.
Do you guys could help me with this? Any guess?
Thanks in advance!