From 34dc558e9817ac147ea6b64bd991ce63ade9a516 Mon Sep 17 00:00:00 2001 From: Claude Date: Wed, 4 Nov 2026 06:13:21 +0000 Subject: [PATCH 1/2] docs(router): a leading slash is a full path under a base Matches solid-router#718 (@solidjs/router 2.0.0-next.44): navigate, links, useLinkState, useResolvedPath and redirect never add the router base to a path that starts with "/"; paths nodes include it. Adds the Vite BASE_URL setup note and the 0.x migration note. Co-Authored-By: Claude Opus 5.5 Claude-Session: https://claude.ai/code/session_0117BoWNSSgtemsSYsaX2hXE --- src/routes/(4)routing/(1)solid-router/(1)setup.mdx | 12 +++++++++++- .../(4)routing/(1)solid-router/(4)navigation.mdx | 5 ++++- src/routes/(6)migration/(3)from-solid-router.mdx | 6 ++++++ .../reference/(3)solid-router/(1)router-factory.mdx | 2 +- .../reference/(3)solid-router/(3)navigation.mdx | 1 + 5 files changed, 23 insertions(+), 3 deletions(-) diff --git a/src/routes/(4)routing/(1)solid-router/(1)setup.mdx b/src/routes/(4)routing/(1)solid-router/(1)setup.mdx index c4d33bc5e..e39682660 100644 --- a/src/routes/(4)routing/(1)solid-router/(1)setup.mdx +++ b/src/routes/(4)routing/(1)solid-router/(1)setup.mdx @@ -120,7 +120,7 @@ The other options exist for a specific situation each: | Option | Reach for it when | | ------------------- | --------------------------------------------------------------------------------------------------------------------------------- | -| `base` | The app is served under a prefix such as `/app`; matching and `paths` both include it. | +| `base` | The app is served under a prefix such as `/app`; matching and `paths` include it, and a string starting with `/` is a full path. | | `history` | The app is not a normal page: an Electron shell or `file://` needs `hashHistory()`, tests need `memoryHistory()`. | | `preload` | The root layout needs data of its own; it runs once per mount or server request and reaches the function child as `props.data`. | | `preloadLinks` | Links should warm route code and data before the click; pass `intentPreload()` or another strategy (off by default). | @@ -131,6 +131,16 @@ The other options exist for a specific situation each: | `singleFlight` | The router's server-function data consumer should be off; it is `true` by default. | | `actionBase` | Server functions are served from a prefix other than the default `/_server`. | +When Vite serves the app under a `base`, pass `import.meta.env.BASE_URL` as the router `base` and link with `paths`. +A `paths` node includes the base, so links, `navigate`, and `redirect` stay under it: + +```tsx +export const Router = createRouter({ + routes, + base: import.meta.env.BASE_URL, +}); +``` + The router uses browser history by default on the client and the current request URL on the server, so `history` is rarely set in a web app: ```tsx diff --git a/src/routes/(4)routing/(1)solid-router/(4)navigation.mdx b/src/routes/(4)routing/(1)solid-router/(4)navigation.mdx index 5d792ec04..722d84860 100644 --- a/src/routes/(4)routing/(1)solid-router/(4)navigation.mdx +++ b/src/routes/(4)routing/(1)solid-router/(4)navigation.mdx @@ -95,7 +95,10 @@ function CheckoutButton() { Click the button and the URL becomes `/checkout` with the cart page's history entry replaced, so **Back** returns to the page before the cart rather than to the cart. The options are the same as the link attributes: `replace`, `scroll`, and `state`, plus `resolve` for how a relative string is interpreted. -A string starting with `/` resolves under the router's `base`; other strings resolve against the current location like a relative URL. +A string starting with `/` is a full path, and the router does not add its `base` to it: under `base: "/app"`, `navigate("/about")` goes to `/about`. +Pass a `paths` node, such as `paths.about`, for a path under the base; a node already includes the base. +A full path outside the base is another document, so `navigate` loads it, as a link or a redirect to it does. +Other strings resolve against the current location like a relative URL. A number moves through history: `navigate(-1)` is back. :::tip[Let the server decide where to go] diff --git a/src/routes/(6)migration/(3)from-solid-router.mdx b/src/routes/(6)migration/(3)from-solid-router.mdx index d9f5a26d8..90639fd8b 100644 --- a/src/routes/(6)migration/(3)from-solid-router.mdx +++ b/src/routes/(6)migration/(3)from-solid-router.mdx @@ -296,6 +296,12 @@ function LoginRedirect() { } ``` +Under a `base`, a string that starts with `/` is now a full path. +With `base: "/app"`, Solid Router 0.x sent `navigate("/login")` and `` to `/app/login`; Solid Router 2 sends them to `/login`. +The same applies to `useResolvedPath`, `useLinkState`, and `redirect`. +Use a `paths` node, such as `Router.paths.login`, which includes the base. +A full path outside the base loads the document. + Rename `useCurrentMatches` to `useRouteMatches`. Use `useLinkState` when a custom link component needs reactive `active`, `current`, or `pending` values. See [Navigation and typed paths](/routing/solid-router/navigation) for the remaining anchor and navigation options. diff --git a/src/routes/reference/(3)solid-router/(1)router-factory.mdx b/src/routes/reference/(3)solid-router/(1)router-factory.mdx index c738c38ea..53791edee 100644 --- a/src/routes/reference/(3)solid-router/(1)router-factory.mdx +++ b/src/routes/reference/(3)solid-router/(1)router-factory.mdx @@ -53,7 +53,7 @@ interface RouterConfig< ``` - `routes` is the route tree used for matching and path inference. -- `base` prefixes matched and generated paths. +- `base` prefixes route matching and `paths` nodes. A string that starts with `/` is a full path everywhere (`href`, `navigate`, `useLinkState`, `useResolvedPath`, and `redirect`), and the router does not add `base` to it. - `preload` returns data for the root render prop. - `history` defaults to browser history on the client. - `singleFlight` defaults to `true`. diff --git a/src/routes/reference/(3)solid-router/(3)navigation.mdx b/src/routes/reference/(3)solid-router/(3)navigation.mdx index 3e4016eaa..81fd321fb 100644 --- a/src/routes/reference/(3)solid-router/(3)navigation.mdx +++ b/src/routes/reference/(3)solid-router/(3)navigation.mdx @@ -196,6 +196,7 @@ function useResolvedPath(path: () => string): () => string | undefined; ``` Resolves a path against the current route context. +A path that starts with `/` is already a full path, so the router does not add its `base` to it. ## `useHref` From fa6ba2e06cb719b8806094ab4f5a78d2b3578329 Mon Sep 17 00:00:00 2001 From: Claude Date: Wed, 4 Nov 2026 06:14:26 +0000 Subject: [PATCH 2/2] docs(router): name 0.x/1.x in the base migration note Co-Authored-By: Claude Opus 5.5 Claude-Session: https://claude.ai/code/session_0117BoWNSSgtemsSYsaX2hXE --- src/routes/(6)migration/(3)from-solid-router.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/routes/(6)migration/(3)from-solid-router.mdx b/src/routes/(6)migration/(3)from-solid-router.mdx index 90639fd8b..2c85542dd 100644 --- a/src/routes/(6)migration/(3)from-solid-router.mdx +++ b/src/routes/(6)migration/(3)from-solid-router.mdx @@ -297,7 +297,7 @@ function LoginRedirect() { ``` Under a `base`, a string that starts with `/` is now a full path. -With `base: "/app"`, Solid Router 0.x sent `navigate("/login")` and `` to `/app/login`; Solid Router 2 sends them to `/login`. +With `base: "/app"`, Solid Router 0.x/1.x sent `navigate("/login")` and `` to `/app/login`; Solid Router 2 sends them to `/login`. The same applies to `useResolvedPath`, `useLinkState`, and `redirect`. Use a `paths` node, such as `Router.paths.login`, which includes the base. A full path outside the base loads the document.