HTML comments for LWC templates

Summary

In most cases, HTML comments in templates only add information for other developers. There are some use cases where HTML comments convey some runtime semantic (e.g., MSO comments). As of today, the LWC template compiler strips HTML comments. This RFC proposes a way to preserve HTML comments in LWC templates.

Basic example

<template lwc:preserve-comments>
  <!-- Greeter container -->
  <div>
	Hello <b>{name}</b>!
  </div>
  <!-- eof: Greeter container -->
</template>
<x-example>
  # shadow-root
  |   <!-- Greeter container -->
  |   <div>
  |     Hello <b>world</b>
  |   </div>
  |   <!-- eof: Greeter container -->
</x-example>

Motivation

Microsoft Outlook's desktop email client leverage MSO (Microsoft Office) to render their HTML content. Because of this, the support for common HTML and CSS properties is limited, eg: <div>s are not supported.

Email developers rely on MSO conditionals to improve the UX of emails opened on Microsoft Outlook.

This RFC introduces a new opt-in mechanism at compile time to preserve HTML comments.

Proposal

Compile-time behavior

LWC compilation strips HTML comments because the browsers do not use them at runtime. The bundle's size is smaller by stripping the HTML comments, and the rehydration process does not need to take into account comments nodes.

To preserve the performance of the existing components, we propose to introduce two options to enable comments:

  1. A new boolean attribute (lwc:preserve-comments) to the root template tag in the component template; false by default.

  2. A new compile option (preserveHTMLComments) in the template compiler; false by default.

Both options will make the compiler invoke a runtime API adding the HTML comments in the component template to the output code that runs in the browser/server. Modifications in each environment's renderers will ensure that the comment node/text is present on the resulting HTML.

Invariants

Runtime behavior

A new API "[co]mment" will be added to the engine/core. The co(string commentText): VNode will receive the comment text and return a Comment vnode.

During rendering cycles, the LWC engine diffing algorithm will show/hide the comment based on the directive containing it (if:true/false, for:each, etc.)

Invariants

Backwards Compatible

This feature is backward compatible because is gated by the new opt-in mechanism.

Prior art

How we teach this

We must update the documentation to reflect this opt-in mechanism.

undefined