I experimented a lot, trying to add comments in React, and discovered this work-around — you can use a <script> element that replaces itself with the comment. It's instant, and doesn't require a wrapper.
"use client"; export default function Comment({ text }) { if (typeof window === "undefined") { const code = `document.currentScript.outerHTML = "<!-- ${text} -->"`; return <script>{code}</script>; } }
It happens instantly. When the browser loads the initial HTML, the script is immediately executed and replaced by a comment. If you keep reloading the page, you might see the <script> element flash in the DevTools for just a moment.
There are no hydration errors, since by the time React loads and hydrates the document, the script element is already replaced by a comment node. The client-render of <Comment> returns undefined, so there isn't anything for React to match it with, and it's simply ignored.
BUT: it only works when rendered from the server-side. You may need to tinker around a bit with client-rendering part, to get the state updates working properly. Getting a reference to the comment node will probably be a bit problematic here.
Well, it should be good enough for hiding easter eggs at least!
Also, here's a IE11-friendly version that doesn't have document.currentScript:
"use client"; import { useId } from "react"; export default function Comment({ text }) { if (typeof window !== "undefined") return; // eslint-disable-next-line react-hooks/rules-of-hooks const id = useId(); const code = `document.getElementById("${id}").outerHTML = "<!-- ${text} -->"`; return <script id={id}>{code}</script>; }
For a renderToStaticMarkup-compatible one (returns comments in the initial HTML, but leaves extraneous elements) see @zomars's answer under a different question.