Having troubles with ReactJs Helmet 6.0.
The app has a language switch option and some other pages.
Once the page or language is changing - the new metadata is rendering.
The description, keywords and title are updated, but nothing is happening to all tags inside htmlAttributes.
So schema or html lang tags are not added to the DOM.
The index.html is simple straightforward:
<!doctype html>
<html lang="en"> <!-- nothing is happening if I remove it -->
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<meta name="author" content="author">
<link rel="icon" href="/img/favicon.png">
</head>
<body>
<div id="app"></div>
</body>
</html>
index.js
class App extends React.Component {
componentWillMount() {
var metaTitle=[];
var desc=[];
var kewd=[];
if (i18n.language=='en') {
this.metaTitle = "En title";
this.desc = 'En desc';
this.kewd = 'En keywords';
} else {
this.metaTitle = "other lang title";
this.desc = 'other lang desc';
this.kewd = 'other lang keywords';
}
}
render() {
var lang = i18n.language;
return (
<I18nextProvider i18n={i18n}>
<div>
<SEO
schema="Product"
title={this.metaTitle}
lang={i18n.language}
keywords={this.kewd}
description={this.desc}
base="base.com"
path={`/${lang}`}
contentType="product"
/>
<Router history={customHistory}>
<Switch>
<Route paths .../>
</Switch>
</Router>
</div>
</I18nextProvider>
)
}
}
ReactDOM.render(<App />, document.getElementById('app'));
SEO.js
import { Helmet } from 'react-helmet';
class SEO extends React.Component {
render() {
const { schema, lang, title, description, keywords, base, path, contentType } = this.props;
const meta = [
{name: 'author', content: 'author'.toString() },
{name: 'description', content: description.toString()},
{name: 'keywords', content: keywords.toString()},
{property: 'og:title', content: `${title}`.toString()},
{property: 'og:description', content: description},
];
return (
<Helmet
htmlAttributes={{
lang: i18n.language,
itemscope: undefined,
itemtype: `http://schema.org/${schema}`,
}.toString()}
title={title}
meta={meta}
/>
)
}
}
export default SEO;
I beieve the .toString() call is the cause.
For the similar property bodyAttributes Helmet requires an object instead of a string:
<Helmet bodyAttributes={{ style: "margin: 0; padding: 0; border: 0;", class="body"}}>
using react-helmet 6.1.0
Thank you for response.
I've removed .toString() but this doesn't changed the situation.
For example, the html lang attribute still doesn't change...
Any fix for this? Trying to use react-snap and react-helmet together. I noticed it's creating a duplicate meta description tag. react-snap gets added first so the react-helmet description is never showed.
EDIT: fixed just had to remove meta description from the index.html file in the public directory now I'm seeing just the react-helmet description and it gets written correctly in react-snap.
Also needed to add the react the data-react-helmet="true" to my description tag in public/index.html so it can find it and replace it correctly. Everything seems to be working though.
@01Kuzma
Thank you for response.
I've removed.toString()but this doesn't changed the situation.
For example, thehtml langattribute still doesn't change...
Have you removed this .toString()?
htmlAttributes={{
lang: i18n.language,
itemscope: undefined,
itemtype: `http://schema.org/${schema}`,
}.toString()}
Calling .toString() on an object literal will always return [object Object] string, unless .toString() is redefined in prototype.
Have you removed this .toString()?
Yes, I did
@01Kuzma few more suggestions:
1) attributes should have camelCase, refer to the link to React docs, and read the warning there - https://reactjs.org/docs/introducing-jsx.html#specifying-attributes-with-jsx
Also, react-helmet, converts it to the proper names with this function: https://github.com/nfl/react-helmet/blob/master/src/HelmetUtils.js#L545
2) make sure that i18n.language has some value when you use it in htmlAttributes. I'm not quite sure why do you use i18n.language in that place, since you've provided lang as a prop to SEO component.
So I would try:
htmlAttributes={{
lang: i18n.language,
itemScope: undefined,
itemType: `http://schema.org/${schema}`,
}}
UPDATE: i'm actually not sure that itemScope or itemType would work, because I can't see the mapping in their constants:
https://github.com/nfl/react-helmet/blob/master/src/HelmetConstants.js#L36
Thank you @ivansvlv , I will try
@01Kuzma
Another idea:
Maybe it seems like the lang attribute does not appear, because you are looking at the html source file (Ctrl + U in Firefox) instead of the react-generated DOM (using inspector in developer console).
kinafu, yes, you are right!
I just forgot to post this information earlier...
Thanks to all of you!
Closing this issue
Most helpful comment
kinafu, yes, you are right!
I just forgot to post this information earlier...
Thanks to all of you!
Closing this issue