Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/rare-jobs-remember.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"react-router": patch
---

[REMOVE] Follow up to https://github.com/remix-run/react-router/pull/14321 to avoid issues with rolling deployments
19 changes: 19 additions & 0 deletions packages/react-router/lib/dom/ssr/fog-of-war.ts
Original file line number Diff line number Diff line change
Expand Up @@ -242,6 +242,25 @@ export async function fetchAndApplyManifestPatches(
try {
let res = await fetch(url, { signal });

// To avoid issues during rolling deployments if we get back a 400 when
// using `paths`, it's likely we hit an old server so retry the request
// with the old `p` parameters
if (res.status === 400) {
let body = await res.text();
if (body !== "Invalid Request") {
throw new Error(`${res.status} ${res.statusText}`);
}
const retrySearchParams = new URLSearchParams();
paths.sort().forEach((path) => retrySearchParams.append("p", path));
retrySearchParams.set("version", manifest.version);
let url = new URL(
getManifestPath(manifestPath, basename),
window.location.origin,
);
url.search = retrySearchParams.toString();
res = await fetch(url, { signal });
}

if (!res.ok) {
throw new Error(`${res.status} ${res.statusText}`);
} else if (
Expand Down
26 changes: 15 additions & 11 deletions packages/react-router/lib/server-runtime/server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -354,19 +354,15 @@ async function handleManifestRequest(

let patches: Record<string, EntryRoute> = {};

if (url.searchParams.has("paths")) {
// Support both the old (`p`) and new formats (`paths`) to avoid issues during
// rolling deployments where an old client hits a new server
if (url.searchParams.has("p") || url.searchParams.has("paths")) {
let paths = new Set<string>();

// In addition to responding with the patches for the requested paths, we
// need to include patches for each partial path so that we pick up any
// pathless/index routes below ancestor segments. So if we
// get a request for `/parent/child`, we need to look for a match on `/parent`
// so that if a `parent._index` route exists we return it so it's available
// for client side matching if the user routes back up to `/parent`.
// This is the same thing we do on initial load in <Scripts> via
// `getPartialManifest()`
let pathParam = url.searchParams.get("paths") || "";
let requestedPaths = pathParam.split(",").filter(Boolean);
let requestedPaths = url.searchParams.has("paths")
? (url.searchParams.get("paths") || "").split(",").filter(Boolean)
: url.searchParams.getAll("p");

requestedPaths.forEach((path) => {
if (!path.startsWith("/")) {
path = `/${path}`;
Expand All @@ -378,6 +374,14 @@ async function handleManifestRequest(
});
});

// In addition to responding with the patches for the requested paths, we
// need to include patches for each partial path so that we pick up any
// pathless/index routes below ancestor segments. So if we
// get a request for `/parent/child`, we need to look for a match on `/parent`
// so that if a `parent._index` route exists we return it so it's available
// for client side matching if the user routes back up to `/parent`.
// This is the same thing we do on initial load in <Scripts> via
// `getPartialManifest()`
for (let path of paths) {
let matches = matchServerRoutes(routes, path, build.basename);
if (matches) {
Expand Down