Skip to content

Commit 8af53e7

Browse files
authored
Root router have a path different to '' or '/' (#10852)
1 parent ebe2491 commit 8af53e7

File tree

4 files changed

+91
-3
lines changed

4 files changed

+91
-3
lines changed

.changeset/404-root-with-path.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"@remix-run/router": patch
3+
---
4+
5+
Allow 404 detection to leverage root route error boundary if path contains a URL segment

contributors.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -237,5 +237,6 @@
237237
- xcsnowcity
238238
- yionr
239239
- yuleicul
240+
- yracnet
240241
- zheng-chuang
241242
- sgrishchenko

packages/router/__tests__/router-test.ts

Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4823,6 +4823,85 @@ describe("a router", () => {
48234823
});
48244824
});
48254825

4826+
it("handles 404 routes when the root route contains a path (initialization)", () => {
4827+
let t = setup({
4828+
routes: [
4829+
{
4830+
id: "root",
4831+
path: "/path",
4832+
children: [
4833+
{
4834+
index: true,
4835+
},
4836+
],
4837+
},
4838+
],
4839+
initialEntries: ["/junk"],
4840+
});
4841+
expect(t.router.state).toMatchObject({
4842+
errors: {
4843+
root: new ErrorResponseImpl(
4844+
404,
4845+
"Not Found",
4846+
new Error('No route matches URL "/junk"'),
4847+
true
4848+
),
4849+
},
4850+
initialized: true,
4851+
location: {
4852+
pathname: "/junk",
4853+
},
4854+
matches: [
4855+
{
4856+
route: {
4857+
id: "root",
4858+
},
4859+
},
4860+
],
4861+
});
4862+
});
4863+
4864+
it("handles 404 routes when the root route contains a path (navigation)", () => {
4865+
let t = setup({
4866+
routes: [
4867+
{
4868+
id: "root",
4869+
path: "/path",
4870+
children: [
4871+
{
4872+
index: true,
4873+
},
4874+
],
4875+
},
4876+
],
4877+
initialEntries: ["/path"],
4878+
});
4879+
expect(t.router.state).toMatchObject({
4880+
errors: null,
4881+
});
4882+
t.navigate("/junk");
4883+
expect(t.router.state).toMatchObject({
4884+
errors: {
4885+
root: new ErrorResponseImpl(
4886+
404,
4887+
"Not Found",
4888+
new Error('No route matches URL "/junk"'),
4889+
true
4890+
),
4891+
},
4892+
location: {
4893+
pathname: "/junk",
4894+
},
4895+
matches: [
4896+
{
4897+
route: {
4898+
id: "root",
4899+
},
4900+
},
4901+
],
4902+
});
4903+
});
4904+
48264905
it("converts formData to URLSearchParams for unspecified formMethod", async () => {
48274906
let t = setup({
48284907
routes: TASK_ROUTES,

packages/router/router.ts

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4074,9 +4074,12 @@ function getShortCircuitMatches(routes: AgnosticDataRouteObject[]): {
40744074
route: AgnosticDataRouteObject;
40754075
} {
40764076
// Prefer a root layout route if present, otherwise shim in a route object
4077-
let route = routes.find((r) => r.index || !r.path || r.path === "/") || {
4078-
id: `__shim-error-route__`,
4079-
};
4077+
let route =
4078+
routes.length === 1
4079+
? routes[0]
4080+
: routes.find((r) => r.index || !r.path || r.path === "/") || {
4081+
id: `__shim-error-route__`,
4082+
};
40804083

40814084
return {
40824085
matches: [

0 commit comments

Comments
 (0)