-
-
Notifications
You must be signed in to change notification settings - Fork 10.6k
[Bug]: RR7 - With basename
configured, .data
requests against root index not correctly routed
#12295
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
Here are the patches I issued to fix this in my Remix 2.14.0 project: diff --git a/node_modules/@remix-run/react/dist/esm/single-fetch.js b/node_modules/@remix-run/react/dist/esm/single-fetch.js
index 96f10cd..4126369 100644
--- a/node_modules/@remix-run/react/dist/esm/single-fetch.js
+++ b/node_modules/@remix-run/react/dist/esm/single-fetch.js
@@ -300,6 +300,8 @@ function singleFetchUrl(reqUrl) {
let url = typeof reqUrl === "string" ? new URL(reqUrl, window.location.origin) : reqUrl;
if (url.pathname === "/") {
url.pathname = "_root.data";
+ } else if (url.pathname === window.__remixContext.basename) {
+ url.pathname = window.__remixContext.basename.concat("_root.data");
} else {
url.pathname = `${url.pathname.replace(/\/$/, "")}.data`;
} diff --git a/node_modules/@remix-run/server-runtime/dist/server.js b/node_modules/@remix-run/server-runtime/dist/server.js
index 7e639d9..f2af2db 100644
--- a/node_modules/@remix-run/server-runtime/dist/server.js
+++ b/node_modules/@remix-run/server-runtime/dist/server.js
@@ -128,7 +128,12 @@ const createRequestHandler = (build, mode$1) => {
}
} else if (_build.future.v3_singleFetch && url.pathname.endsWith(".data")) {
let handlerUrl = new URL(request.url);
- handlerUrl.pathname = handlerUrl.pathname.replace(/\.data$/, "").replace(/^\/_root$/, "/");
+ handlerUrl.pathname = handlerUrl.pathname.replace(/\.data$/, "").replace(
+ _build.basename ?
+ /\/_root$/ :
+ /^\/_root$/,
+ "/"
+ );
let singleFetchMatches = routeMatching.matchServerRoutes(routes, handlerUrl.pathname, _build.basename);
response = await handleSingleFetchRequest(serverMode, _build, staticHandler, request, handlerUrl, loadContext, handleError);
if (_build.entry.module.handleDataRequest) { |
We ran into this issue when upgrading our Remix app (without single fetch) to RR7. It works locally with basename configured but failed in the production environment since our reverse proxy wouldn't route We ended up working around it by configuring our reverse proxy to route It works, but it would definitely be cleaner if the requests were |
Hello there! We encounter same issue after enable singleFetch future at our roadmap to react-router 7. We use cookie based Workaroung
function singleFetchUrl(reqUrl) {
let url = typeof reqUrl === "string" ? new URL(reqUrl, window.location.origin) : reqUrl;
const basename = window.__remixContext.basename;
if (url.pathname === "/") {
url.pathname = "_root.data";
} else if (basename && (url.pathname === basename || url.pathname === `${basename}/`)) {
url.pathname = basename.endsWith("/") ? basename.concat("_root.data") : basename.concat("/_root.data");
} else {
url.pathname = `${url.pathname.replace(/\/$/, "")}.data`;
}
return url;
}
|
could possibly be related to this? |
I'm also running into this issue after migrating a remix app into RR7. I noticed it when using the browser's back button to go back to the entry page, and getting a 404. Also does not happen in dev, but only in a production build. |
I'm also having this issue.
It happens in Remix v2 latest when the v3_singleFetch is enabled. We have a baseURL defined:
This is a blocker to upgrade from Remix to React Router 7. Is there any fix for this, other than a patch? |
@ryanflorence , is the team aware of this bug / is there any fix planned? I attempted to patch React Router, but this didn't solve the 404 issue with a basename: index 53d57562cbbe0a80bc80a88fc930b84679c805e2..73c737041b92b573ad9a77492412315ffdbc63d7 100644
--- a/dist/production/index.js
+++ b/dist/production/index.js
@@ -5952,8 +5952,11 @@ function singleFetchUrl(reqUrl) {
// don't assume window is available
typeof window === "undefined" ? "server://singlefetch/" : window.location.origin
) : reqUrl;
+ const basename = window.__reactRouterContext.basename;
if (url.pathname === "/") {
url.pathname = "_root.data";
+ } else if (basename && (url.pathname === basename || url.pathname === `${basename}/`)) {
+ url.pathname = basename.endsWith("/") ? basename.concat("_root.data") : basename.concat("/_root.data");
} else {
url.pathname = `${url.pathname.replace(/\/$/, "")}.data`;
}
@@ -9152,7 +9155,12 @@ var createRequestHandler = (build, mode) => {
let response;
if (url.pathname.endsWith(".data")) {
let handlerUrl = new URL(request.url);
- handlerUrl.pathname = handlerUrl.pathname.replace(/\.data$/, "").replace(/^\/_root$/, "/");
+ handlerUrl.pathname = handlerUrl.pathname.replace(/\.data$/, "").replace(
+ _build.basename ?
+ /\/_root$/ :
+ /^\/_root$/,
+ "/"
+ );
let singleFetchMatches = matchServerRoutes(
routes,
handlerUrl.pathname,
|
My thought here was that the For example, this structure:
would instead be:
|
I'm having the same issue with the additional issue that my form action that is set to /${basename} gets sent to /${basename}.data instead of /${basename}/_root.data |
For React Router v7, I had to create this patch (based on @mpqmpqm's) for it to work consistently in local and production environments. diff --git a/node_modules/react-router/dist/development/chunk-SYFQ2XB5.mjs b/node_modules/react-router/dist/development/chunk-SYFQ2XB5.mjs
index 25fce4e..85d529b 100644
--- a/node_modules/react-router/dist/development/chunk-SYFQ2XB5.mjs
+++ b/node_modules/react-router/dist/development/chunk-SYFQ2XB5.mjs
@@ -5811,6 +5811,8 @@ function singleFetchUrl(reqUrl) {
) : reqUrl;
if (url.pathname === "/") {
url.pathname = "_root.data";
+ } else if (url.pathname === window.__reactRouterContext.basename) {
+ url.pathname = window.__reactRouterContext.basename.concat("_root.data");
} else {
url.pathname = `${url.pathname.replace(/\/$/, "")}.data`;
}
@@ -9009,7 +9011,12 @@ var createRequestHandler = (build, mode) => {
let response;
if (url.pathname.endsWith(".data")) {
let handlerUrl = new URL(request.url);
- handlerUrl.pathname = handlerUrl.pathname.replace(/\.data$/, "").replace(/^\/_root$/, "/");
+ handlerUrl.pathname = handlerUrl.pathname.replace(/\.data$/, "").replace(
+ _build.basename ?
+ /\/_root$/ :
+ /^\/_root$/,
+ "/"
+ );
let singleFetchMatches = matchServerRoutes(
routes,
handlerUrl.pathname,
diff --git a/node_modules/react-router/dist/development/dom-export.js b/node_modules/react-router/dist/development/dom-export.js
index 59c9a78..af2dbfb 100644
--- a/node_modules/react-router/dist/development/dom-export.js
+++ b/node_modules/react-router/dist/development/dom-export.js
@@ -4471,6 +4471,8 @@ function singleFetchUrl(reqUrl) {
) : reqUrl;
if (url.pathname === "/") {
url.pathname = "_root.data";
+ } else if (url.pathname === window.__reactRouterContext.basename) {
+ url.pathname = window.__reactRouterContext.basename.concat("_root.data");
} else {
url.pathname = `${url.pathname.replace(/\/$/, "")}.data`;
}
diff --git a/node_modules/react-router/dist/development/index.js b/node_modules/react-router/dist/development/index.js
index 46834a0..42c686c 100644
--- a/node_modules/react-router/dist/development/index.js
+++ b/node_modules/react-router/dist/development/index.js
@@ -5956,6 +5956,8 @@ function singleFetchUrl(reqUrl) {
) : reqUrl;
if (url.pathname === "/") {
url.pathname = "_root.data";
+ } else if (url.pathname === window.__reactRouterContext.basename) {
+ url.pathname = window.__reactRouterContext.basename.concat("_root.data");
} else {
url.pathname = `${url.pathname.replace(/\/$/, "")}.data`;
}
@@ -9154,7 +9156,12 @@ var createRequestHandler = (build, mode) => {
let response;
if (url.pathname.endsWith(".data")) {
let handlerUrl = new URL(request.url);
- handlerUrl.pathname = handlerUrl.pathname.replace(/\.data$/, "").replace(/^\/_root$/, "/");
+ handlerUrl.pathname = handlerUrl.pathname.replace(/\.data$/, "").replace(
+ _build.basename ?
+ /\/_root$/ :
+ /^\/_root$/,
+ "/"
+ );
let singleFetchMatches = matchServerRoutes(
routes,
handlerUrl.pathname,
diff --git a/node_modules/react-router/dist/production/chunk-OKQ6KMOJ.mjs b/node_modules/react-router/dist/production/chunk-OKQ6KMOJ.mjs
index 3d1b632..535fe32 100644
--- a/node_modules/react-router/dist/production/chunk-OKQ6KMOJ.mjs
+++ b/node_modules/react-router/dist/production/chunk-OKQ6KMOJ.mjs
@@ -5811,6 +5811,8 @@ function singleFetchUrl(reqUrl) {
) : reqUrl;
if (url.pathname === "/") {
url.pathname = "_root.data";
+ } else if (url.pathname === window.__reactRouterContext.basename) {
+ url.pathname = window.__reactRouterContext.basename.concat("_root.data");
} else {
url.pathname = `${url.pathname.replace(/\/$/, "")}.data`;
}
@@ -9009,7 +9011,12 @@ var createRequestHandler = (build, mode) => {
let response;
if (url.pathname.endsWith(".data")) {
let handlerUrl = new URL(request.url);
- handlerUrl.pathname = handlerUrl.pathname.replace(/\.data$/, "").replace(/^\/_root$/, "/");
+ handlerUrl.pathname = handlerUrl.pathname.replace(/\.data$/, "").replace(
+ _build.basename ?
+ /\/_root$/ :
+ /^\/_root$/,
+ "/"
+ );
let singleFetchMatches = matchServerRoutes(
routes,
handlerUrl.pathname,
diff --git a/node_modules/react-router/dist/production/dom-export.js b/node_modules/react-router/dist/production/dom-export.js
index 8d83202..cac7673 100644
--- a/node_modules/react-router/dist/production/dom-export.js
+++ b/node_modules/react-router/dist/production/dom-export.js
@@ -4471,6 +4471,8 @@ function singleFetchUrl(reqUrl) {
) : reqUrl;
if (url.pathname === "/") {
url.pathname = "_root.data";
+ } else if (url.pathname === window.__reactRouterContext.basename) {
+ url.pathname = window.__reactRouterContext.basename.concat("_root.data");
} else {
url.pathname = `${url.pathname.replace(/\/$/, "")}.data`;
}
diff --git a/node_modules/react-router/dist/production/index.js b/node_modules/react-router/dist/production/index.js
index d5cace8..1f1138a 100644
--- a/node_modules/react-router/dist/production/index.js
+++ b/node_modules/react-router/dist/production/index.js
@@ -5956,6 +5956,8 @@ function singleFetchUrl(reqUrl) {
) : reqUrl;
if (url.pathname === "/") {
url.pathname = "_root.data";
+ } else if (url.pathname === window.__reactRouterContext.basename) {
+ url.pathname = window.__reactRouterContext.basename.concat("_root.data");
} else {
url.pathname = `${url.pathname.replace(/\/$/, "")}.data`;
}
@@ -9154,7 +9156,12 @@ var createRequestHandler = (build, mode) => {
let response;
if (url.pathname.endsWith(".data")) {
let handlerUrl = new URL(request.url);
- handlerUrl.pathname = handlerUrl.pathname.replace(/\.data$/, "").replace(/^\/_root$/, "/");
+ handlerUrl.pathname = handlerUrl.pathname.replace(/\.data$/, "").replace(
+ _build.basename ?
+ /\/_root$/ :
+ /^\/_root$/,
+ "/"
+ );
let singleFetchMatches = matchServerRoutes(
routes,
handlerUrl.pathname,
|
I am still experiencing this issue, any updates on a patch for this? |
Can verify this works, used patch-package https://www.npmjs.com/package/patch-package. Thank You!!! @Aleuck |
This should be resolved by #12898 and will be included in the next release |
@brophdawg11 , thanks for the update. On 7.2.0 I'm still getting the 404 error when following a link to the root route. I have a basename configured in the |
@manzaloros, from what I can tell this didn't make the 7.2 cut. This was merged into dev right after 7.2 was cut for a release. I have my eye on this one as well, but I think we'll be waiting for 7.3. |
🤖 Hello there, We just published version Thanks! |
@s-cochrane , thanks! After upgrading to 7.3.0 it looks like the issue is fixed! Just curious: I made a quick RR7 app from scratch before 7.3.0 and didn't notice this issue occurring. Why did it occur only on my app that I upgraded from Remix? |
@manzaloros - I'm not sure about the specifics of your setup, but we observed the issues when we put RR behind a reverse-proxy. In our case we're replacing a legacy application with a new RR app, and we can't move the legacy app off of the base URL. Because the RR app was being routed to via the reverse proxy it made the break very obvious for us. The app would work if we opened the app directly, but as soon as we put it behind the reverse proxy the issues would surface. Instead of routing static assets and data requests on top of the |
What version of React Router are you using?
7
Steps to Reproduce
Minimal repro
vite.config.base
andvite.config.reactRouter.basename
.Link
componentto
the root index, or an action against the root index..data
requests against root index are routed tolocalhost:5173/${basename}.data
, rather than e.g.localhost:5173/${basename}/_root.data
..data
requests against root index 404.Expected Behavior
.data
requests against root index should resolve accounting for configuredbasename
.Actual Behavior
.data
requests against root index 404..data
requests against nested routes resolve as expected.In minimal repro above, try clicking links to
Home
and submitting action on that route. Then try the same atAbout
. Observe thatAbout
works whileHome
(root index) doesn't.The text was updated successfully, but these errors were encountered: