W↓
All docs
🔑
Sign Up/Sign In
docs.solidjs.com/solid-router/reference/
Public Link
Apr 8, 2025, 10:14:07 AM - complete - 46.7 kB
Starting URLs:
https://docs.solidjs.com/solid-router/reference/components/a
Crawl Prefixes:
https://docs.solidjs.com/solid-router/reference/
## Page: https://docs.solidjs.com/solid-router/reference/components/a Solid Router exposes the `<A />` component as a wrapper around the native anchor tag . It relies on the routing context provided by the `<Router>` component and if used outside, will triggers a runtime error.. `<A />` supports relative and base paths. `<a />` doesn't. But `<a />` gets augmented when JS is present via a top-level listener to the DOM, so you get the soft-navigation experience nonetheless. The `<A />` supports the `<Router />` base property (`<Router base="/subpath">`) and prepend it to the received `href` automatically and the `<a />`does not. The same happens with relative paths passed to `<A />`. The `<A>` tag has an `active` class if its href matches the current location, and `inactive` otherwise. By default matching includes locations that are descendants (e.g.: href `/users` matches locations `/users` and `/users/123`). * * * When JavaScript is present at the runtime, both components behave in a very similar fashion. This is because Solid Router adds a listener at the top level of the DOM and will augment the native `<a />` tag to a more performant experience (with soft navigation). * * * | prop | type | description | | --- | --- | --- | | href | string | The path of the route to navigate to. This will be resolved relative to the route that the link is in, but you can preface it with `/` to refer back to the root. | | noScroll | boolean | If true, turn off the default behavior of scrolling to the top of the new page | | replace | boolean | If true, don't add a new entry to the browser history. (By default, the new page will be added to the browser history, so pressing the back button will take you to the previous route.) | | state | unknown | Push this value to the history stack when navigating | | inactiveClass | string | The class to show when the link is inactive (when the current location doesn't match the link) | | activeClass | string | The class to show when the link is active | | end | boolean | If `true`, only considers the link to be active when the current location matches the `href` exactly; if `false`, check if the current location _starts with_ `href` | --- ## Page: https://docs.solidjs.com/solid-router/reference/components/hash-router 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. 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. Compared to a browser-router, such as `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. 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 `<A>` links. import { render } from "solid-js/web";import { HashRouter, Route } from "@solidjs/router";const App = (props) => ( <> <h1>Root header</h1> {props.children} </>);render( () => <HashRouter root={App}>{/*... routes */}</HashRouter>, document.getElementById("app")); --- ## Page: https://docs.solidjs.com/solid-router/reference/components/memory-router The `MemoryRouter` can be used to route while keeping the entire routing history within internal memory. Other routers keep history externally such as in the url like the `<HashRouter>` or in the browser history like `<Router>`. Keeping the history in memory is useful when you want full control over the routing history. Since `MemoryRouter` can manipulate `MemoryHistory`, it is often used for testing purposes. import { MemoryRouter, createMemoryHistory, A } from "@solidjs/router";import { Suspense } from "solid-js";export default function App() { const history = createMemoryHistory(); const toHome = () => { history.set({ value: "/" }); }; const toAbout = () => { history.set({ value: "/about" }); }; return ( <> <button onClick={toHome}>{'"/"'}</button> <button onClick={toAbout}>{'"/about"'}</button> <MemoryRouter history={history} root={(props) => <Suspense>{props.children}</Suspense>} > {/*... routes */} </MemoryRouter> </> );} In this example, a history object is pre-filled to navigate to the `/about` route, which is then passed to the `MemoryRouter`. The `MemoryHistory` object contains the following methods, which you can use to control the navigation of your app. --- ## Page: https://docs.solidjs.com/solid-router/reference/components/navigate Solid Router provides a `Navigate` component that works similarly to `<A>`, but it will _immediately_ navigate to the provided path as soon as the component is rendered. It also uses the `href` prop, but with the additional option of passing a function to `href` that returns a path to navigate to: function getPath({ navigate, location }) { // navigate is the result of calling useNavigate(); location is the result of calling useLocation(). // You can use those to dynamically determine a path to navigate to return "/some-path";}// Navigating to /redirect will redirect you to the result of getPath<Route path="/redirect" component={() => <Navigate href={getPath} />} />; --- ## Page: https://docs.solidjs.com/solid-router/reference/components/route ComponentsEdit this page `Route` is the component used when defining the routes of an application. This component is used to define the structure of the application and the components that will be rendered for each route. | prop | type | description | | --- | --- | --- | | path | `string | string[]` | Path partial for defining the route segment | | component | `Component` | Component that will be rendered for the matched segment | | matchFilters | `MatchFilters` | Additional constraints for matching against the route | | children | `JSX.Element` | Nested `<Route>` definitions | | preload | `RoutePreloadFunc` | Function called during preload or when the route is navigated to. | Report an issue with this page --- ## Page: https://docs.solidjs.com/solid-router/reference/components/router The `Router` component is a top level component that manages the routing of your application. There is an optional `root` prop that can be used to wrap the entire application in a layout component, which will not be updated when the page changes. import { render } from "solid-js/web";import { Router, Route } from "@solidjs/router";const App = (props) => ( <> <h1>Root header</h1> {props.children} </>);render( () => <Router root={App}>{/*... routes */}</Router>, document.getElementById("app")); | prop | type | description | | --- | --- | --- | | children | `JSX.Element`, `RouteDefinition`, or `RouteDefinition[]` | The route definitions | | root | Component | Top level layout component | | base | string | Base url to use for matching routes | | actionBase | string | Root url for server actions, default: `/_server` | | preload | boolean | Enables/disables preloads globally, default: `true` | | explicitLinks | boolean | Disables all anchors being intercepted and instead requires `<A>`. default: `false`. (To disable interception for a specific link, set `target` to any value, e.g. `<a target="_self">`.) | | url | string | The initial route to render | --- ## Page: https://docs.solidjs.com/solid-router/reference/data-apis/action Actions are data mutations that can trigger invalidations and further routing. A list of prebuilt response helpers can be found below. import { action, revalidate, redirect } from "@solidjs/router"// anywhereconst myAction = action(async (data) => { await doMutation(data); throw redirect("/", { revalidate: getUser.keyFor(data.id) }); // throw a response to do a redirect});// in component<form action={myAction} method="post" />//or<button type="submit" formaction={myAction}></button> Actions only work with **post** requests. This means forms require `method="post"`. A `with` method can be used when typed data is required. This removes the need to use `FormData` or other additional hidden fields. The `with` method works similar to `bind`, which applies the arguments in order. Without `with`: const deleteTodo = action(async (formData: FormData) => { const id = Number(formData.get("id")) await api.deleteTodo(id)})<form action={deleteTodo} method="post"> <input type="hidden" name="id" value={todo.id} /> <button type="submit">Delete</button></form> Using `with`: const deleteTodo = action(async (id: number) => { await api.deleteTodo(id)})<form action={deleteTodo} method="post"> <input type="hidden" name="id" value={todo.id} /><form action={deleteTodo.with(todo.id)} method="post"> <button type="submit">Delete</button></form> * * * This requires stable references because a string can only be serialized as an attribute, and it is crucial for consistency across SSR. where these references must align. The solution is to provide a unique name. const myAction = action(async (args) => {}, "my-action"); * * * Instead of forms, actions can directly be wrapped in a `useAction` primitive. This is how router context is created. // in componentconst submit = useAction(myAction);submit(...args); The outside of a form context can use custom data instead of `formData`. These helpers preserve types. However, even when used with server functions, such as with SolidStart, this requires client-side JavaScript and is not progressively enhanceable like forms are. * * * These functions are used when incorporating optimistic updates during ongoing actions. They provide either a singular Submission (the latest one), or a collection of Submissions that match, with an optional filtering function. type Submission<T, U> = { input: T; result: U; error: any; pending: boolean clear: () => {} retry: () => {}}const submissions = useSubmissions(action, (input) => filter(input));const submission = useSubmission(action, (input) => filter(input)); * * * ### Revalidate all (default) By default all cached functions will be revalidated wether the action does not return or return a "normal" response. const deleteTodo = action(async (formData: FormData) => { const id = Number(formData.get("id")) await api.deleteTodo(id) // ... return new Response("success", { status: 200 });}) ### Revalidate specific cached keys By returning a response with solid-router's `json`, `reload` or `redirect` helpers you can pass a key / keys to the revalidate prop as the second argument of the json response helper. You can either pass as `string` directly or use the cached functions `key` or `keyFor` props. import { action, json, reload, redirect } from "@solidjs/router"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)]} ) //or return reload({ revalidate: ["getAllTodos", getTodos.key, getTodoByID.keyFor(id)]}) //or return redirect("/", { revalidate: ["getAllTodos", getTodos.key, getTodoByID.keyFor(id)]})}) * * * To opt out of any revalidation you can pass any `string` to revalidate which is not a key of any cached function. 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" }) // or reload the route without revalidating the request. return reload({ revalidate: "nothing" }) // or redirect without revalidating return redirect("/", { revalidate: "nothing" })}) ### Revalidate without action Cached functions can also be revalidated by the `revalidate` helper. 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. export default function TodoLayout(){ const todos = createAsync(() => getTodos()) onMount(() => { //30 second polling const interval = setInterval(() => revalidate(getTodos.key),1000 * 30) onCleanup(() => clearInterval(interval)) }) // ...} --- ## Page: https://docs.solidjs.com/solid-router/reference/data-apis/cache `cache` is a higher-order function designed to create a new function with the same signature as the function passed to it. When this newly created function is called for the first time with a specific set of arguments, the original function is run, and its return value is stored in a cache and returned to the caller of the created function. The next time the created function is called with the same arguments (as long as the cache is still valid), it will return the cached value instead of re-executing the original function. * * * const getUser = query( (id, options = {}) => fetch(`/api/users/${id}?summary=${options.summary || false}`).then((r) => r.json() ), "usersById");getUser(123); // Causes a GET request to /api/users/123?summary=falsegetUser(123); // Does not cause a GET requestgetUser(123, { summary: true }); // Causes a GET request to /api/users/123?summary=truesetTimeout(() => getUser(123, { summary: true }), 999000); // Eventually causes another GET request to /api/users/123?summary=true ### With preload functions Using it with a preload function: import { lazy } from "solid-js";import { Route } from "@solidjs/router";import { getUser } from ... // the cache functionconst User = lazy(() => import("./pages/users/[id].js"));// preload functionfunction preloadUser({params, location}) { void getUser(params.id)}// Pass it in the route definition<Route path="/users/:id" component={User} preload={preloadUser} />; ### Inside a route's component Using it inside a route's component: // pages/users/[id].jsimport { getUser } from ... // the cache functionexport default function User(props) { const user = createAsync(() => getUser(props.params.id)); return <h1>{user().name}</h1>;} * * * `cache` accomplishes the following: 1. Deduping on the server for the lifetime of the request. 2. Preloading the cache in the browser - this lasts 5 seconds. When a route is preloaded on hover or when preload is called when entering a route it will make sure to dedupe calls. 3. A reactive refetch mechanism based on key. This prevents routes that are not new from retriggering on action revalidation. 4. Serve as a back/forward cache for browser navigation for up to 5 minutes. Any user based navigation or link click bypasses it. Upon revalidation or new fetch the cache is updated. * * * To ensure that the cache keys are consistent and unique, arguments are deterministically serialized using JSON.stringify. Before serialization, key/value pairs in objects are sorted so that the order of properties does not affect the serialization. For instance, both `{ name: 'Ryan', awesome: true }` and `{ awesome: true, name: 'Ryan' }` will serialize to the same string so that they produce the same cache key. * * * The return value is a `CachedFunction`, a function that has the same signature as the function you passed to `cache`. This cached function stores the return value using the cache key. Under most circumstances, this temporarily prevents the passed function from running with the same arguments, even if the created function is called repeatedly. * * * | argument | type | description | | --- | --- | --- | | `fn` | `(...args: any) => any` | A function whose return value you'd like to be cached. | | `name`\* | string | Any arbitrary string that you'd like to use as the rest of the cache key. | \*Since the internal cache is shared by all the functions using `cache`, the string should be unique for each function passed to `cache`. If the same key is used with multiple functions, one function might return the cached result of the other. * * * ### `.key` and `.keyFor` Cached functions provide `.key` and `.keyFor`, are useful when retrieving the keys used in cases involving invalidation: let id = 5;getUser.key; // returns "users"getUser.keyFor(id); // returns "users[5]" ### `revalidate` The cache can be revalidated using the `revalidate` method or the `revalidate` keys that are set on the response from the actions. If the entire key is passed, it will invalidate all entries for the cache (ie. `users` in the example above). If only a single entry needs to be invalidated, `keyFor` is provided. To revalidate everything in the cache, pass `undefined` as the key. --- ## Page: https://docs.solidjs.com/solid-router/reference/data-apis/create-async An asynchronous primitive with a function that tracks similar to `createMemo`. `createAsync` expects a promise back that is then turned into a Signal. Reading it before it is ready causes Suspense/Transitions to trigger. This is light wrapper over `createResource` 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 helper. import { createAsync } from "@solidjs/router";import { Suspense } from "solid-js";import { getUser } from "./api";export function Component () => { const user = createAsync(() => getUser(params.id)); return ( <Suspense fallback="loading user..."> <p>{user()}</p> </Suspense> ); --- ## Page: https://docs.solidjs.com/solid-router/reference/data-apis/create-async-store Similar to createAsync except it uses a deeply reactive store. Perfect for applying fine-grained changes to large model data that updates. const todos = createAsyncStore(() => getTodos()); --- ## Page: https://docs.solidjs.com/solid-router/reference/data-apis/query `query` is a higher-order function designed to create a new function with the same signature as the function passed to it. When this newly created function is called for the first time with a specific set of arguments, the original function is run, and its return value is stored in a cache and returned to the caller of the created function. The next time the created function is called with the same arguments (as long as the cache is still valid), it will return the cached value instead of re-executing the original function. * * * const getUser = query( (id, options = {}) => fetch(`/api/users/${id}?summary=${options.summary || false}`).then((r) => r.json() ), "usersById");getUser(123); // Causes a GET request to /api/users/123?summary=falsegetUser(123); // Does not cause a GET requestgetUser(123, { summary: true }); // Causes a GET request to /api/users/123?summary=truesetTimeout(() => getUser(123, { summary: true }), 999000); // Eventually causes another GET request to /api/users/123?summary=true ### With preload functions Using it with a preload function: import { lazy } from "solid-js";import { Route } from "@solidjs/router";import { getUser } from ... // the cache functionconst User = lazy(() => import("./pages/users/[id].js"));// preload functionfunction preloadUser({params, location}) { void getUser(params.id)}// Pass it in the route definition<Route path="/users/:id" component={User} preload={preloadUser} />; ### Inside a route's component Using it inside a route's component: // pages/users/[id].jsimport { getUser } from ... // the cache functionexport default function User(props) { const user = createAsync(() => getUser(props.params.id)); return <h1>{user().name}</h1>;} * * * `query` accomplishes the following: 1. Deduping on the server for the lifetime of the request. 2. It fills a preload cache in the browser - this lasts 5 seconds. When a route is preloaded on hover or when preload is called when entering a route it will make sure to dedupe calls. 3. A reactive refetch mechanism based on key. This prevents routes that are not new from retriggering on action revalidation. 4. Serve as a back/forward cache for browser navigation for up to 5 minutes. Any user based navigation or link click bypasses this cache. Revalidation or new fetch updates the cache. * * * To ensure that the cache keys are consistent and unique, arguments are deterministically serialized using `JSON.stringify`. Before serialization, key/value pairs in objects are sorted so that the order of properties does not affect the serialization. For instance, both `{ name: 'Ryan', awesome: true }` and `{ awesome: true, name: 'Ryan' }` will serialize to the same string so that they produce the same cache key. * * * The return value is a `CachedFunction`, a function that has the same signature as the function you passed to `query`. This cached function stores the return value using the cache key. Under most circumstances, this temporarily prevents the passed function from running with the same arguments, even if the created function is called repeatedly. * * * | argument | type | description | | --- | --- | --- | | `fn` | `(...args: any) => any` | A function whose return value you'd like to be cached. | | `name`\* | string | Any arbitrary string that you'd like to use as the rest of the cache key. | \*Since the internal cache is shared by all the functions using `query`, the string should be unique for each function passed to `query`. If the same key is used with multiple functions, one function might return the cached result of the other. * * * ### `.key` and `.keyFor` Query functions provide `.key` and `.keyFor`, are useful when retrieving the keys used in cases involving invalidation: let id = 5;getUser.key; // returns "users"getUser.keyFor(id); // returns "users[5]" ### `revalidate` The `query` can be revalidated using the `revalidate` method or the `revalidate` keys that are set on the response from the actions. If the entire key is passed, it will invalidate all entries for the cache (ie. `users` in the example above). If only a single entry needs to be invalidated, `keyFor` is provided. To revalidate everything in the cache, pass `undefined` as the key. --- ## Page: https://docs.solidjs.com/solid-router/reference/data-apis/use-action `useAction` allows an `action` to be invoked programmatically. import { useAction } from "@solidjs/router";import { updateNameAction } from "./actions";const updateName = useAction(updateNameAction);const result = updateName("John Wick"); info `useAction` requires client-side JavaScript and is not progressively enhanceable. * * * ## Parameters * `action`: The action to be invoked. * * * ## Returns `useAction` returns a function that invokes the action. It shares the same signature as the action itself. --- ## Page: https://docs.solidjs.com/solid-router/reference/data-apis/use-submission This helper is used to handle form submissions and can provide optimistic updates while actions are in flight as well as pending state feedback. This method will return a single (latest) value while its sibling, `useSubmissions`, will return all values submitted while the component is active. With an optional second parameter for a filter function. It's important to note that `useSubmission` requires the form method to be **post** otherwise it will trigger a browser navigation and will not work. import { useSubmission } from "@solidjs/router";function Component() { const submission = useSubmission(postNameAction); return ( <form action={postNameAction} method="post"> <input type="text" name="name" /> <button type="submit"> {submission.pending ? "Adding..." : "Add"} </button> </form> )} * * * 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". import { useSubmission } from "@solidjs/router";function Component() { const submission = useSubmission(postNameAction, ([formData]) => { const name = formData.get("name") ?? ""; return name === "solid"; }); return ( <form action={postNameAction} method="post"> <input type="text" name="name" /> <button type="submit"> {submission.pending ? "Adding..." : "Add"} </button> </form> )} * * * When the form is submitted, the `submission` object will be updated with the new value and the `pending` property will be set to `true`. 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. // component.tsximport { Show } from "solid-js";import { useSubmission } from "@solidjs/router";function Component() { const submission = useSubmission(postNameAction); return ( <> <Show when={submission.input?.[0].get("name")}> {(name) => <div>Optimistic: {name() as string}</div>} </Show> <Show when={submission.result?.name}> {(name) => <div>Result: {name()}</div>} </Show> <form method="post" action={sendData}> <input type="text" name="name" required /> <button type="submit" disabled={submission.pending}> {submission.pending ? "Submitting" : "Submit"} </button> </form> </> )} // component.jsximport { Show } from "solid-js";import { useSubmission } from "@solidjs/router";function Component() { const submission = useSubmission(postNameAction); return ( <> <Show when={submission.input?.[0].get("name")}> {(name) => <div>Optimistic: {name()}</div>} </Show> <Show when={submission.result?.name}> {(name) => <div>Result: {name()}</div>} </Show> <form method="post" action={sendData}> <input type="text" name="name" required /> <button type="submit" disabled={submission.pending}> {submission.pending ? "Submitting" : "Submit"} </button> </form> </> )} * * * If the action fails, the `submission` object will be updated with the error and the `pending` property will be set to `false`. This allows you to provide feedback to the user that the action has failed. Additionally, the return type of `useSubmission` will have a new key `error` that will contain the error object thrown by the submission handler. 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. import { Show } from "solid-js";import { useSubmission } from "@solidjs/router";function Component() { const submission = useSubmission(postNameAction); return ( <> <Show when={submission.error}> {(error) => ( <div> <p>Error: {error.message}</p> <button onClick={() => submission.clear()}> Clear </button> <button onClick={async () => submission.retry()}> Retry </button> </div> )} </Show> <form method="post" action={sendData}> <input type="text" name="name" required /> <button type="submit" disabled={submission.pending}> {submission.pending ? "Submitting" : "Submit"} </button> </form> </> )} --- ## Page: https://docs.solidjs.com/solid-router/reference/data-apis/use-submissions This helper is used to handle form submissions and can provide optimistic updates while actions are in flight as well as pending state feedback. This method will return an iterable of all submitted actions while its component is mounted. With an optional second parameter for a filter function. It's important to note that it requires the form method to be **post** otherwise it will trigger a browser navigation and will not work. 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. import { useSubmissions } from "@solidjs/router";function Component() { const submissions = useSubmissions(postNameAction); return ( <form method="post" action={postNameAction}> <ul> <For each={Array.from(submissions.entries())}> {([attemptIndex, data]) => ( <Show when={data.result}> { result => ( <li> Backend {attemptIndex}: {result.name} </li> )} </Show> </> )} </For> </ul> <input name="name" type="text" /> <button type="submit">{submissions.pending ? "sending" : "send"}</button> </form> )} * * * 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". import { useSubmissions } from "@solidjs/router";function Component() { const submissions = useSubmissions(postNameAction, ([formData]) => { const name = formData.get("name") ?? ""; return name === "solid"; }); return ( <form method="post" action={postNameAction}> <ul> <For each={Array.from(submissions.entries())}> {([attemptIndex, data]) => ( <Show when={data.result}> { result => ( <li> Backend {attemptIndex}: {result.name} </li> )} </Show> </> )} </For> </ul> <input name="name" type="text" /> <button type="submit">{submissions.pending ? "sending" : "send"}</button> </form> )} * * * When the form is submitted, the `submission` object will be updated with the new value and the `pending` property will be set to `true`. 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. // component.tsximport { Show } from "solid-js";import { useSubmissions } from "@solidjs/router";function Component() { const submissions = useSubmissions(postNameAction); return ( <form method="post" action={postNameAction}> <ul> <For each={Array.from(submissions.entries())}> {([attemptIndex, data]) => ( <Show when={data.input[0].entries().next()}> {(input) => { const name = (input().value as [string, string])[1] return ( <li>Optimistic: {name}</li> )}} </Show> )} </For> </ul> <input name="name" type="text" /> <button type="submit">{submissions.pending ? "sending" : "send"}</button> </form> )} // component.jsximport { Show } from "solid-js";import { useSubmissions } from "@solidjs/router";function Component() { const submissions = useSubmissions(postNameAction); return ( <form method="post" action={postNameAction}> <ul> <For each={Array.from(submissions.entries())}> {([attemptIndex, data]) => ( <Show when={data.input[0].entries().next()}> {(input) => { const name = input().value[1] return ( <li>Optimistic: {name}</li> )}} </Show> )} </For> </ul> <input name="name" type="text" /> <button type="submit">{submissions.pending ? "sending" : "send"}</button> </form> )} * * * If the action fails, the `submission` object will be updated with the error and the `pending` property will be set to `false`. This allows you to provide feedback to the user that the action has failed. Additionally, the return type of `useSubmission` will have a new key `error` that will contain the error object thrown by the submission handler. 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. import { Show } from "solid-js";import { useSubmissions } from "@solidjs/router";function Component() { const submissions = useSubmissions(postNameAction); return ( <form method="post" action={postNameAction}> <ul> <For each={Array.from(submissions.entries())}> {([attempt, data]) => ( <Show when={data.error}> <li> <p>Backend {attempt}: {data.error.message}</p> <button onClick={() => data.retry()}>retry</button> <button onClick={() => data.clear()}>clear</button> </li> </Show> )} </For> </ul> <input name="name" type="text" required autocomplete="off" /> <button type="submit">{submissions.pending ? "sending" : "send"}</button> </form> )} --- ## Page: https://docs.solidjs.com/solid-router/reference/preload-functions/preload Preload functionsEdit this page With smart caches waterfalls are still possible with view logic and with lazy loaded code. With preload functions, fetching the data parallel to loading the route is possible to allow use of the data as soon as possible. The preload function can be called when the Route is loaded or eagerly when links are hovered. As its only argument, the preload function is passed an object that can be used to access route information: import { lazy } from "solid-js";import { Route } from "@solidjs/router";const User = lazy(() => import("./pages/users/[id].js"));// preload functionfunction preloadUser({ params, location }) { // do preloading}// Pass it in the route definition<Route path="/users/:id" component={User} preload={preloadUser} />; | key | type | description | | --- | --- | --- | | params | object | The route parameters (same value as calling `useParams()` inside the route component) | | location | `{ pathname, search, hash, query, state, key}` | An object that used to get more information about the path (corresponds to `useLocation()`) | | intent | `"initial", "navigate", "native", "preload"` | Indicates why this function is being called. * "initial" - the route is being initially shown (ie page load) * "native" - navigate originated from the browser (eg back/forward) * "navigate" - navigate originated from the router (eg call to navigate or anchor clicked) * "preload" - not navigating, just preloading (eg link hover) | A common pattern is to export the preload function and data wrappers that correspond to a route in a dedicated `route.data.js` file. This imports the data functions without loading anything else. import { lazy } from "solid-js";import { Route } from "@solidjs/router";import preloadUser from "./pages/users/[id].data.js";const User = lazy(() => import("/pages/users/[id].js"));// In the Route definition<Route path="/users/:id" component={User} preload={preloadUser} />; The return value of the `preload` function is passed to the page component when called at anytime other than `preload`. This initializes things in there, or alternatively the following new `Data APIs` can be used. Report an issue with this page --- ## Page: https://docs.solidjs.com/solid-router/reference/primitives/use-before-leave `useBeforeLeave` takes a function that will be called prior to leaving a route. The function will be called with: 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); }}); --- ## Page: https://docs.solidjs.com/solid-router/reference/primitives/use-current-matches `useCurrentMatches` returns all the matches for the current matched route. Useful for getting all the route information. For example if you stored breadcrumbs on your route definition you could retrieve them like so: const matches = useCurrentMatches();const breadcrumbs = createMemo(() => matches().map((m) => m.route.info.breadcrumb)); --- ## Page: https://docs.solidjs.com/solid-router/reference/primitives/use-is-routing Retrieves a signal that indicates whether the route is currently in a transition. This is useful for showing a stale or pending state when the route resolution is suspended state during concurrent rendering. const isRouting = useIsRouting();return ( <div classList={{ "grey-out": isRouting() }}> <MyAwesomeContent /> </div>); --- ## Page: https://docs.solidjs.com/solid-router/reference/primitives/use-location Retrieves reactive `location` object useful for getting things like `pathname` const location = useLocation();const pathname = createMemo(() => parsePath(location.pathname)); | attribute | type | description | | --- | --- | --- | | `pathname` | string | The pathname part of the URL, without the query string. | | `search` | string | The query string part of the URL. | | `hash` | string | The hash part of the URL, including the `#`. | | `state` | any | Custom state passed from `useNavigate` | | `query` | object | Returns a store-like object containing all the query parameters of the URL. | --- ## Page: https://docs.solidjs.com/solid-router/reference/primitives/use-match `useMatch` takes an accessor that returns the path and creates a Memo that returns match information if the current path matches the provided path. Useful for determining if a given path matches the current route. const match = useMatch(() => props.href);return <div classList={{ active: Boolean(match()) }} />; As a second parameter, `useMatch` also accepts a group of `MatchFilters`. These filteres allow for a more granular check. The filters are the same used by the `<Router>` 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. const filters: MatchFilters = { parent: ["mom", "dad"] id: /^\d+$/, withHtmlExtension: (v: string) => v.length > 5 && v.endsWith(".html")}; Finally, any parameter can be determined optional by adding a `?` at the end of the parameter name. const isReference = useMatch(() => "/:project?/reference/*?", { project: ["solid-router", "solid-meta", "solid-start"], }); The check above will match: /reference/solid-router/reference/solid-meta/reference/solid-start/reference/reference/.../solid-router/reference/.../solid-meta/reference/.../solid-start/reference/... --- ## Page: https://docs.solidjs.com/solid-router/reference/primitives/use-navigate Retrieves the method which accepts a path to navigate to and an optional object with the following options: * resolve (_boolean_, default `true`): resolve the path against the current route * replace (_boolean_, default `false`): replace the history entry * scroll (_boolean_, default `true`): scroll to top after navigation * state (_any_, default `undefined`): pass custom state to `location.state` const navigate = useNavigate();if (unauthorized) { navigate("/login", { replace: true });} If you are inside of a query, action or cache (deprecated) function you will instead want to use redirect or reload. info --- ## Page: https://docs.solidjs.com/solid-router/reference/primitives/use-params `useParams` retrieves a reactive object similar to a store. It contains the current route's path parameters as defined in the Route. const params = useParams();// Route path: /user/:id => /user/123console.log(params.id); // 123 --- ## Page: https://docs.solidjs.com/solid-router/reference/primitives/use-preload-route `usePreloadRoute` returns a function that can be used to preload a route manually. This is what happens automatically with link hovering and similar focus based behavior, but it is available here as an API. const preload = usePreloadRoute();preload(`/users/settings`, { preloadData: true }); --- ## Page: https://docs.solidjs.com/solid-router/reference/primitives/use-search-params Retrieves a tuple containing a reactive object to read the current location's query parameters and a method to update them. The object is a proxy so you must access properties to subscribe to reactive updates. Note values will be strings and property names will retain their casing. The setter method accepts an object as an input, and its key-value pairs will be merged into the existing query string. If a value is `''`, `undefined` or `null`, the corresponding key will be omitted from the resulting query string. The updates behave like navigation and will not scroll the page to the top. Additionally, the setter can take an optional second parameter, the same as `navigate`, to control the navigation behavior and auto-scrolling, which are disabled by default. const [searchParams, setSearchParams] = useSearchParams();return ( <div> <span>Page: {searchParams.page}</span> <button onClick={() => setSearchParams({ page: (parseInt(searchParams.page) || 0) + 1 }) } > Next Page </button> </div>); --- ## Page: https://docs.solidjs.com/solid-router/reference/response-helpers/json Returns JSON data from an action while also providing options for controlling revalidation of cache data on the route. import { action, json } from "@solidjs/router";import { fetchTodo } from "../fetchers";const getCompletedTodos = action(async () => { const completedTodos = await fetchTodo({ status: 'complete' }); return json(completedTodos, { revalidate: getTodo.keyFor(id) });}); interface ResponseOptions & Omit<ResponseInit, "body"> { revalidate?: string | string[];}json<T>(data: T, opt?: ResponseOptions): CustomResponse<T>; --- ## Page: https://docs.solidjs.com/solid-router/reference/response-helpers/redirect 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. Other useful redirect codes: | Code | Description | | --- | --- | | `301` | Moved Permanently | | `307` | Temporary Redirect | | `308` | Permanent redirect | 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. 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") * * * 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. This is useful when redirecting the user to a different route once a mutation is done. import { action, redirect } from "@solidjs/router";const addUser = action(async (user: User) => { await postUser(user); return redirect("/users");}); 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. * * * 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. When returning from a nested method, the parent method will continue to execute, which can lead to unexpected behavior. ### TypeScript Signature interface ResponseOptions & Omit<ResponseInit, "body"> { revalidate?: string | string[];} | numberfunction redirect(url: string, opts = 302): CustomResponse<never>; The `ResponseOptions` extens the types from the native `ResponseInit` interface. --- ## Page: https://docs.solidjs.com/solid-router/reference/response-helpers/reload Reload is a response helper built on top of revalidate. It will receive a cache key, or an array of cache keys, to invalidate those queries, and cause them to fire again. import { action, reload } from "@solidjs/router";import { putTodo, getTodo } from "../db";const updateTodo = action(async (todo: Todo) => { await putTodo(todo.id, todo); return reload({ revalidate: getTodo.keyFor(id) });}); The code snippet above uses the cache-key from a user-defined query (`getTodo`). To better understand how queries work, check the query documentation. interface ResponseOptions & Omit<ResponseInit, "body"> { revalidate?: string | string[];}reload(opt?: ResponseOptions): CustomResponse<never>; --- ## Page: https://docs.solidjs.com/solid-router/reference/response-helpers/revalidate Response helpersEdit this page Revalidate will receive the either a cache key or an array of cache keys and invalidate those queries. The code below will revalidate the `getTodo` query with the cache key. import { action, revalidate } from "@solidjs/router";const updateTodo = action(async (todo: Todo) => { await putTodo(todo.id, todo); return revalidate(getTodo.keyFor());}); To better understand how queries work, check the query documentation. * * * The `revalidate` function also accepts a second parameter to force the revalidation of the cache data. import { action, revalidate } from "@solidjs/router";const updateTodo = action(async (todo: Todo) => { await putTodo(todo.id, todo); return revalidate(getTodo.keyFor(), true);}); * * * function revalidate(key?: string | string[] | void, force?: boolean): Promise<void>; Report an issue with this page