Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions src/routes/solid-start/building-your-application/data.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
{
"title": "Building your application",
"pages": [
"rendering-modes.mdx",
"routing.mdx",
"api-routes.mdx",
"css-and-styling.mdx",
Expand Down
110 changes: 110 additions & 0 deletions src/routes/solid-start/building-your-application/rendering-modes.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
---
title: "Rendering Modes"
---

SolidStart has 3 kinds of rendering modes:

- `sync`: renders on server with `renderToString` and performs Client-Side Rendering (CSR) for asynchronous features.
- `async`: renders on server with `renderToStringAsync`. Blocking the response until all asynchronous data fetching is resolved.
- `stream` (default): renders on server with `renderToStream`. Streaming the response as soon as possible and continuing to fetch asynchronous data in the background, resolving the page as soon as possible and sending next chunks.

All modes have some degree of Server-Side Rendering, you may need to change them globally depending on your deployment provider.

### 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.

:::caution[Page Components]
In SolidStart, all page components are lazy-loaded by default. This means that `renderToString` will SSR only until `app.tsx` and the route components will be rendered client-side.
:::

Asynchronous features will be directly impacted since rendering will mostly happen on the client-side.

- Data-fetching: client-side only, first load will render Suspense fallbacks.
- Time To First Byte (TTFB): fast since the server-side rendering is minimal.
- Total page load time: slower since the client-side rendering is heavier.
Copy link

Copilot AI Oct 26, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The phrase 'to render the page' is repeated. Remove the first occurrence to read: 'Uses renderToString from Solid's core to render the page synchronously.'

Suggested change
- Total page load time: slower since the client-side rendering is heavier.
Uses [`renderToString`](/reference/rendering/render-to-string) from Solid's core to render the page synchronously.

Copilot uses AI. Check for mistakes.

### Async Mode

Uses [`renderToStringAsync`](/reference/rendering/render-to-string-async) to render the page from Solid's core to render the page asynchronously.
Uses [`renderToStringAsync`](/reference/rendering/render-to-string-async) from Solid's core to render the page asynchronously.
Copy link

Copilot AI Oct 26, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Duplicate line: Line 31 repeats the same content as line 30. Remove the duplicate line.

Suggested change
Uses [`renderToStringAsync`](/reference/rendering/render-to-string-async) from Solid's core to render the page asynchronously.

Copilot uses AI. Check for mistakes.

:::tip[SEO and Bot Support]
No suspense fallbacks are shown in the browser, which makes this mode ideal for SEO optimizations and bot support.
:::

Asynchronous features will happen in the Server-Side during first render.
Uses [`renderToStream`](/reference/rendering/render-to-stream) from Solid's core to render the page streaming.
- **Data-fetching**: first render will be similar to sync mode, but data fetching will still happen in the background and responses will be streamed in chunks as available.
Comment on lines +38 to +39
Copy link

Copilot AI Oct 26, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The description at line 38 appears to be misplaced in the Async Mode section. This line describes stream mode functionality but is located within the Async Mode section (after line 37 which discusses server-side features for async mode). It should either be removed from this section or the section structure needs to be corrected.

Copilot uses AI. Check for mistakes.
- **Time To First Byte (TTFB)**: slower since the server-side rendering is heavier.
- **Total page load time**: faster than sync mode since the server-side tends to be faster than the client-side.

### Stream Mode (default)

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.

:::tip[Performance and Future-Friendly Apps]
This mode is ideal for performance and future-friendly apps. It provides best perceived performance and consumes less memory and CPU from the client-side.
:::

Asynchronous features will happen in the Server-Side during first render.

- **Data-fetching**: server-side only, data fetching will happen in the background and the page will be rendered as soon as possible.
- **Time To First Byte (TTFB)**: faster since the server-side rendering is lighter.
- **Total page load time**: faster since the server-side tends to be faster than the client-side.

## 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
Copy link

Copilot AI Oct 26, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The options parameter should be a function that returns an object with a mode property, but the signature shows it can also be just an object. The example wraps the mode in a function that returns an object, but based on the type signature in create-handler.mdx (line 35), when using a function, it should return { mode: RenderingModes } directly. The current example has an unnecessary wrapper function—it should be (event) => ({ mode: event.request.url.includes(\"/special-route\") ? \"async\" : \"stream\" }).

Suggested change
mode: (event) => {
return { mode: event.request.url.includes("/special-route") ? "async" : "stream" };
}
mode: (event) => ({ mode: event.request.url.includes("/special-route") ? "async" : "stream" })

Copilot uses AI. Check for mistakes.
});
```

It can also be used for bot detection via the `userAgent` property of the `RequestEvent`.

```tsx title="src/entry-server.tsx"
import { createHandler, StartServer } from "@solidjs/start/server";

export default createHandler(() => (
<StartServer document={...} />
), {
mode: (event) => {
return { mode: isBot(event.request.userAgent) ? "async" : "stream" };
}
Comment on lines +106 to +108
Copy link

Copilot AI Oct 26, 2025

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.

Suggested change
mode: (event) => {
return { mode: isBot(event.request.userAgent) ? "async" : "stream" };
}
mode: (event) => ({ mode: isBot(event.request.userAgent) ? "async" : "stream" })

Copilot uses AI. Check for mistakes.
});
```
39 changes: 20 additions & 19 deletions src/routes/solid-start/reference/config/define-config.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -21,11 +21,12 @@ export default defineConfig({
});
```

The `vite` option can also be a function that can be customized for each Vinxi router.
The `vite` option can also be a function that can be customized for each Vinxi router.

In SolidStart, 3 routers are used:

- `server` - server-side routing
- `client` - for the client-side routing
- `client` - for the client-side routing
- `server-function` - server functions.

```tsx
Expand All @@ -44,11 +45,11 @@ export default defineConfig({

## Configuring Nitro

SolidStart uses [Nitro](https://nitro.build/) to run on a number of platforms.
The `server` option exposes some Nitro options including the build and deployment presets.
SolidStart uses [Nitro](https://nitro.build/) to run on a number of platforms.
The `server` option exposes some Nitro options including the build and deployment presets.
An overview of all available presets is available in the [Deploy section of the Nitro documentation](https://nitro.build/deploy).

Some common ones include:
Some common ones include:

**Servers**

Expand Down Expand Up @@ -85,7 +86,7 @@ export default defineConfig({

#### Special note

SolidStart uses async local storage.
SolidStart uses async local storage.
Netlify, Vercel, and Deno support this out of the box but if you're using Cloudflare you will need to specify the following:

```js
Expand All @@ -103,22 +104,22 @@ export default defineConfig({

Within `wrangler.toml` you will need to enable node compatibility:


```
compatibility_flags = [ "nodejs_compat" ]
```

## Parameters

| Property | Type | Default | Description |
| -------------------- | ------------------------------------------ | -------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| ssr | boolean | true | Toggle between client and server rendering. |
| solid | object | | Configuration object for [vite-plugin-solid](https://github.com/solidjs/vite-plugin-solid) |
| extensions | string[] | ["js", "jsx", "ts", "tsx"] | Array of file extensions to be treated as routes. |
| server | object | | Nitro server config options |
| appRoot | string | "./src" | The path to the root of the application. |
| routeDir | string | "./routes" | The path to where the routes are located. |
| middleware | string | | The path to an optional [middleware](/solid-start/advanced/middleware) file. |
| devOverlay | boolean | true | Toggle the dev overlay. |
| experimental.islands | boolean | false | Enable "islands" mode. |
| vite | `ViteConfig` or `({ router })=>ViteConfig` | | [Vite config object](https://vitejs.dev/config/shared-options.html). Can be configured for each `router` which has the string value "server", "client" or "server-function"` |
| Property | Type | Default | Description |
| -------------------- | ------------------------------------------ | ---------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| ssr | boolean | true | Toggle between client and server rendering. |
| mode | stream, async, sync | stream | The rendering mode to use. |
| solid | object | | Configuration object for [vite-plugin-solid](https://github.com/solidjs/vite-plugin-solid) |
| extensions | string[] | js, jsx, ts, tsx | Array of file extensions to be treated as routes. |
| server | object | | Nitro server config options |
| appRoot | string | "./src" | The path to the root of the application. |
| routeDir | string | "./routes" | The path to where the routes are located. |
| middleware | string | | The path to an optional [middleware](/solid-start/advanced/middleware) file. |
| devOverlay | boolean | true | Toggle the dev overlay. |
| experimental.islands | boolean | false | Enable "islands" mode. |
| vite | `ViteConfig` or `({ router })=>ViteConfig` | | [Vite config object](https://vitejs.dev/config/shared-options.html). Can be configured for each `router` which has the string value "server", "client" or "server-function"` |
9 changes: 5 additions & 4 deletions src/routes/solid-start/reference/entrypoints/entry-server.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,12 @@
title: entry-server.tsx
---

`entry-server.tsx` is where an application starts on the server.
This is where application is rendered on the server.
This happens by `entry-server.tsx` providing a document component to [`<StartServer>`](/solid-start/reference/server/start-server) and passing it into [`createHandler`](/solid-start/reference/server/create-handler) for server side rendering.
A typical `entry-server.tsx` for a new project looks like this:

```tsx
Every SolidStart app must have an `entry-server.tsx` file, the most basic usage looks about the following example:

```tsx title="src/entry-server.tsx"
import { createHandler, StartServer } from "@solidjs/start/server";

export default createHandler(() => (
Expand All @@ -29,4 +30,4 @@ export default createHandler(() => (
));
```

For setting different SSR modes (sync | async | stream), see [`createHandler`](/solid-start/reference/server/create-handler).
To take full advantage of the `entry-server.tsx` file, check the [`createHandler` docs](/solid-start/reference/server/create-handler) and the [Rendering Modes](/solid-start/building-your-application/rendering-modes) page.
36 changes: 22 additions & 14 deletions src/routes/solid-start/reference/server/create-handler.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -3,28 +3,36 @@ title: createHandler
---

The `createHandler` is used to start the server in [`entry-server.tsx`](/solid-start/reference/entrypoints/entry-server).
It takes a function that returns a static document (often created with [`<StartServer>`](/solid-start/reference/server/start-server)), and serves it using one of the three function for server side rendering (SSR):
It takes a function that returns a static document (often created with [`<StartServer>`](/solid-start/reference/server/start-server)), renders, and serves it.

- [`renderToString`](/reference/rendering/render-to-string) - "sync"
- [`renderToStringAsync`](/reference/rendering/render-to-string-async) - "async"
- [`renderToStream`](/reference/rendering/render-to-stream) - "stream"
:::note
To fully understand how to leverage different rendering modes, please refer to the [Rendering Modes](/solid-start/building-your-application/rendering-modes) page.
:::

The SSR mode can be configured through the `mode` property on the options object:
A `createHandler` is essential to every SolidStart app.
To fallback the rendering mode to the [`app.config.ts`](/solid-start/reference/entrypoints/app-config-ts) definition (or the default "stream" mode), you can use the `createHandler` without any options.

```tsx
```tsx title="src/entry-server.tsx"
import { createHandler, StartServer } from "@solidjs/start/server";

export default createHandler(() => (
<StartServer document={...}
/>
), {
mode: "async"
});
));
```

## Parameters
It is also possible to [override the rendering mode for a specific route](/solid-start/building-your-application/rendering-modes#per-route-configuration).

## Type Signature

| Argument | Type | Default | Description |
| ------------ | ------------------------ | -------- | ----------------------------------------------------------------- |
| fn | fn: (context: PageEvent) | | A function that returns the static document for your application. |
| options.mode | string | "stream" | The SSR mode. Options are 'sync', 'async' and 'stream'. |
```tsx
type RenderingModes = "stream" | "async" | "sync";

function createHandler(
handler: () => (document: any, options?: any) => void,
options?:
| { mode?: RenderingModes }
| ((event: RequestEvent) => { mode: RenderingModes })
| undefined
): (event: RequestEvent) => Response;
```