Skip to content

Commit f8ff11e

Browse files
authored
Merge pull request #464 from preactjs/jovi/options-root-suspense-mask
fix: call root hook during server render
2 parents c97e1f5 + 1179e9b commit f8ff11e

4 files changed

Lines changed: 34 additions & 0 deletions

File tree

.changeset/clever-peaches-brush.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"preact-render-to-string": patch
3+
---
4+
5+
Call `options._root` before the render-to-string invocation

src/index.js

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ import {
2121
NEXT_STATE,
2222
PARENT,
2323
RENDER,
24+
ROOT,
2425
SKIP_EFFECTS,
2526
VNODE,
2627
CATCH_ERROR
@@ -80,6 +81,7 @@ export function renderToString(vnode, context, _rendererState) {
8081

8182
const parent = h(Fragment, null);
8283
parent[CHILDREN] = [vnode];
84+
if (options[ROOT]) options[ROOT](vnode, { [CHILDREN]: parent, nodeType: 1 });
8385

8486
try {
8587
const rendered = _renderToString(
@@ -134,6 +136,7 @@ export async function renderToStringAsync(vnode, context) {
134136

135137
const parent = h(Fragment, null);
136138
parent[CHILDREN] = [vnode];
139+
if (options[ROOT]) options[ROOT](vnode, { [CHILDREN]: parent, nodeType: 1 });
137140

138141
try {
139142
const rendered = await _renderToString(

src/lib/constants.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ export const DIFFED = 'diffed';
55
export const COMMIT = '__c';
66
export const SKIP_EFFECTS = '__s';
77
export const CATCH_ERROR = '__e';
8+
export const ROOT = '__';
89

910
// VNode properties
1011
export const COMPONENT = '__c';

test/render.test.jsx

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ import {
2020
import { expect, vi, describe, it } from 'vitest';
2121
import { svgAttributes, htmlAttributes } from './utils.jsx';
2222
import { COMPONENT_DIRTY_BIT } from '../src/lib/util.js';
23+
import { CHILDREN } from '../src/lib/constants.js';
2324

2425
function shallowRender(vnode) {
2526
const context = {};
@@ -1396,6 +1397,30 @@ describe('render', () => {
13961397

13971398
expect(render(<App />)).to.equal('<div><p>P0-0</p><p>P0-1</p></div>');
13981399
});
1400+
1401+
it('should invoke options._root for root renders', () => {
1402+
const oldRoot = options.__;
1403+
let args;
1404+
1405+
function App() {
1406+
const id = useId();
1407+
return <p>{id}</p>;
1408+
}
1409+
1410+
const vnode = <App />;
1411+
options.__ = (rootVNode, parentDom) => {
1412+
args = [rootVNode, parentDom];
1413+
};
1414+
1415+
try {
1416+
expect(render(vnode)).to.equal('<p>P0-0</p>');
1417+
expect(args[0]).to.equal(vnode);
1418+
expect(args[1][CHILDREN][CHILDREN][0]).to.equal(vnode);
1419+
expect(args[1]).to.have.property('nodeType', 1);
1420+
} finally {
1421+
options.__ = oldRoot;
1422+
}
1423+
});
13991424
});
14001425

14011426
describe('Error Handling', () => {

0 commit comments

Comments
 (0)