Skip to content

Commit 659b456

Browse files
Add support for rendering HTML comments
This is done via Fragments because they are the least common components. That way the additional branching has minimal impact
1 parent 52be312 commit 659b456

File tree

3 files changed

+29
-0
lines changed

3 files changed

+29
-0
lines changed

.changeset/shy-hotels-impress.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
---
2+
'preact-render-to-string': minor
3+
---
4+
5+
Add ability to render comments via `<Fragment comment="my-comment" />`. When the `comment` prop is present all children of that `Fragment` will be ignored. This PR only supports that in server environments as it's useful to mark islands and other things. It's not supported in the browser.
6+
7+
We picked a `Fragment` for this as it's the least common component and therefore the branch in our code with the least impact on perf by adding another if-check.

src/index.js

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -165,6 +165,12 @@ function _renderToString(vnode, context, isSvgMode, selectValue, parent) {
165165
// Invoke rendering on Components
166166
if (typeof type === 'function') {
167167
if (type === Fragment) {
168+
// Fragments are the least use components of core that's why
169+
// branching here for comments has the least effect on perf.
170+
if (props.comment) {
171+
return '<!--' + encodeEntities(props.comment || '') + '-->';
172+
}
173+
168174
rendered = props.children;
169175
} else {
170176
contextType = type.contextType;

test/render.test.js

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1309,6 +1309,22 @@ describe('render', () => {
13091309
expect(render(<div>{() => {}}</div>)).to.equal('<div></div>');
13101310
});
13111311

1312+
describe('HTML Comments', () => {
1313+
it('should render HTML comments via Fragments', () => {
1314+
expect(render(<Fragment comment="foo" />)).to.equal('<!--foo-->');
1315+
});
1316+
1317+
it('should ignore children with comment prop', () => {
1318+
expect(
1319+
render(
1320+
<Fragment comment="foo">
1321+
<p>foo</p>
1322+
</Fragment>
1323+
)
1324+
).to.equal('<!--foo-->');
1325+
});
1326+
});
1327+
13121328
describe('vnode masks (useId)', () => {
13131329
it('should skip component top level Fragment child', () => {
13141330
const Wrapper = ({ children }) => <Fragment>{children}</Fragment>;

0 commit comments

Comments
 (0)