DEV Community

Cover image for ☢️ HTML Comment in React
Andrew Luca
Andrew Luca

Posted on

☢️ HTML Comment in React

If you ever started learning React and saw it's syntax JSX, you maybe thought. "This looks like HTML"

And one day you want to comment something in JSX, and your first try would be to do:

function Component() {
  return (
    <div>
      <!-- This is my comment -->
      The quick brown fox ...
    </div>
  )
}
Enter fullscreen mode Exit fullscreen mode

And for sure your bundler started complaining, that your syntax is invalid, and then you search the internet, and realise that a HTML Comment is not valid in JSX, and you learn that you have to use a JavaScript comment.

Well in this blog post I will show you for learning purposes how to trick React to render a real HTML Comment in your browser in a few steps.

Step 1

Generate a React app using Create React App

npx create-react-app my-experiment --template typescript
cd my-experiment
npm run start
Enter fullscreen mode Exit fullscreen mode

Step 2

Open App.tsx and add a const with a unique id as a string

const HTMLComment = 'unique-html-comment'
Enter fullscreen mode Exit fullscreen mode

Step 3

Declare this HTMLComment as a Intrinsic Element in your App.tsx. TypeScript is not required, but you have to learn something interesting 😊

import { PropsWithChildren } from 'react';

declare global {
  namespace JSX {
    interface IntrinsicElements {
      [HTMLComment]: PropsWithChildren<unknown>
    }
  }
}
Enter fullscreen mode Exit fullscreen mode

Step 4

Render this created HTMLComment as a JSX element in your App.tsx

function App() {
  return (
    <div className="App">
      <header className="App-header">
        <HTMLComment>This is my comment</HTMLComment>
        {/* ... */}
      </header>
    </div>
  );
}
Enter fullscreen mode Exit fullscreen mode

Let's check what was rendered in browser.

Image description

Well, that's expected, React thinks our element is a DOM element and renders it as usual. Let's move on.

Step 5

  • Open node_modules/react-dom/cjs/react-dom.development.js
  • Find createElement function (line ~8954)
  • Find } else if (typeof props.is === 'string') { (line ~8986)

Image description

You see last } else {? inside that last branch a new element is created. We need to add one more if branch to check for our HTMLComment

if (type === 'unique-html-comment') {
  domElement = ownerDocument.createComment('')
}
Enter fullscreen mode Exit fullscreen mode

Our final added code will look like this:

Image description

Save the file. Restart the CRA process so it can see new changes from inside node_modules

Open the browser to see the result.

Image description

And that's how you trick React into rendering a HTML Comment!
Feeeling like a hacker now? 🤣

haker typing

Cover Photo by Florian Olivo on Unsplash

Discussion (11)

Collapse
lukeshiru profile image
LUKESHIRU

Interesting experiment, non practical at all, but interesting 🤔

Collapse
iamandrewluca profile image
Andrew Luca Author • Edited on

It's practical, I assure you 😀 But it is not showed in this blog post. Soon will release a library that will add some light to this.

Collapse
lukeshiru profile image
LUKESHIRU

I would have to see that, because we have comments in JSX already...

const CommentsInJSX = props => (
    <div>
        {/* Hi, I'm a comment */}
        <span
            // Hi, I'm another comment!
            data-example="hello"
        />
    </div>
);
Enter fullscreen mode Exit fullscreen mode

... so tbh I don't see much value in having to import a component to have comments, that will leak into the DOM instead of staying in my code.

Thread Thread
iamandrewluca profile image
Andrew Luca Author • Edited on

that will leak into the DOM instead of staying in my code

That was the point, I needed the comment to land in DOM. 🙂
This is useful when you need something like IE/MSO conditional comments

<!--[if condition]>
(HTML to use if condition is true)
<![endif]-->
Enter fullscreen mode Exit fullscreen mode
Thread Thread
lukeshiru profile image
LUKESHIRU

But, you could just...

condition ? <html /> : null;
Enter fullscreen mode Exit fullscreen mode
Thread Thread
iamandrewluca profile image
Andrew Luca Author • Edited on

🤔 what do you mean? What is <html /> ? Like HTML tag, or the HTML string?

When you are writing Email HTML templates, in the end you need a HTML output, and you need conditional comments to target specific email clients like Outlook, that why I need the comment to land in final HTML.

It's not for frontend applications 🤷‍♂️

Thread Thread
lukeshiru profile image
LUKESHIRU

That being the case, why use React for something that will be sent by Email? There are tools way better suited for that task.

And with <html/ > I meant any piece of JSX (read it as <span /> or <div /> or something more complex with nesting). Using ternaries is pretty common in React to achieve optional rendering.

Thread Thread
iamandrewluca profile image
Andrew Luca Author

why use React for something that will be sent by Email

For better DX

Collapse
sergiuprt profile image
Sergiu Pruteanu

So much trouble for a comment

Collapse
iamandrewluca profile image
Andrew Luca Author • Edited on

Hunting a solution for almost a year, for a greater scope. 🙂 Soon will release a library
Some context: stackoverflow.design/email/base/mso/

Collapse
sergiuprt profile image
Sergiu Pruteanu

Got it. Interesting.