HTML Streaming
Vike not only has first-class support for HTML streaming (aka SSR streaming), but also provides you with extensive control over the HTML stream.
If you merely want to enable/disable HTML streaming, see the API >
stream
setting instead.
Instead of manually integrating HTML Streaming yourself, you can use a UI framework Vike extension
vike-react
/vike-vue
/vike-solid
which already integrates HTML Streaming. And you can use Bati to scaffold an app that usesvike-react
/vike-vue
/vike-solid
.
⚠️The documentation on this page is meant for users who want to manually integrate HTML Streaming. If you usevike-react
/vike-vue
/vike-solid
then HTML Streaming is already built-in and you can skip reading this page.
Examples
Examples of manually integrating HTML streaming (without using a Vike extension).
React
- React 18 +
react-streaming
+ Node.js: /examples/react-full/ - React 18 +
react-streaming
+ Cloudflare Workers: /examples/cloudflare-workers-react-full/ - React 18 +
react-streaming
+ server agnostic:vike-react
source code - React 18 + Relay: Vilay
Vue
- Vue's
renderToNodeStream()
+ Node.js: - Vue's
pipeToWebWritable()
+ Cloudflare Workers: /examples/cloudflare-workers-vue/
Basics
Node.js platforms (Vercel, AWS EC2, AWS Lambda, ...):
Edge platforms (e.g. Cloudflare Workers):
In general, we recommend using pageContext.httpResponse.pipe()
because pipe()
is able to flush streams. In other words: the stream provided by your UI framework can say "now is a good time to flush the buffer and send it to the user".
As far as we know, only React leverages the flush capability. Thus, the recommendation may be irrelevant if you use a UI framework other than React.
If your server doesn't expose a writable stream then you cannot use pipe()
. In that case you can fallback to:
pageContext.httpResponse.getReadableWebStream()
pageContext.httpResponse.getReadableNodeStream()
For example, Cloudflare Workers doesn't expose any writable stream and the only option is to use getReadableWebStream()
.
API
pageContext.httpResponse.pipe()
: The recommended way of integrating the stream into your server.pageContext.httpResponse.getReadableWebStream()
: Only use if you cannot usepipe()
.pageContext.httpResponse.getReadableNodeStream()
: Only use if you cannot usepipe()
.enableEagerStreaming
: Start the stream as soon as possible.stampPipe()
: Only needed if your UI framework provides a stream pipe.pageContext.httpResponse.getBody()
: Convert the stream into a string.pageContext
promise: You can return apageContext
promise, in order to send initial data to the client after the stream ends.
enableEagerStreaming
By default, the HTML stream isn't immediately sent to the user. Instead, Vike awaits for your UI framework to start its stream.
If you set pageContext.enableEagerStreaming
to true
then Vike starts emitting the HTML template right away.
Make sure your server (or any proxy between your server and the user) doesn't buffer the stream, otherwise you may still notice a delay.
stampPipe()
If your UI framework provides a stream pipe, then you need to use stampPipe()
.
For Node.js:
If your server expects a readable stream (e.g. Cloudflare Workers) you can use new TransformStream()
:
For some UI frameworks, such as Vue, you need a pipe wrapper:
See /examples/cloudflare-workers-vue for an example of using a pipe wrapper with Vue's pipeToWebWritable()
/pipeToNodeWritable()
, as well as using new TransformStream()
for Cloudflare Workers.
pageContext.httpResponse.getBody()
You can convert the stream to a string:
Initial data after stream end
Some data fetching tools, such as Relay and Vue's onServerPrefetch()
, collect data during the stream.
Consequently, you can determine the initial data (which needs to be passed to the client-side) only after the stream has ended.
In such situations, you can return a pageContext
async function in your onRenderHtml()
hook:
Progressive Rendering
Some UI frameworks, such as React, support progressive rendering: while some parts of the UI are being loaded, other parts are already rendered (and already hydrated).
Instead of using HTML streaming, an easy alternative is to use a stateful component. But the issue with that approach is that the content isn't rendered to HTML. For example, a product page fetching its content from a database won't get the SEO and performance advantages of SSR.
With HTML streaming, all content is rendered to HTML.
Vike has first-class support for HTML streaming and progressive rendering.
Example: vike-react
> examples/full/
.
See also: React > React Server Components.
See also
- Node.js Streams (Node.js documentation)
- Web Streams (MDN documentation)
- Guides > Preloading
-
API >
stream