diff --git a/src/routes/solid-router/concepts/actions.mdx b/src/routes/solid-router/concepts/actions.mdx index 53a96da9c5..1e6982aa17 100644 --- a/src/routes/solid-router/concepts/actions.mdx +++ b/src/routes/solid-router/concepts/actions.mdx @@ -49,8 +49,8 @@ In [SolidStart](/solid-start) apps, it's recommended to use the [`"use server"`] ### Using actions -To use the action, you can call it from within a component using [`useAction`](/solid-router/reference/data-apis/use-action). -This returns a function that can be called with the necessary arguments to trigger the action. +With [`useAction`](/solid-router/reference/data-apis/use-action), you can invoke an action from a component. +It returns a function that triggers the action, allowing you to include any parameters needed by the function wrapped by `action`. ```tsx del={1} ins={2,9-13} import { action } from "@solidjs/router"; diff --git a/src/routes/solid-router/concepts/dynamic-routes.mdx b/src/routes/solid-router/concepts/dynamic-routes.mdx index aba2b544e5..1059a4d5df 100644 --- a/src/routes/solid-router/concepts/dynamic-routes.mdx +++ b/src/routes/solid-router/concepts/dynamic-routes.mdx @@ -47,8 +47,7 @@ This allows for more complex routing descriptions rather than just checking the ```jsx import { lazy } from "solid-js"; import { render } from "solid-js/web"; -import { Router, Route } from "@solidjs/router"; -import type { SegmentValidators } from "./types"; +import { Router, Route, type MatchFilters } from "@solidjs/router"; const User = lazy(() => import("./pages/User")); diff --git a/src/routes/solid-router/concepts/path-parameters.mdx b/src/routes/solid-router/concepts/path-parameters.mdx index 4d7ff707e7..054a791de2 100644 --- a/src/routes/solid-router/concepts/path-parameters.mdx +++ b/src/routes/solid-router/concepts/path-parameters.mdx @@ -51,7 +51,7 @@ import { lazy } from "solid-js"; import { render } from "solid-js/web"; import { Router, Route } from "@solidjs/router"; -const User = import("./pages/User"); +const User = lazy(() => import("./pages/User")); const filters = { parent: ["mom", "dad"], // allow enum values @@ -119,3 +119,4 @@ In this case, `rest` will contain the rest of the path after `/users/`. It is important to note that wildcard routes must be located at the **end of the path**. If you place a wildcard route before the end, such as `/users/*rest/:id`, no routes will be matched. + diff --git a/src/routes/solid-router/index.mdx b/src/routes/solid-router/index.mdx index d75f93c719..b03c0ffca7 100644 --- a/src/routes/solid-router/index.mdx +++ b/src/routes/solid-router/index.mdx @@ -5,11 +5,11 @@ title: Overview # Overview :::note[Prerequisites] - The docs are based on latest Solid Router. + The docs are based on the latest version of Solid Router. To use this version, you need to have Solid v1.8.4 or later installed. ::: -Solid Router is the universal router for Solid which works for rendering on the client or the server. +Solid Router is the universal router for Solid, supporting rendering on both the client and the server. It was inspired by and combines paradigms of [React Router](https://reactrouter.com/en/main) and the [Ember Router](https://guides.emberjs.com/release/routing/). A router provides a way to change a user's view based on the URL in the browser. diff --git a/src/routes/solid-router/reference/components/a.mdx b/src/routes/solid-router/reference/components/a.mdx index e09be7df16..0e92fc03cf 100644 --- a/src/routes/solid-router/reference/components/a.mdx +++ b/src/routes/solid-router/reference/components/a.mdx @@ -3,7 +3,7 @@ title: A --- Solid Router exposes the `` component as a wrapper around the [native anchor tag ](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/a). -It relies on the routing context provided by the [`` component](/solid-router/reference/components/router) and if used outside, will triggers a runtime error.. +It relies on the routing context provided by the [`` component](/solid-router/reference/components/router) and if used outside it will trigger a runtime error. `` supports relative and base paths. `` doesn't. But `` gets augmented when JS is present via a top-level listener to the DOM, so you get the diff --git a/src/routes/solid-router/reference/components/hash-router.mdx b/src/routes/solid-router/reference/components/hash-router.mdx index 168edac886..28d5c09910 100644 --- a/src/routes/solid-router/reference/components/hash-router.mdx +++ b/src/routes/solid-router/reference/components/hash-router.mdx @@ -2,15 +2,13 @@ title: HashRouter --- -The `HashRouter` is a top level component that manages the routing of your application. -It is a client side router that uses hash-values in the URL - providing a single-page application a way to replicate the experience of a multi-page application. +The `HashRouter` is a top-level component that manages the routing of your application. It is a client-side router that uses the hash portion of the URL, allowing a single-page application to mimic the experience of a multi-page site. -Since hash-routing provides a way for an application to run from a single HTML file, it can be used when hosting on a static file server. +Hash routing enables an application to run from a single HTML file, making it suitable for hosting on static file servers. -Compared to a browser-router, such as [`Router`](/solid-router/reference/components/router), is that this approach is not SEO friendly. -Because most search engines do not index the hash portion of a URL, they are only able to see the index page of your application when using this approach. +However, compared to a browser router like [`Router`](/solid-router/reference/components/router), this approach is not SEO-friendly. Most search engines do not index the hash portion of URLs, so they can only crawl the index page of your application. -The `root` property is used for components that wrap a matched route and require access to the router context, relevant with navigation components that use [``](/solid-router/reference/components/a) links. +The `root` prop is used for layout components that wrap matched routes and need access to the router context. This is particularly useful for navigation components that include [``](/solid-router/reference/components/a) links. ```tsx import { render } from "solid-js/web"; diff --git a/src/routes/solid-router/reference/data-apis/action.mdx b/src/routes/solid-router/reference/data-apis/action.mdx index 8f3a5e666a..f63230344e 100644 --- a/src/routes/solid-router/reference/data-apis/action.mdx +++ b/src/routes/solid-router/reference/data-apis/action.mdx @@ -112,7 +112,7 @@ const submission = useSubmission(action, (input) => filter(input)); ## Revalidate cached functions ### Revalidate all (default) -By default all cached functions will be revalidated wether the action does not return or return a "normal" response. +By default all cached functions will be revalidated whether the action does not return or return a "normal" response. ```jsx @@ -120,7 +120,7 @@ const deleteTodo = action(async (formData: FormData) => { const id = Number(formData.get("id")) await api.deleteTodo(id) // ... - return new Response("success", { status: 200 }); + return new Response("success", { status: 200 }); }) ``` @@ -136,15 +136,15 @@ const deleteTodo = action(async (formData: FormData) => { const id = Number(formData.get("id")) await api.deleteTodo(id) return json( - { deleted: id }, - { revalidate: ["getAllTodos", getTodos.key, getTodoByID.keyFor(id)]} + { deleted: id }, + { revalidate: ["getAllTodos", getTodos.key, getTodoById.keyFor(id)]} ) //or - return reload({ revalidate: ["getAllTodos", getTodos.key, getTodoByID.keyFor(id)]}) + return reload({ revalidate: ["getAllTodos", getTodos.key, getTodoById.keyFor(id)]}) //or - return redirect("/", { revalidate: ["getAllTodos", getTodos.key, getTodoByID.keyFor(id)]}) + return redirect("/", { revalidate: ["getAllTodos", getTodos.key, getTodoById.keyFor(id)]}) }) @@ -158,7 +158,7 @@ const deleteTodo = action(async (formData: FormData) => { const id = Number(formData.get("id")) await api.deleteTodo(id) // returns a `json` without revalidating the action. - return json(`deleted ${id}`,{ revalidate: "nothing" }) + return json(`deleted ${id}`, { revalidate: "nothing" }) // or reload the route without revalidating the request. return reload({ revalidate: "nothing" }) @@ -174,21 +174,20 @@ const deleteTodo = action(async (formData: FormData) => { Cached functions can also be revalidated by the `revalidate` helper. ```jsx -revalidate([getTodos.key, getTodoByID.keyFor(id)]) +revalidate([getTodos.key, getTodoById.keyFor(id)]) ``` This is also great if you want to set your own "refresh" interval e.g. poll data every 30 seconds. ```jsx -export default function TodoLayout(){ - - const todos = createAsync(() => getTodos()) +export default function TodoLayout() { + const todos = createAsync(() => getTodos()); onMount(() => { - //30 second polling - const interval = setInterval(() => revalidate(getTodos.key),1000 * 30) - onCleanup(() => clearInterval(interval)) + // 30 second polling + const interval = setInterval(() => revalidate(getTodos.key), 1000 * 30); + onCleanup(() => clearInterval(interval)); }) // ... diff --git a/src/routes/solid-router/reference/data-apis/create-async.mdx b/src/routes/solid-router/reference/data-apis/create-async.mdx index c8b7b833dc..c6fedca507 100644 --- a/src/routes/solid-router/reference/data-apis/create-async.mdx +++ b/src/routes/solid-router/reference/data-apis/create-async.mdx @@ -12,7 +12,7 @@ Reading it before it is ready causes Suspense/Transitions to trigger. ::: This is light wrapper over [`createResource`](/reference/basic-reactivity/create-resource) which serves as a stand-in for a future primitive being brought to Solid core in 2.0. -It is recommended that `createAsync` be used in favor of `createResource` specially when in a **SolidStart** app because `createAsync` works better in conjunction with the [cache](/solid-router/reference/data-apis/cache) helper. +It is recommended that `createAsync` be used in favor of `createResource` especially in a **SolidStart** app because `createAsync` works better in conjunction with the [query](/solid-router/reference/data-apis/query) helper. @@ -21,7 +21,7 @@ import { createAsync } from "@solidjs/router"; import { Suspense } from "solid-js"; import { getUser } from "./api"; -export function Component () => { +export function Component() { const user = createAsync(() => getUser(params.id)); return ( diff --git a/src/routes/solid-router/reference/data-apis/revalidate.mdx b/src/routes/solid-router/reference/data-apis/revalidate.mdx index 0319ba41d0..f184991bb4 100644 --- a/src/routes/solid-router/reference/data-apis/revalidate.mdx +++ b/src/routes/solid-router/reference/data-apis/revalidate.mdx @@ -10,9 +10,9 @@ import { For } from "solid-js"; import { query, createAsync, revalidate } from "@solidjs/router"; const getPosts = query(async () => { - return await fetch("https://api.com/posts").then((response) => - response.json() - ); + const response = await fetch("https://api.com/posts"); + const data = await response.json(); + return data; }, "posts"); function Posts() { diff --git a/src/routes/solid-router/reference/data-apis/use-submission.mdx b/src/routes/solid-router/reference/data-apis/use-submission.mdx index 7153e664cd..a2aa0ef38d 100644 --- a/src/routes/solid-router/reference/data-apis/use-submission.mdx +++ b/src/routes/solid-router/reference/data-apis/use-submission.mdx @@ -13,14 +13,12 @@ import { useSubmission } from "@solidjs/router"; function Component() { const submission = useSubmission(postNameAction); - return ( - - - - {submission.pending ? "Adding..." : "Add"} - - - ) + return ( + + + {submission.pending ? "Adding..." : "Add"} + + ); } ``` @@ -31,27 +29,24 @@ Learn more about actions in the [`action`](/solid-router/reference/data-apis/act ## Filtering Submissions As an optional second parameter, the `useSubmission` helper can receive a filter function to only return the submission that matches the condition. -The filter receives the submitted dated as a parameter and should return a boolean value. -E.g.: action below will only submit if the name is "solid". +The filter receives the submitted data as a parameter and should return a boolean value. +The action below will only submit if the name is "solid". -```tsx title="component.tsx" {4-8} +```tsx title="component.tsx" {4-7} import { useSubmission } from "@solidjs/router"; function Component() { - const submission = useSubmission(postNameAction, ([formData]) => { - const name = formData.get("name") ?? ""; - - return name === "solid"; - }); - - return ( - - - - {submission.pending ? "Adding..." : "Add"} - - - ) + const submission = useSubmission( + postNameAction, + ([formData]) => formData.get("name") === "solid" + ); + + return ( + + + {submission.pending ? "Adding..." : "Add"} + + ); } ``` @@ -61,61 +56,59 @@ When the form is submitted, the `submission` object will be updated with the new This allows you to provide feedback to the user that the action is in progress. Once the action is complete, the `pending` property will be set to `false` and the `result` property will be updated with final value. -```tsx tab title="TypeScript" {6,10-12} -// component.tsx +```tsx tab title="TypeScript" {5,9-11} import { Show } from "solid-js"; import { useSubmission } from "@solidjs/router"; function Component() { const submission = useSubmission(postNameAction); - return ( - <> - - {(name) => Optimistic: {name() as string}} - - - - {(name) => Result: {name()}} - - - - - - {submission.pending ? "Submitting" : "Submit"} - - - > - ) + return ( + <> + + {(name) => Optimistic: {name() as string}} + + + + {(name) => Result: {name()}} + + + + + + {submission.pending ? "Submitting" : "Submit"} + + + > + ); } ``` -```tsx tab title="JavaScript" {6,10-12} -// component.jsx +```tsx tab title="JavaScript" {5,9-11} import { Show } from "solid-js"; import { useSubmission } from "@solidjs/router"; function Component() { const submission = useSubmission(postNameAction); - return ( - <> - - {(name) => Optimistic: {name()}} - - - - {(name) => Result: {name()}} - - - - - - {submission.pending ? "Submitting" : "Submit"} - - - > - ) + return ( + <> + + {(name) => Optimistic: {name()}} + + + + {(name) => Result: {name()}} + + + + + + {submission.pending ? "Submitting" : "Submit"} + + + > + ); } ``` @@ -126,36 +119,32 @@ This allows you to provide feedback to the user that the action has failed. Addi At this stage, you can also use the `retry()` method to attempt the action again or the `clear()` to wipe the filled data in the platform. -```tsx title="component.tsx" {12-18} +```tsx title="component.tsx" {12-14} import { Show } from "solid-js"; import { useSubmission } from "@solidjs/router"; function Component() { const submission = useSubmission(postNameAction); - return ( - <> - - {(error) => ( - - Error: {error.message} - submission.clear()}> - Clear - - submission.retry()}> - Retry - - - )} - - - - - - {submission.pending ? "Submitting" : "Submit"} - - - > - ) + return ( + <> + + {(error) => ( + + Error: {error.message} + submission.clear()}>Clear + submission.retry()}>Retry + + )} + + + + + + {submission.pending ? "Submitting" : "Submit"} + + + > + ); } ``` diff --git a/src/routes/solid-router/reference/data-apis/use-submissions.mdx b/src/routes/solid-router/reference/data-apis/use-submissions.mdx index c03ac618ca..2f4147b055 100644 --- a/src/routes/solid-router/reference/data-apis/use-submissions.mdx +++ b/src/routes/solid-router/reference/data-apis/use-submissions.mdx @@ -13,32 +13,28 @@ It's important to note that it requires the form method to be **post** otherwise In the example below, the `useSubmissions` helper is used to retain a list of all submission results to that action while also giving feedback on the pending state of the current in-flight submission. -```tsx title="component.tsx" {4,9-20, 23} +```tsx title="component.tsx" {5,10-16, 19} +import { For, Show } from "solid-js"; import { useSubmissions } from "@solidjs/router"; function Component() { const submissions = useSubmissions(postNameAction); - return ( - - - - {([attemptIndex, data]) => ( - - { result => ( - - Backend {attemptIndex}: {result.name} - - )} - - > - )} - - - - {submissions.pending ? "sending" : "send"} - - ) + return ( + + + + {([attemptIndex, data]) => ( + + {(result) => Backend {attemptIndex}: {result.name}} + + )} + + + + {submissions.pending ? "sending" : "send"} + + ); } ``` @@ -49,39 +45,34 @@ To trigger a submission, [actions](https://docs.solidjs.com/) can be used. ## Filtering Submissions As an optional second parameter, the `useSubmissions` helper can receive a filter function to only return the submission that matches the condition. -The filter receives the submitted dated as a parameter and should return a boolean value. -E.g.: action below will only submit if the name is "solid". +The filter receives the submitted data as a parameter and should return a boolean value. +The action below will only submit if the name is "solid". -```tsx title="component.tsx" {4-8} +```tsx title="component.tsx" {5-8} +import { For, Show } from "solid-js"; import { useSubmissions } from "@solidjs/router"; function Component() { - const submissions = useSubmissions(postNameAction, ([formData]) => { - const name = formData.get("name") ?? ""; - - return name === "solid"; - }); + const submissions = useSubmissions( + postNameAction, + ([formData]) => formData.get("name") === "solid" + ); return ( - - - {([attemptIndex, data]) => ( - - { result => ( - - Backend {attemptIndex}: {result.name} - - )} - - > - )} - - - - {submissions.pending ? "sending" : "send"} - - ) + + + {([attemptIndex, data]) => ( + + {(result) => Backend {attemptIndex}: {result.name}} + + )} + + + + {submissions.pending ? "sending" : "send"} + + ); } ``` @@ -91,65 +82,59 @@ When the form is submitted, the `submission` object will be updated with the new This allows you to provide feedback to the user that the action is in progress. Once the action is complete, the `pending` property will be set to `false` and the `result` property will be updated with final value. -```tsx tab title="TypeScript" {6,13-20} -// component.tsx -import { Show } from "solid-js"; +```tsx tab title="TypeScript" {5,12-17} +import { For, Show } from "solid-js"; import { useSubmissions } from "@solidjs/router"; function Component() { const submissions = useSubmissions(postNameAction); - return ( - - - - {([attemptIndex, data]) => ( - - {(input) => { - const name = (input().value as [string, string])[1] - - return ( - Optimistic: {name} - )}} - - )} - - - - {submissions.pending ? "sending" : "send"} - - ) + return ( + + + + {([, data]) => ( + + {(input) => { + const name = (input().value as [string, string])[1]; + return Optimistic: {name}; + }} + + )} + + + + {submissions.pending ? "sending" : "send"} + + ); } ``` -```tsx tab title="JavaScript" {6,13-20} -// component.jsx -import { Show } from "solid-js"; +```tsx tab title="JavaScript" {5,12-17} +import { For, Show } from "solid-js"; import { useSubmissions } from "@solidjs/router"; function Component() { const submissions = useSubmissions(postNameAction); - return ( - - - - {([attemptIndex, data]) => ( - - {(input) => { - const name = input().value[1] - - return ( - Optimistic: {name} - )}} - - )} - - - - {submissions.pending ? "sending" : "send"} - - ) + return ( + + + + {([, data]) => ( + + {(input) => { + const name = input().value[1]; + return Optimistic: {name}; + }} + + )} + + + + {submissions.pending ? "sending" : "send"} + + ); } ``` @@ -161,30 +146,30 @@ This allows you to provide feedback to the user that the action has failed. Addi At this stage, you can also use the `retry()` method to attempt the action again or the `clear()` to wipe the filled data in the platform. ```tsx title="component.tsx" {12-18} -import { Show } from "solid-js"; +import { For, Show } from "solid-js"; import { useSubmissions } from "@solidjs/router"; function Component() { const submissions = useSubmissions(postNameAction); - return ( - - - - {([attempt, data]) => ( - - - Backend {attempt}: {data.error.message} - data.retry()}>retry - data.clear()}>clear - - - )} - - - - {submissions.pending ? "sending" : "send"} - - ) + return ( + + + + {([attempt, data]) => ( + + + Backend {attempt}: {data.error.message} + data.retry()}>retry + data.clear()}>clear + + + )} + + + + {submissions.pending ? "sending" : "send"} + + ); } ``` diff --git a/src/routes/solid-router/reference/primitives/use-before-leave.mdx b/src/routes/solid-router/reference/primitives/use-before-leave.mdx index 784ea506d5..5b861231b3 100644 --- a/src/routes/solid-router/reference/primitives/use-before-leave.mdx +++ b/src/routes/solid-router/reference/primitives/use-before-leave.mdx @@ -5,27 +5,27 @@ title: useBeforeLeave `useBeforeLeave` takes a function that will be called prior to leaving a route. The function will be called with: -- from (_Location_): current location (before change). -- to (_string | number_}: path passed to `navigate.` -- options (_NavigateOptions_}: options passed to `navigate.` -- preventDefault (_void function_): call to block the route change. -- defaultPrevented (_readonly boolean_): `true` if any previously called leave handlers called `preventDefault()`. -- retry (_void function_, _force?: boolean_ ): call to retry the same navigation. - Pass `true` to skip running the leave handlers again (ie. force navigate without confirming). +- from (_Location_): current location (before change) +- to (_string | number_): path passed to `navigate` +- options (_NavigateOptions_): options passed to `navigate` +- preventDefault (_void function_): call to block the route change +- defaultPrevented (_readonly boolean_): `true` if any previously called leave handlers called `preventDefault()` +- retry (_void function_, _force?: boolean_ ): call to retry the same navigation + Pass `true` to skip running the leave handlers again (ie. force navigate without confirming) -Example usage: +Example usage ```js useBeforeLeave((e: BeforeLeaveEventArgs) => { - if (form.isDirty && !e.defaultPrevented) { - // preventDefault to block immediately and prompt user async - e.preventDefault(); - setTimeout(() => { - if (window.confirm("Discard unsaved changes - are you sure?")) { - // user wants to proceed anyway so retry with force=true - e.retry(true); - } - }, 100); - } + if (form.isDirty && !e.defaultPrevented) { + // preventDefault to block immediately and prompt user async + e.preventDefault(); + setTimeout(() => { + if (window.confirm("Discard unsaved changes - are you sure?")) { + // user wants to proceed anyway so retry with force=true + e.retry(true); + } + }, 100); + } }); ``` diff --git a/src/routes/solid-router/reference/primitives/use-match.mdx b/src/routes/solid-router/reference/primitives/use-match.mdx index c0391d9067..3637ae3c9b 100644 --- a/src/routes/solid-router/reference/primitives/use-match.mdx +++ b/src/routes/solid-router/reference/primitives/use-match.mdx @@ -12,9 +12,9 @@ return ; ``` As a second parameter, `useMatch` also accepts a group of `MatchFilters`. -These filteres allow for a more granular check. +These filters allow for a more granular check. -The filters are the same used by the `` itself and they accept either a an array of strings, or a regular expression. Additionally, there's a `boolean` option to match a route only if it has, or doesn't have, the HTML extension. +The filters are the same used by the `` itself and they accept either an array of strings, or a regular expression. Additionally, there's a `boolean` option to match a route only if it has, or doesn't have, the HTML extension. ```js const filters: MatchFilters = { @@ -44,4 +44,4 @@ The check above will match: /solid-router/reference/... /solid-meta/reference/... /solid-start/reference/... -``` \ No newline at end of file +``` diff --git a/src/routes/solid-router/reference/primitives/use-navigate.mdx b/src/routes/solid-router/reference/primitives/use-navigate.mdx index 82988990a3..71fe2a4aa7 100644 --- a/src/routes/solid-router/reference/primitives/use-navigate.mdx +++ b/src/routes/solid-router/reference/primitives/use-navigate.mdx @@ -13,11 +13,11 @@ Retrieves the method which accepts a path to navigate to and an optional object const navigate = useNavigate(); if (unauthorized) { - navigate("/login", { replace: true }); + navigate("/login", { replace: true }); } ``` -If you are inside of a query, action or cache (deprecated) function you will instead want to use [redirect](/solid-router/reference/response-helpers/redirect) or [reload](/solid-router/reference/response-helpers/reload). +If you are inside a query or action function you will instead want to use [redirect](/solid-router/reference/response-helpers/redirect) or [reload](/solid-router/reference/response-helpers/reload). :::note The state is serialized using the [structured clone diff --git a/src/routes/solid-router/rendering-modes/spa.mdx b/src/routes/solid-router/rendering-modes/spa.mdx index 6bdcc8263a..ce919c7e9c 100644 --- a/src/routes/solid-router/rendering-modes/spa.mdx +++ b/src/routes/solid-router/rendering-modes/spa.mdx @@ -16,11 +16,11 @@ Vercel, on the other hand, requires a rewrites section in your `vercel.json`: ```json { - "rewrites": [ - { - "source": "/(.*)", - "destination": "/index.html" - } - ] + "rewrites": [ + { + "source": "/(.*)", + "destination": "/index.html" + } + ] } ```
Error: {error.message}
Backend {attempt}: {data.error.message}