Skip to content

Commit c9f43c4

Browse files
committed
docs: Rewrite most of our SSR doc, add streaming mentions
1 parent f9a20b2 commit c9f43c4

File tree

1 file changed

+112
-56
lines changed

1 file changed

+112
-56
lines changed

content/en/guide/v10/server-side-rendering.md

Lines changed: 112 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -23,113 +23,169 @@ npm install -S preact-render-to-string
2323

2424
After the command above finished, we can start using it right away.
2525

26-
## Basic Usage
26+
## HTML Strings
2727

28-
Basic functionality can be best explained via a simple snippet:
28+
Both of the following options return a single HTML string that represents the full rendered output of your Preact application.
29+
30+
### renderToString
31+
32+
The most basic and straightforward rendering method, `renderToString` transforms a Preact tree into a string of HTML synchronously.
2933

3034
```jsx
31-
import render from 'preact-render-to-string';
32-
import { h } from 'preact';
35+
import { renderToString } from 'preact-render-to-string';
3336

3437
const name = 'Preact User!'
3538
const App = <div class="foo">Hello {name}</div>;
3639

37-
console.log(render(App));
40+
const html = renderToString(App);
41+
console.log(html);
3842
// <div class="foo">Hello Preact User!</div>
3943
```
4044

41-
## Asynchronous Rendering with `Suspense` & `lazy`
45+
### renderToStringAsync
4246

43-
You may find that you need to render components that are dynamically loaded, like when using `Suspense` and `lazy` to facilitate code splitting (along with some other use cases). The async renderer will await the resolution of promises, allowing you to fully construct your HTML string:
47+
Awaits the resolution of promises before returning the complete HTML string. This is particularly useful when utilizing suspense for lazy-loaded components or data fetching.
4448

4549
```jsx
46-
// page/home.js
47-
export default () => {
48-
return <h1>Home page</h1>;
50+
// app.js
51+
import { Suspense, lazy } from 'preact/compat';
52+
53+
const HomePage = lazy(() => import('./pages/home.js'));
54+
55+
function App() {
56+
return (
57+
<Suspense fallback={<p>Loading</p>}>
58+
<HomePage />
59+
</Suspense>
60+
);
4961
};
5062
```
5163

5264
```jsx
53-
// main.js
54-
import { Suspense, lazy } from 'preact/compat';
55-
56-
// Creation of the lazy component
57-
const HomePage = lazy(() => import('./pages/home'));
65+
import { renderToStringAsync } from 'preact-render-to-string';
66+
import { App } from './app.js';
5867

59-
const Main = () => {
60-
return (
61-
<Suspense fallback={<p>Loading</p>}>
62-
<HomePage />
63-
</Suspense>
64-
);
65-
};
68+
const html = await renderToStringAsync(<App />);
69+
console.log(html);
70+
// <h1>Home page</h1>
6671
```
6772

68-
The above is a very typical setup for a Preact application that uses code splitting, with no changes necessary to make use of server-side rendering.
73+
## HTML Streams
74+
75+
Streaming is a method of rendering that allows you to send parts of your Preact application to the client as they are ready rather than waiting for the entire render to complete.
6976

70-
To render this, we will deviate slightly from the basic usage example and use the `renderToStringAsync` export to render our application:
77+
### renderToPipeableStream
78+
79+
`renderToPipeableStream` is a streaming method that utilizes [Node.js Streams](https://nodejs.org/api/stream.html) to render your application. If you are not using Node, you should look to [renderToReadableStream](#rendertoreadablestream) instead.
7180

7281
```jsx
73-
import { renderToStringAsync } from 'preact-render-to-string';
74-
import { Main } from './main';
82+
import { renderToPipeableStream } from 'preact-render-to-string/stream-node';
83+
84+
// Request handler syntax and form will vary across frameworks
85+
function handler(req, res) {
86+
const { pipe, abort } = renderToPipeableStream(<App />, {
87+
onShellReady() {
88+
res.statusCode = 200;
89+
res.setHeader('Content-Type', 'text/html');
90+
pipe(res);
91+
},
92+
onError(error) {
93+
res.statusCode = 500;
94+
res.send(
95+
`<!doctype html><p>An error ocurred:</p><pre>${error.message}</pre>`
96+
);
97+
},
98+
});
99+
100+
// Abandon and switch to client rendering if enough time passes.
101+
setTimeout(abort, 2000);
102+
}
103+
```
75104

76-
const main = async () => {
77-
// Rendering of lazy components
78-
const html = await renderToStringAsync(<Main />);
105+
### renderToReadableStream
79106

80-
console.log(html);
81-
// <h1>Home page</h1>
82-
};
107+
`renderToReadableStream` is another streaming method and similar to `renderToPipeableStream`, but designed for use in environments that support standardized [Web Streams](https://developer.mozilla.org/en-US/docs/Web/API/Streams_API) instead.
83108

84-
// Execution & error handling
85-
main().catch((error) => {
86-
console.error(error);
87-
});
109+
```jsx
110+
import { renderToReadableStream } from 'preact-render-to-string/stream';
111+
112+
// Request handler syntax and form will vary across frameworks
113+
function handler(req, res) {
114+
const stream = renderToReadableStream(<App />);
115+
116+
return new Response(stream, {
117+
headers: {
118+
'Content-Type': 'text/html',
119+
},
120+
});
121+
}
88122
```
89123

90-
## Shallow Rendering
124+
## Customize Renderer Output
91125

92-
For some purposes it's often preferable to not render the whole tree, but only one level. For that we have a shallow renderer which will print child components by name, instead of their return value.
126+
We offer a number of options through the `/jsx` module to customize the output of the renderer for a handful of popular use cases.
127+
128+
### JSX Mode
129+
130+
The JSX rendering mode is especially useful if you're doing any kind of snapshot testing. It renders the output as if it was written in JSX.
93131

94132
```jsx
95-
import { shallow } from 'preact-render-to-string';
96-
import { h } from 'preact';
133+
import renderToString from 'preact-render-to-string/jsx';
97134

98-
const Foo = () => <div>foo</div>;
99-
const App = <div class="foo"><Foo /></div>;
135+
const App = <div data-foo={true} />;
100136

101-
console.log(shallow(App));
102-
// <div class="foo"><Foo /></div>
137+
const html = renderToString(App, {}, { jsx: true });
138+
console.log(html);
139+
// <div data-foo={true} />
103140
```
104141

105-
## Pretty Mode
142+
### Pretty Mode
106143

107144
If you need to get the rendered output in a more human friendly way, we've got you covered! By passing the `pretty` option, we'll preserve whitespace and indent the output as expected.
108145

109146
```jsx
110-
import render from 'preact-render-to-string/jsx';
111-
import { h } from 'preact';
147+
import renderToString from 'preact-render-to-string/jsx';
112148

113149
const Foo = () => <div>foo</div>;
114150
const App = <div class="foo"><Foo /></div>;
115151

116-
console.log(render(App, {}, { pretty: true }));
117-
// Logs:
152+
const html = renderToString(App, {}, { pretty: true });
153+
console.log(html);
118154
// <div class="foo">
119155
// <div>foo</div>
120156
// </div>
121157
```
122158

123-
## JSX Mode
159+
### Shallow Mode
124160

125-
The JSX rendering mode is especially useful if you're doing any kind of snapshot testing. It renders the output as if it was written in JSX.
161+
For some purposes it's often preferable to not render the whole tree, but only one level. For that we have a shallow renderer which will print child components by name, instead of their return value.
126162

127163
```jsx
128-
import render from 'preact-render-to-string/jsx';
129-
import { h } from 'preact';
164+
import renderToString from 'preact-render-to-string/jsx';
130165

131-
const App = <div data-foo={true} />;
166+
const Foo = () => <div>foo</div>;
167+
const App = <div class="foo"><Foo /></div>;
168+
169+
const html = renderToString(App, {}, { shallow: true });
170+
console.log(html);
171+
// <div class="foo"><Foo /></div>
172+
```
173+
174+
### XML Mode
175+
176+
For elements without children, XML mode will instead render them as self-closing tags.
177+
178+
```jsx
179+
import renderToString from 'preact-render-to-string/jsx';
180+
181+
const Foo = () => <div></div>;
182+
const App = <div class="foo"><Foo /></div>;
183+
184+
let html = renderToString(App, {}, { xml: true });
185+
console.log(html);
186+
// <div class="foo"><div /></div>
132187

133-
console.log(render(App));
134-
// Logs: <div data-foo={true} />
188+
html = renderToString(App, {}, { xml: false });
189+
console.log(html);
190+
// <div class="foo"><div></div></div>
135191
```

0 commit comments

Comments
 (0)