diff --git a/src/routes/solid-router/reference/response-helpers/json.mdx b/src/routes/solid-router/reference/response-helpers/json.mdx index b2668eee8..a6bf91a8c 100644 --- a/src/routes/solid-router/reference/response-helpers/json.mdx +++ b/src/routes/solid-router/reference/response-helpers/json.mdx @@ -7,38 +7,134 @@ tags: - json - api - actions - - cache + - queries - revalidation - response -version: '1.0' +version: "1.0" description: >- - Return JSON data from actions with cache revalidation control. Configure how + Return JSON data from actions with query revalidation control. Configure how route data updates after mutations for optimal performance. --- -Returns JSON data from an action while also providing options for controlling revalidation of cache data on the route. +The `json` function returns a [`Response`](https://developer.mozilla.org/en-US/docs/Web/API/Response) object that contains the provided data. +It is intended for sending JSON data from a [query](/solid-router/reference/data-apis/query) or [action](/solid-router/concepts/actions) while also allowing configuration of query revalidation. -```ts title="/actions/get-completed-todos.ts" {7} -import { action, json } from "@solidjs/router"; -import { fetchTodo } from "../fetchers"; +This works both in client and server (e.g., using a server function) environments. -const getCompletedTodos = action(async () => { - const completedTodos = await fetchTodo({ status: 'complete' }); +## Import - return json(completedTodos, { revalidate: getTodo.keyFor(id) }); -}); +```ts +import { json } from "@solidjs/router"; ``` -Also read [action](/solid-router/reference/data-apis/action) and [revalidate](/solid-router/reference/response-helpers/revalidate). +## Type -## Type Signature +```ts +function json( + data: T, + init: { + revalidate?: string | string[]; + headers?: HeadersInit; + status?: number; + statusText?: string; + } = {} +): CustomResponse; +``` + +## Parameters + +### `data` + +- **Type:** `T` +- **Required:** Yes + +The data to be serialized as JSON in the response body. +It must be a value that can be serialized with [`JSON.stringify`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/stringify). + +### `init` + +- **Type:** `{ revalidate?: string | string[]; headers?: HeadersInit; status?: number; statusText?: string; }` +- **Required:** No + +An optional configuration object with the following properties: + +#### `revalidate` + +- **Type:** `string | string[]` +- **Required:** No + +A query key or an array of query keys to revalidate. +Passing an empty array (`[]`) disables query revalidation entirely. + +#### `headers` + +- **Type:** `HeadersInit` +- **Required:** No + +An object containing any headers to be sent with the response. + +#### `status` -```typescript -interface ResponseOptions & Omit { - revalidate?: string | string[]; +- **Type:** `number` +- **Required:** No + +The HTTP status code of the response. +Defaults to [`200 OK`](http://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Status/200). + +#### `statusText` + +- **Type:** `string` +- **Required:** No + +The status text associated with the status code. + +## Examples + +### Invalidating Data After a Mutation + +```tsx +import { For } from "solid-js"; +import { query, action, json, createAsync } from "@solidjs/router"; + +const getCurrentUserQuery = query(async () => { + return await fetch("/api/me").then((response) => response.json()); +}, "currentUser"); + +const getPostsQuery = query(async () => { + return await fetch("/api/posts").then((response) => response.json()); +}, "posts"); + +const createPostAction = action(async (formData: FormData) => { + const title = formData.get("title")?.toString(); + const newPost = await fetch("/api/posts", { + method: "POST", + body: JSON.stringify({ title }), + }).then((response) => response.json()); + + // Only revalidate the "posts" query. + return json(newPost, { revalidate: "posts" }); +}, "createPost"); + +function Posts() { + const currentUser = createAsync(() => getCurrentUserQuery()); + const posts = createAsync(() => getPostsQuery()); + + return ( +
+

Welcome back {currentUser()?.name}

+
    + {(post) =>
  • {post.title}
  • }
    +
+
+ + +
+
+ ); } +``` -json(data: T, opt?: ResponseOptions): CustomResponse; -``` +## Related -The `ResponseOptions` extens the types from the native [`ResponseInit`](https://developer.mozilla.org/en-US/docs/Web/API/Response/Response#options) interface. +- [`query`](/solid-router/reference/data-apis/query) +- [`action`](/solid-router/reference/data-apis/action) diff --git a/src/routes/solid-router/reference/response-helpers/redirect.mdx b/src/routes/solid-router/reference/response-helpers/redirect.mdx index 394193965..57535bcb9 100644 --- a/src/routes/solid-router/reference/response-helpers/redirect.mdx +++ b/src/routes/solid-router/reference/response-helpers/redirect.mdx @@ -10,89 +10,106 @@ tags: - routing - authorization - forms -version: '1.0' +version: "1.0" description: >- Redirect users between routes with proper status codes. Handle authentication flows, form submissions, and protected route access. --- -Redirects to the next route. -When done over a server RPC (Remote Procedure Call), the redirect will be done through the server. -By default the status code of a `redirect()` is `302 - FOUND`, also known as a temporary redirect. +The `redirect` function returns a [`Response`](https://developer.mozilla.org/en-US/docs/Web/API/Response) object that instructs the router to navigate to a different route when returned or thrown from a [query](/solid-router/reference/data-apis/query) or [action](/solid-router/concepts/actions). -Other useful redirect codes: +This works both in client and server (e.g., using a server function) environments. -| Code | Description | -| ---- | ----------- | -| `301` | Moved Permanently | -| `307` | Temporary Redirect | -| `308` | Permanent redirect | +## Import -:::tip[Redirect Methods] -307 and 308 won't allow the browser to change the method of the request. -If you want to change the method, you should use 301 or 302. -::: +```ts +import { redirect } from "@solidjs/router"; +``` -A common use-case for throwing a redirect is when a user is not authenticated and needs to be sent to the login page or another public route. +## Type -```js title="/queries/get-user.ts" {7} -import { query, redirect } from "@solidjs/router"; -import { getCurrentUser } from "../auth"; - -const getUser = query(() => { - const user = await getCurrentUser(); - - if (!user) throw redirect("/login"); - - return user; -}, "get-user") +```ts +function redirect( + url: string, + init?: + | number + | { + revalidate?: string | string[]; + headers?: HeadersInit; + status?: number; + statusText?: string; + } +): CustomResponse; ``` -## Single-Flight Mutations +## Parameters -When using `redirect` during a Server Action, the redirect will be done through the server. -The response value will automatically send data for the destination route, avoiding a subsequent roundtrip to load the data from the target route. +### `url` -This is useful when redirecting the user to a different route once a mutation is done. +- **Type:** `string` +- **Required:** Yes -```ts title="/actions/add-user.ts" {3,6} -import { action, redirect } from "@solidjs/router"; +The absolute or relative URL to which the redirect should occur. -const addUser = action(async (user: User) => { - await postUser(user); - - return redirect("/users"); -}); -``` +### `init` -The `addUser` action will redirect the user to the `/users` route once the user has been added to the database. -The response from the form action will send the updated data for the `/users` route without the developer needing to revalidate or reload. +- **Type:** `number | { revalidate?: string | string[]; headers?: HeadersInit; status?: number; statusText?: string; }` +- **Required:** No -## Throw vs Return +Either a number representing the status code or a configuration object with the following properties: -Both `throw` and `return` can be used to redirect the user to a different route. -For general usage `throw` is recommended as it immediately stops the execution of the current action and redirects the user. +#### `revalidate` -When returning from a nested method, the parent method will continue to execute, which can lead to unexpected behavior. +- **Type:** `string | string[]` +- **Required:** No -### TypeScript Signature +A query key or an array of query keys to revalidate on the destination route. -```typescript -type RouterResponseInit = Omit & { - revalidate?: string | string[]; -}; +#### `status` -function redirect(url: string, init?: number | RouterResponseInit): CustomResponse; -``` +- **Type:** `number` +- **Required:** No -The `RouterResponseInit` type extends the native [`ResponseInit`](https://developer.mozilla.org/en-US/docs/Web/API/Response/Response#options) interface. +The HTTP status code for the redirect. +Defaults to [`302 Found`)](https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Status/302). -## Revalidate Query Keys +## Examples -You can pass query keys to the redirect helper to revalidate them. +### Basic Usage ```ts -redirect("/", { revalidate: ["getUser", getUser.keyFor(id)] }); +import { query, redirect } from "@solidjs/router"; + +const getCurrentUserQuery = query(async () => { + const response = await fetch("/api/me"); + + if (response.status === 401) { + return redirect("/login"); + } + + return await response.json(); +}, "currentUser"); ``` -This will only invalidate the query keys passed to the redirect helper instead of the entire next page. +### Configuring Query Revalidation + +```ts +import { action, redirect } from "@solidjs/router"; + +const loginAction = action(async (formData: FormData) => { + const username = formData.get("username")?.toString(); + const password = formData.get("password")?.toString(); + + await fetch("/api/login", { + method: "POST", + body: JSON.stringify({ username, password }), + }).then((response) => response.json()); + + return redirect("/users", { revalidate: ["currentUser"] }); +}, "login"); +``` + +## Related + +- [`query`](/solid-router/reference/data-apis/query) +- [`action`](/solid-router/reference/data-apis/action) diff --git a/src/routes/solid-router/reference/response-helpers/reload.mdx b/src/routes/solid-router/reference/response-helpers/reload.mdx index 4a7f2546d..94c390963 100644 --- a/src/routes/solid-router/reference/response-helpers/reload.mdx +++ b/src/routes/solid-router/reference/response-helpers/reload.mdx @@ -10,37 +10,80 @@ tags: - mutations - queries - refresh -version: '1.0' +version: "1.0" description: >- Reload and revalidate specific queries after mutations. Efficiently update cached data without full page refreshes for better UX. --- -Reload is a response helper built on top of [revalidate](/solid-router/reference/response-helpers/revalidate). -It will receive a query key, or an array of query keys, to invalidate those queries, and cause them to fire again. +The `reload` function returns a [`Response`](https://developer.mozilla.org/en-US/docs/Web/API/Response) object that instructs the router to revalidate specific queries when returned or thrown from a [query](/solid-router/reference/data-apis/query) or [action](/solid-router/concepts/actions). -```ts title="/actions/update-todo.ts" {7} -import { action, reload } from "@solidjs/router"; -import { putTodo, getTodo } from "../db"; +## Import -const updateTodo = action(async (todo: Todo) => { - await putTodo(todo.id, todo); - - return reload({ revalidate: getTodo.keyFor(id) }); -}); +```ts +import { reload } from "@solidjs/router"; ``` -The code snippet above uses the query key from a user-defined query (`getTodo`). -To better understand how queries work, check the [query](/solid-router/reference/data-apis/query) documentation. +## Type + +```ts +function reload(init?: { + revalidate?: string | string[]; + headers?: HeadersInit; + status?: number; + statusText?: string; +}): CustomResponse; +``` + +## Parameters + +### `init` + +- **Type:** `{ revalidate?: string | string[]; headers?: HeadersInit; status?: number; statusText?: string; }` +- **Required:** No + +An optional configuration object with the following properties: + +#### `revalidate` + +- **Type:** `string | string[]` +- **Required:** No + +A query key or an array of query keys to revalidate. + +#### `headers` -## TypeScript Signature +- **Type:** `HeadersInit` +- **Required:** No + +An object containing any headers to be sent with the response. + +#### `status` + +- **Type:** `number` +- **Required:** No + +The HTTP status code of the response. +Defaults to [`200 OK`](http://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Status/200). + +#### `statusText` + +- **Type:** `string` +- **Required:** No + +The status text associated with the status code. + +## Examples + +### Basic Usage ```ts -interface ResponseOptions & Omit { - revalidate?: string | string[]; -} +import { action, reload } from "@solidjs/router"; -reload(opt?: ResponseOptions): CustomResponse; -``` +const savePreferencesAction = action(async () => { + // ... Saves the user preferences. -The `ResponseOptions` extends the types from the native [`ResponseInit`](https://developer.mozilla.org/en-US/docs/Web/API/Response/Response#options) interface. + // Only revalidate the "userPreferences" query. + return reload({ revalidate: ["userPreferences"] }); +}, "savePreferences"); +```