-
Notifications
You must be signed in to change notification settings - Fork 333
SolidStart: expand docs on rendering modes #1308
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from 10 commits
c83f957
28afce1
2e8d401
7a73d35
926ff16
08b8670
41d8ff0
3207564
4bdba75
a02ed4c
4d313c3
b7fb815
717bca0
c56434a
ea97511
142c87f
e09cc3c
bd9cbed
d3a447d
2b21ae7
3449f45
5c40d3d
c3cb991
0a7f7ec
889b9d7
eb2cd49
75c77b2
6738c75
ff476f4
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||||
|---|---|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,95 @@ | ||||||||||
| --- | ||||||||||
| title: "Rendering Modes" | ||||||||||
| --- | ||||||||||
|
|
||||||||||
| SolidStart has 3 kinds of rendering modes: `sync`, `async`, and `stream`. | ||||||||||
| Let's talk about how each of them work and which one to pick. | ||||||||||
|
|
||||||||||
| :::note | ||||||||||
| Default is **stream** and performance-wise should be preferred as a rule-of-thumb. | ||||||||||
atilafassina marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||||||||||
| ::: | ||||||||||
|
|
||||||||||
| All modes have some degree of Server-Side Rendering, you may need to change them globally depending on your deployment provider. | ||||||||||
| And you may prefer to override them for better bot support and SEO. | ||||||||||
|
|
||||||||||
| ## Impacted Features | ||||||||||
atilafassina marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||||||||||
|
|
||||||||||
| | Feature | sync | async | stream | | ||||||||||
| | -------------------- | ----------- | --------------------------- | ----------------------- | | ||||||||||
| | Data fetching | Client-side | Server-side (blocking) | Server-side (streaming) | | ||||||||||
| | Suspense fallbacks | Yes | No | Yes | | ||||||||||
| | Time to first byte | Fast | Slower (waits for all data) | Faster | | ||||||||||
| | Total page load time | Slower | Fast (server fetches) | Faster (progressive) | | ||||||||||
|
|
||||||||||
| ### Sync Mode | ||||||||||
|
|
||||||||||
| Uses [`renderToString`](/reference/rendering/render-to-string) to render the page from Solid's core to render the page synchronously. | ||||||||||
| All async features are disabled and the page is rendered as soon as possible and sent to the client-side where data fetching will happen post-hydration. | ||||||||||
|
|
||||||||||
| ### Async Mode | ||||||||||
|
|
||||||||||
| Uses [`renderToStringAsync`](/reference/rendering/render-to-string-async) to render the page from Solid's core to render the page asynchronously. | ||||||||||
| All Suspense boundaries are resolved and rendered before being sent to the client-side. | ||||||||||
atilafassina marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||||||||||
|
|
||||||||||
| No suspense fallbacks are shown in the browser, which makes this mode ideal for SEO optimizations and bot support. | ||||||||||
|
|
||||||||||
| ### Stream Mode | ||||||||||
|
|
||||||||||
| Uses [`renderToStream`](/reference/rendering/render-to-stream) to render the page from Solid's core to render the page streaming. | ||||||||||
| Leveraging [TransformableStream](https://developer.mozilla.org/en-US/docs/Web/API/TransformStream) to progressively send the HTML to the client-side. | ||||||||||
|
|
||||||||||
| This mode is ideal for performance and future-friendly apps. | ||||||||||
danieljcafonso marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||||||||||
|
|
||||||||||
| ## Global Configuration | ||||||||||
|
|
||||||||||
| The modes can be defined app-wide via the configuration file or via the [`entry-server.tsx`](/solid-start/reference/entrypoints/entry-server) file. | ||||||||||
|
|
||||||||||
| ```tsx title="app.config.ts" | ||||||||||
| import { defineConfig } from "@solidjs/start/config"; | ||||||||||
|
|
||||||||||
| export default defineConfig({ | ||||||||||
| mode: "stream", | ||||||||||
| }); | ||||||||||
| ``` | ||||||||||
|
|
||||||||||
| The value in [`entry-server.tsx`](/solid-start/reference/entrypoints/entry-server) overrides the value in [`app.config.ts`](/solid-start/reference/entrypoints/app-config). | ||||||||||
|
|
||||||||||
| ```tsx title="src/entry-server.tsx" | ||||||||||
| import { createHandler, StartServer } from "@solidjs/start/server"; | ||||||||||
|
|
||||||||||
| export default createHandler(() => ( | ||||||||||
| <StartServer document={...} /> | ||||||||||
| ), { | ||||||||||
| mode: "async" | ||||||||||
| }); | ||||||||||
| ``` | ||||||||||
|
|
||||||||||
| ## Per-Route Configuration | ||||||||||
|
|
||||||||||
| The optional secondary parameter in [`createHandler`](/solid-start/reference/server/create-handler) can be an object or a function that receives the `RequestEvent` and returns an object with the mode to use for the route. | ||||||||||
|
|
||||||||||
| ```tsx title="src/entry-server.tsx" | ||||||||||
| import { createHandler, StartServer } from "@solidjs/start/server"; | ||||||||||
|
|
||||||||||
| export default createHandler(() => ( | ||||||||||
| <StartServer document={...} /> | ||||||||||
| ), { | ||||||||||
| mode: (event) => { | ||||||||||
| return { mode: event.request.url.includes("/special-route") ? "async" : "stream" }; | ||||||||||
| } | ||||||||||
|
Comment on lines
+92
to
+94
|
||||||||||
| mode: (event) => { | |
| return { mode: event.request.url.includes("/special-route") ? "async" : "stream" }; | |
| } | |
| mode: (event) => ({ mode: event.request.url.includes("/special-route") ? "async" : "stream" }) |
Copilot
AI
Oct 26, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same issue as Comment 3: The function should directly return the object ({ mode: isBot(event.request.userAgent) ? \"async\" : \"stream\" }) without the explicit return statement and extra braces, to match the type signature.
| mode: (event) => { | |
| return { mode: isBot(event.request.userAgent) ? "async" : "stream" }; | |
| } | |
| mode: (event) => ({ mode: isBot(event.request.userAgent) ? "async" : "stream" }) |
Uh oh!
There was an error while loading. Please reload this page.