When using next/head in a page we should be able to render head scripts conditionally by returning null from a custom component.
If a custom component that can return null (depending on its internal logic) is added as a child of Next/Head the page breaks.
Example:
<Head>
<CustomComponent booleanProp={true} />
</Head>
Where CustomComponent is something like:
const CustomComponent = ({booleanProp}) => {
if(booleanProp){
return <script>some js script</script>
}
return null;
};
The last 'return null' will break the page since a file called headManager.js has this logic:
for (var i = 0, j = headCountEl.previousElementSibling; i < headCount; i++, j = j.previousElementSibling) {
if (j.tagName.toLowerCase() === type) {
oldTags.push(j);
}
}
Therefore j.tagName is undefined.
I would like to be able to return null (as it's very common in react components) when my condition is not met; this will let NextJs skip the script.
Something simple like:
if (j.tagName && j.tagName.toLowerCase() === type) {
oldTags.push(j);
}
As an added bonus we can log a warning for head scripts returning null.
headManager.js should handle 'null' script tags.
Likely to be solved in 9.5.4 by https://github.com/vercel/next.js/pull/16758?
@klapec Did you check if this is still an issue on the latest canary?
@lfades I've just gave it a try and unfortunately it still is an issue (although a different one?):
Uncaught (in promise) DOMException: Failed to execute 'createElement' on 'Document': The tag name provided ('function Analytics(_ref) {
...my component...
}') is not a valid name.
at reactElementToDOM (webpack-internal:///./node_modules/next/dist/client/head-manager.js:20:21)
at eval (webpack-internal:///./node_modules/next/dist/client/head-manager.js:59:18)
at Array.forEach (<anonymous>)
at updateElements (webpack-internal:///./node_modules/next/dist/client/head-manager.js:46:14)
at eval (webpack-internal:///./node_modules/next/dist/client/head-manager.js:107:9)
11 | function reactElementToDOM({ type, props }: JSX.Element): HTMLElement {
> 12 | const el = document.createElement(type)
| ^
13 | for (const p in props) {
14 | if (!props.hasOwnProperty(p)) continue
15 | if (p === 'children' || p === 'dangerouslySetInnerHTML') continue
and here's my <Head> component:
<Head>
<meta name="web" content={serverName} />
<Analytics
{...props}
/>
</Head>
So now I can't even use a custom component within <Head>, regardless of what it returns (whether a valid
"next": "^9.5.4-canary.20",
I am getting the same issue as @klapec in 10.0.0
Most helpful comment
@lfades I've just gave it a try and unfortunately it still is an issue (although a different one?):
and here's my
<Head>component:So now I can't even use a custom component within
DOM element child or a custom React component).<Head>, regardless of what it returns (whether a validI'm on
"next": "^9.5.4-canary.20",