react-helmet
react-helmet copied to clipboard
Body style attribut is not set properly
When trying to set <body>
style
attribute like this:
<Helmet>
<body style={{background: 'black'}}/>
</Helmet>
It is actually set to <body style="[object Object]"/>
I figured out that I need to pass style attribute as a string to make it work:
<Helmet>
<body style="background: black"/>
</Helmet>
This is working in the browser but for SSR I get this error:
The
style
prop expects a mapping from style properties to values, not a string.
Here is how I use helmet for SSR:
const Html = ({children}) => {
const helmet = Helmet.rewind();
return (
<html lang="en" {...helmet.htmlAttributes.toComponent()}>
<body {...helmet.bodyAttributes.toComponent()}>
{children}
</body>
</html>
)
}
Am I missing something?
I am having the very same problem with react-helmet 5.2.0.
@janjarfalk if it helps, here is the simple workaround I used:
const getBodyStyleAttribute = (
backgroundUrl?: string,
backgroundColor?: string,
) => isClient
? [
backgroundUrl && `background-image: url(${backgroundUrl});`,
backgroundColor && `background-color: ${backgroundColor};`,
].filter(s => s).join('')
: {
backgroundImage: backgroundUrl ? `url(${backgroundUrl})` : undefined,
backgroundColor: backgroundColor || undefined,
};
@janjarfalk @testerez I am using a similar solution; though more generic.
import kebabCase from 'lodash/kebabCase';
const getHelmetBodyStyleAttributeValue = (style) => {
if (typeof window === 'undefined') {
return style;
}
return Object.keys(style).map(key => `${kebabCase(key)}: ${style[key]}`).join(';');
};
It seems to work for everything I have needed so far (though might fail on non standard things as it transforms keys to kebabCase)
Thanks for sharing @AubreyHewes what about having something similar built into react-helmet?
@testerez Good point, I will get a PR going ;-)
@AubreyHewes @testerez Any update on the PR? Looks stale
@matt-whitaker I never had any feedback on it.
@AubreyHewes thats unfortunate. Feels like a bug.
I'm using react-helmet with Gatsbyjs. I couldn't understand @testerez and @AubreyHewes examples. I used useEffect
to add style
attribute to body
:
useEffect(() => {
document.body.setAttribute('style', 'background-color: red;');
}, []);