Skip to content

Commit 773f72c

Browse files
docs: reconcile Learn pages with the Glossary and the source
Cross-page audit driven by the Glossary's six groups. Mechanism fixes: - SILENT_HOLD thresholds are 100/200ms; acknowledged long holds report LONG_HOLD; a revealed Loading boundary still holds. - Optimistic writes show at once inside an action; ordinary writes are held. - A relay effect's write lands in the same flush, not a frame later. - A returned respond() is a result, not an error; throw it for a 400. - A no-JS form post follows the redirect's own status (302 by default); 303 is the flash-back default. - Query adoption is unbounded outside a navigation, 5s inside one. - An isServer tag swap reports Hydration tag mismatch, not structure. - Loading's on is compared with !==. - ASYNC_WATERFALL prints at three flights; two is info only. - A file under src/routes is an API route only with a method export. - Surviving items keep their proxies after a returned filter. - Server functions read a derived event with a copy of locals. - Start mode is not a precondition for the server-function transform. Naming: effect function/phase (not apply), function child (not render prop), pathless route, the static shell is written not prerendered; Glossary aliases move reactive context/scope to Owner, drop derived value from Memo and slots from Children, and Root no longer claims to be ownerless. Co-authored-by: Cursor <cursoragent@cursor.com>
1 parent 03dd759 commit 773f72c

30 files changed

Lines changed: 94 additions & 89 deletions

src/routes/(1)getting-started/(0)quick-start.mdx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -286,7 +286,7 @@ The `flush()` call matters: Solid applies DOM updates in a batch after the event
286286
The [Testing guide](/guides/testing) covers this and the other environments.
287287

288288
Run `npm run build`.
289-
The output is a static site in `dist/client`, with each route in its own chunk.
289+
The output is a set of static files in `dist/client`, with each route in its own chunk.
290290
You can deploy that directory to any static host.
291291
When you later need server rendering or server functions, add `ssr: true` next to `start: true` in `vite.config.ts`; the files you have written carry over unchanged.
292292
[Project shapes](/getting-started/project-shapes) compares `bare`, `basic`, and `fullstack`.

src/routes/(1)getting-started/(1)project-shapes.mdx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ Moving up is a configuration change; moving down means removing code you did not
1919

2020
| Shape | Adds | Build output |
2121
| ----------- | ----------------------------------------------------- | ------------------------------------------------------------ |
22-
| `bare` | Solid, nothing else | `vite build` emits a static site |
22+
| `bare` | Solid, nothing else | `vite build` emits static files |
2323
| `basic` | Router, file-system routes, per-page titles, testing | Still static; deploy `dist/client` to any static host |
2424
| `fullstack` | Streaming SSR, server functions, sessions, API routes | Static client assets plus a request handler in `dist/server` |
2525

@@ -41,7 +41,7 @@ export default defineConfig({
4141
});
4242
```
4343

44-
Without `ssr`, the document shell is prerendered as static HTML and pages render in the browser.
44+
Without `ssr`, the build writes the empty document shell as static HTML and pages render in the browser.
4545
With `ssr: true`, pages stream from the server and hydrate in the browser.
4646
The `src/App.tsx` and `src/Document.tsx` structure does not change.
4747

src/routes/(2)concepts/(2)stores.mdx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -143,8 +143,8 @@ setCart((draft) => {
143143
});
144144
```
145145

146-
A returned or assigned collection is matched by position, not by identity.
147-
If the surviving items must keep their proxies, and therefore their rows, filter inside a [projection](#derive-a-store-with-a-projection) instead, which reconciles by key.
146+
A returned or assigned collection replaces the array by index, and the items that survive are the same objects, so their proxies and their rows are kept.
147+
When the new array holds new objects, such as a fresh server response, nothing matches them to the old ones; reconcile that inside a [projection](#derive-a-store-with-a-projection) with a key, or with `reconcile`.
148148

149149
Store writes are staged and applied in the same batch as signal writes, so a read on the next line sees the previous value until the batch lands.
150150
[When updates land](/concepts/reactivity#when-updates-land) explains the batch and when to call `flush()`.

src/routes/(2)concepts/(4)boundaries.mdx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,7 @@ Without it, choosing a new product keeps the old product on screen while the new
9191
Pending work caused by anything else, such as a refresh of the same product, leaves the content in place.
9292

9393
:::pitfall[Passing the accessor to on instead of its value]
94-
`on` is compared by value across updates.
94+
`on` is compared with `!==` across updates, so pass a primitive; join several inputs into one string rather than passing an array.
9595

9696
```tsx
9797
// Avoid: the function reference never changes, so the fallback never returns

src/routes/(2)concepts/(6)rendering-and-ssr.mdx

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -141,7 +141,7 @@ onSettled(() => setRenderedAt(Date.now()));
141141
</p>;
142142
```
143143

144-
The `Avoid` version logs, in development, a warning such as `Hydration structure mismatch: expected <time> as first child of` followed by the node it found instead, and the client's bindings for that region attach to the wrong nodes.
144+
The `Avoid` version logs, in development, a warning such as `Hydration tag mismatch for key "...": expected <time> but found` followed by the `<p>` it found instead, and the client's bindings for that region attach to the wrong node.
145145
The `Prefer` version hydrates cleanly and updates the text once the browser has taken over.
146146
A value that differs only in its text, such as `<p>{Date.now()}</p>`, produces no warning: hydration adopts the server's text node as it is, so the page keeps showing the server's value until a reactive update replaces it.
147147
[SSR-safe code](/guides/ssr-safe-code#values-that-differ-on-every-run) goes through these cases and how to read each warning.
@@ -297,9 +297,9 @@ A module or component body reads a browser API while the server renders.
297297
Move the read into an effect function or an `onSettled` callback, guard it with `isServer`, or wrap the component in `clientOnly`.
298298
See [Server and client boundaries](#server-and-client-boundaries).
299299

300-
### `Hydration structure mismatch` or `Hydration key miss` in the console
300+
### `Hydration tag mismatch`, `Hydration structure mismatch`, or `Hydration key miss` in the console
301301

302-
The server and the client rendered different elements for the same region: a conditional on `isServer` that picks a different tag, a `Show` whose condition depends on `Math.random()`, or data that differs between the request and the browser.
302+
The server and the client rendered different elements for the same region: a conditional on `isServer` that picks a different tag reports a tag mismatch; a `Show` whose condition depends on `Math.random()`, or data that differs between the request and the browser, reports a structure mismatch inside the template.
303303
Render the same structure on both sides and fill in browser-only values after hydration; [Reading the hydration warnings](/guides/ssr-safe-code#reading-the-hydration-warnings) explains what each message checks.
304304
A key miss whose message mentions namespaces means a subtree was hydrated with a different `renderId` than the server used; see [Controlling hydration](#controlling-hydration).
305305

src/routes/(3)building-apps/(0)app-structure.mdx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ export default defineConfig({
3131
The three modes the [Choose a rendering mode](/guides/choose-a-rendering-mode) guide compares all use the same `App` and `Document` files:
3232

3333
- A static shell rendered in the browser, the default without `ssr`.
34-
The build prerenders `Document` without the app into `dist/client/index.html`, and the generated client entry calls `render()` to mount `App` into `document.body`.
34+
The build writes `Document` without the app into `dist/client/index.html`, and the generated client entry calls `render()` to mount `App` into `document.body`.
3535
Without server functions the build removes `dist/server`, so `dist/client` deploys to any static host.
3636
- Streaming server rendering, with `ssr: true`.
3737
Each request renders `<Document><App /></Document>` on the server and streams it; the generated client entry calls `hydrate()` on the same tree.

src/routes/(3)building-apps/(3)server-functions/(0)index.mdx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -214,7 +214,7 @@ Move that read into a server function, or put the import in a `"use server"` mod
214214

215215
### The function body runs in the browser
216216

217-
The `serverFunctions` option is off, or the project is not in start mode.
217+
The `serverFunctions` option is off.
218218
Without the transform, `"use server"` is a string expression the engine evaluates and ignores, and the body runs wherever it is called.
219219
Check `vite.config.ts` against the [Enable server functions](#enable-server-functions) section.
220220

src/routes/(3)building-apps/(3)server-functions/(3)mutations-and-responses.mdx

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,7 @@ Both reach the caller the same way.
7575

7676
What the browser does next depends on who made the call.
7777
A Solid Router `action()` navigates to `/goodbye` without a page load.
78-
An HTML form post without JavaScript is answered with a 303 and the browser follows it.
78+
An HTML form post without JavaScript is answered with the redirect itself, 302 by default, and the browser follows it.
7979
Plain code that called `deleteAccount()` directly receives the `Response` object as the resolved value, because the transport hands navigation metadata back whole for the caller to apply.
8080

8181
The target can be a string or an `Href` produced by a router's typed paths helper; a branded `Href` redirects to its logical path.
@@ -197,7 +197,7 @@ export const addToCartAction = action(addToCart);
197197
```
198198

199199
Render `<form method="post" action={addToCartAction}>` and the form posts to the function's URL before JavaScript loads; after hydration the router intercepts the submit, calls the function over the transport, and applies the `reload`.
200-
The router tracks the submission while it runs and turns the thrown envelope's value into `submission.error`, which the [Forms guide](/guides/forms) reads to show messages next to the fields.
200+
The router marks the form `aria-busy` while it runs and, once it settles, records a submission whose `error` is the thrown envelope's value, which the [Forms guide](/guides/forms) reads to show messages next to the fields.
201201

202202
Keep the server function a named export and wrap it separately, as above, so a test or an API route can call `addToCart` without the form.
203203
When the function exists only for the form, write the body inline, `action(async (form: FormData) => { "use server"; ... })`; the [Data loading and mutations](/routing/solid-router/data#mutate-with-actions) page uses that shape throughout, and the two behave the same.
@@ -236,7 +236,7 @@ Pass a string path, or the value a router's typed paths helper returns.
236236
## Recap
237237

238238
- Return a plain value when the caller needs data and nothing else; use `respond()` to add a status or headers to it.
239-
- Return or throw `redirect(path)`; a router action navigates, a form post follows a 303, and direct code receives the `Response`.
239+
- Return or throw `redirect(path)`; a router action navigates, a form post follows the redirect, and direct code receives the `Response`.
240240
- Return `reload({ revalidate })` after a write so the router refetches the named reads.
241241
- Throw `respond(value, { status })` for a failure the caller should see; a returned envelope resolves the caller whatever its status.
242242
- A plain thrown value becomes `Internal Server Error` in production; `markSafeError()` opts one `Error` out of that.

src/routes/(3)building-apps/(3)server-functions/(5)progressive-enhancement.mdx

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ const addToCartAction = action(addToCart);
5252
```
5353

5454
Load the page with JavaScript disabled and submit.
55-
The browser posts to the function's URL, the server runs `addToCart`, and the 303 it answers sends the browser to `/cart`.
55+
The browser posts to the function's URL, the server runs `addToCart`, and the redirect it answers sends the browser to `/cart`.
5656
With JavaScript on, the router intercepts the submit, calls the function over the transport, and navigates to `/cart` without a page load.
5757

5858
The wiring that makes this work is the form, not the handler:
@@ -177,7 +177,7 @@ Bind a string or number and convert inside the function, or pass the value throu
177177
### The form submits but the page reloads instead of staying put
178178

179179
The router is not mounted around the form, so nothing intercepts the submit and the browser follows the `action` URL as a full-page navigation.
180-
The result is still correct, because the function ran and the 303 was followed; mount the form inside the `Router` to get the scripted path.
180+
The result is still correct, because the function ran and the redirect was followed; mount the form inside the `Router` to get the scripted path.
181181

182182
### The 400 shows nothing after a no-JavaScript submit
183183

@@ -190,7 +190,7 @@ Solid Router reads the cookie on the next server render and records the submissi
190190
- Put every mutation behind `<form method="post" action={...}>` so the browser can submit it before the client bundle runs.
191191
- Wrap the server function with the router's `action()`; it serializes to the function's plain-HTTP URL and takes over after hydration.
192192
- Pending state, `useSubmissions`, and `.onSubmit` optimistic writes are layers the hydrated page adds; the HTML and the server function stay the same.
193-
- A browser form post is answered with a 303 and a flash cookie; the router turns the cookie into a submission on the next render.
193+
- A browser form post follows a returned redirect; any other outcome is answered with a 303 back to the page and a flash cookie, which the router turns into a submission on the next render.
194194
- Use `method="get"` and `fn.url` only for a `GET()` read; the function receives the fields as `URLSearchParams`.
195195
- `url` is on every reference at runtime and only on `GET()` and `live()` references in the type.
196196
- Bound arguments travel in the `args` query parameter and must be JSON-safe.

src/routes/(3)building-apps/(4)sessions-and-auth.mdx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -250,7 +250,7 @@ async function attachCustomer(
250250
}
251251
```
252252

253-
Server functions, API handlers, and the page render for that request read the same event, so `locals.userId` set here is visible to all of them.
253+
Server functions, API handlers, and the page render for that request read that request's event, so `locals.userId` set here is visible to all of them; a server function called during the render gets a derived event with a copy of `locals`, so what it writes stays with the call.
254254
Augment `RequestEventLocals` from `@solidjs/web` when the application wants a precise type for those fields:
255255

256256
```ts

0 commit comments

Comments
 (0)