You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Commit 1ac0712
Browse filesBrowse the repository at this point in the historyBrowse files
docs(v2): catch up with solid rc.14–next and router next.34–next.40 (#1653)
* reference: regenerate against solid next eb4e0192; dispositions for rc.14-rc.15 exports
New pages: markRaw, onHydrationEnd, dispatchAsInteraction. dynamicComponent,
lazyModule and reportRequestFailure join the dynamic, lazy and
configureServerErrors pages; ssrStyleProperties is compiler ABI and hidden.
The NoArray brand on the seedless derived-store form is dropped from
rendered signatures.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Y4HXPRqXPnqriNxDyin6eK
* docs: catch up hand-written pages with solid rc.14-next and router next.34-next.40
Solid: seedless derived stores and complete seeds (#4073); storePath
recipes become draft setters (#4053); respond() envelope and non-JSON
bodies; performance-tracks defaults; kind "request" and
reportRequestFailure; lowercase on* migration note; dynamicComponent,
lazyModule and onHydrationEnd mentions.
Router: link preloading is opt-in (preloadLinks strategies); data-pending
needs pendingLinks; aria-current matches path and query; decoded params
(#681); useInRouter (#675); action settle timing; liveQuery reference;
anchor attributes typed by the router.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Y4HXPRqXPnqriNxDyin6eK
* docs(router): say held update, not transition, per the Solid Terms table
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Y4HXPRqXPnqriNxDyin6eK
---------
Co-authored-by: Claude <noreply@anthropic.com>
Copy file name to clipboardExpand all lines: src/routes/(2)concepts/(1)components-and-jsx.mdx
+3-1Lines changed: 3 additions & 1 deletion
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -504,7 +504,9 @@ export function Preview() {
504
504
```
505
505
506
506
The source may also resolve to a native tag name or an async component.
507
-
See the [`dynamic()` reference](/reference/solid-web/components/dynamic).
507
+
Because a source may answer with a tag name, one `dynamic` on a page keeps the element runtime in the bundle.
508
+
When the source only ever answers with a component, as `Result` does, `dynamicComponent` from `solid-js` takes the same source and options without that cost; a tag name is a type error there.
509
+
See the [`dynamic()` reference](/reference/solid-web/components/dynamic), which covers both.
Copy file name to clipboardExpand all lines: src/routes/(2)concepts/(2)stores.mdx
+13-13Lines changed: 13 additions & 13 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -150,8 +150,9 @@ Store writes are staged and applied in the same batch as signal writes, so a rea
150
150
[When updates land](/concepts/reactivity#when-updates-land) explains the batch and when to call `flush()`.
151
151
152
152
:::note[Path setters from Solid 1]
153
-
[`storePath`](/reference/solid-js/advanced/store-advanced/store-path) accepts the path-and-value form Solid 1 used, `setCart(storePath("coupon", "SAVE10"))`, for code that has not moved yet.
154
-
New code uses the draft.
153
+
The setter takes no path arguments.
154
+
A Solid 1 path setter such as `setCart("coupon", "SAVE10")` becomes a draft write to the same path, `setCart((draft) => { draft.coupon = "SAVE10"; })`.
155
+
Ranges and filters become ordinary loops over the draft, and setting a key to `undefined` to remove it becomes `delete`.
155
156
:::
156
157
157
158
## Derive a store with a projection
@@ -160,7 +161,8 @@ A projection is a store whose value is computed from other reactive values.
160
161
Where a memo derives one value, a projection derives an object or array whose properties are tracked separately, and whose items keep their identity from one computation to the next.
161
162
162
163
[`createProjection`](/reference/solid-js/stores/create-projection) takes a function and a seed.
163
-
The function receives a draft of the seed and may mutate it or return a replacement; a returned array is reconciled into the store by `id`:
164
+
The function receives a draft of the seed and may mutate it or return a replacement; a returned array is reconciled into the store by `id`.
165
+
The seed is a complete value of the store's type, and an array projection always takes one, `[]`:
164
166
165
167
```tsx
166
168
import { For, createProjection, createSignal, createStore } from"solid-js";
@@ -213,23 +215,23 @@ The projection function may return a promise.
213
215
The function form of `createStore` is a projection with a setter, and it is the normal way to load server data into a store:
The request starts when the store is created, and again whenever a reactive value the function read changes.
222
222
Each response reconciles into the same proxy by `id`, so items the server did not change keep their identity and their DOM.
223
223
A [`Loading`](/concepts/boundaries) boundary shows a fallback before the first response, [`isPending(() => cart.items)`](/reference/solid-js/reactivity/is-pending) reports a refetch, and [`refresh(cart)`](/reference/solid-js/lifecycle-actions/refresh) asks the server again.
224
224
225
-
With an async function, the seed is not shown as a first answer by default; readers wait for the first response the same way they wait for an async memo.
226
-
[Async reactivity](/concepts/async-reactivity) explains that wait, and the `seedLoadingValue` option that makes the seed an acceptable first answer.
225
+
This form takes no seed: the function reads no draft, and each response is a complete cart.
226
+
Readers wait for the first response the same way they wait for an async memo.
227
+
A store with an object root may omit the seed this way; an array root still takes `[]`, and a seed, when given, is a complete value of the store's type, not a partial one.
228
+
[Async reactivity](/concepts/async-reactivity) explains that wait, and the `seedLoadingValue` option that makes a seed an acceptable first answer; that option needs a seed.
227
229
228
230
Split the request into its own memo only when a second reader shapes the same response differently:
Copy file name to clipboardExpand all lines: src/routes/(3)building-apps/(3)server-functions/(3)mutations-and-responses.mdx
+7-3Lines changed: 7 additions & 3 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -41,18 +41,22 @@ export async function createProduct(input: CreateProductInput) {
41
41
```
42
42
43
43
Call `createProduct(input)` from the admin page and the promise resolves to `product`, not to the envelope.
44
-
The transport applies the 201 and the header to the HTTP response, and a plain HTTP caller such as `curl` receives a JSON body with the same product in it.
44
+
`respond<T>()` is typed as `T`, so the function's inferred return type is the product's, and a direct call made on the server during SSR unwraps the envelope the same way.
45
+
The transport applies the 201 and the header to the HTTP response.
46
+
A plain HTTP caller such as `curl` receives a JSON body with the same product in it when JSON carries the value faithfully; a value JSON cannot represent, such as a `bigint`, is encoded the same way as a plain return.
45
47
46
48
:::deep-dive[The envelope on the wire]
47
-
`respond()` returns a `ResponseEnvelope`, an object holding the `Response` that carries the metadata and the `value` the caller should see.
49
+
At runtime `respond()` returns a `ResponseEnvelope`, a `Response` subclass that carries the status, headers, and body, plus the `value` the caller should see.
50
+
Because it is a real `Response`, a fetch-style handler with no Solid knowledge can answer with it as it is.
48
51
The server-function handler forwards the response's status and headers and encodes the value as the body.
49
52
Integration code that has to recognize an envelope, such as a router applying revalidation, uses [`isResponseEnvelope()`](/reference/solid-web/request-response/respond); the check is a registered symbol, so it works when a bundle contains two copies of the runtime.
50
53
Application code never touches the envelope directly.
51
54
:::
52
55
53
56
## Redirect the caller
54
57
55
-
`redirect()` returns a `Response` with a `Location` header:
58
+
`redirect()` returns a `Response` with a `Location` header.
59
+
Its return type defaults to `never`, so a returned redirect drops out of the function's inferred return type; `reload()` is typed the same way:
returnResponse.json({ error: "Internal Server Error" }, { status: 500 });
156
158
}
157
159
}
158
160
```
159
161
160
-
Log the real error and return a generic body.
162
+
Report the real error and return a generic body.
163
+
`reportRequestFailure` hands the error to the server error hook as `kind: "request"`, the same hook that hears render and server-function failures, and logs it with `console.error` when no hook is registered; [Observability](/guides/observability#hear-every-failure-the-server-handles) sets that hook up.
164
+
An error the hook already heard, such as a failed render, is reported once.
161
165
Exception messages can carry database, filesystem, or token details; the only errors whose text belongs in a response are the ones the app marked safe, which [Mutations and responses](/building-apps/server-functions/mutations-and-responses#handle-thrown-errors) covers for server functions.
162
166
Production builds also wrap the generated page render in a default error boundary; set `start.errorBoundary: false` when this middleware owns errors, as [App structure](/building-apps/app-structure#common-problems) notes.
Because the route tree is a literal, `paths.products()` without an argument is a type error, and so is `paths.produts`.
38
38
39
39
`lazy` splits each page into its own chunk.
40
-
The router loads a chunk when a link to it is hovered or when the route is matched, whichever comes first.
40
+
The router loads a chunk when the route is matched, or earlier when a [link preload strategy](/routing/solid-router/data#preloading-from-links) warms it.
`/account/orders/42` matches; `/account/orders/latest` falls through to the next route that matches, usually the `*404` catch-all.
133
133
134
+
Filters test the decoded parameter value, so `{ tag: ["café"] }` matches `/tags/caf%C3%A9`.
135
+
134
136
The built-in `int` filter accepts integer strings at runtime.
135
137
It also changes the corresponding `Router.paths` argument to `number`, so `paths.account.orders(42)` type-checks and `paths.account.orders("latest")` does not.
136
138
@@ -193,7 +195,7 @@ export default defineRoutes([
193
195
```
194
196
195
197
Visit `/` and the admin route table is not downloaded.
196
-
Visit `/admin/products/mug`, or hover a link to it, and the thunk runs, the router adds the resolved subtree to the compiled route tree, and the match completes.
198
+
Visit `/admin/products/mug`, or preload a link to it with a [link preload strategy](/routing/solid-router/data#preloading-from-links), and the thunk runs, the router adds the resolved subtree to the compiled route tree, and the match completes.
197
199
TypeScript infers `paths.admin.products("mug")` through the import's promise type when the imported route array retains literal types.
198
200
199
201
Use a deterministic thunk such as `() => import("./admin/routes")`.
0 commit comments