Skip to content

Commit 586344f

Browse files
authored
Respect replace behavior on external redirects (#9654)
* Respect replace behavior on external redirects * Add changeset
1 parent 83b4758 commit 586344f

File tree

3 files changed

+47
-2
lines changed

3 files changed

+47
-2
lines changed

.changeset/itchy-phones-rush.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+
Respect `replace` behavior on external redirects

packages/router/__tests__/router-test.ts

Lines changed: 37 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5570,7 +5570,7 @@ describe("a router", () => {
55705570
});
55715571
});
55725572

5573-
it("processes external redirects if window is present", async () => {
5573+
it("processes external redirects if window is present (push)", async () => {
55745574
let urls = [
55755575
"http://remix.run/blog",
55765576
"https://remix.run/blog",
@@ -5583,6 +5583,7 @@ describe("a router", () => {
55835583
// https://stackoverflow.com/a/60697570
55845584
let oldLocation = window.location;
55855585
const location = new URL(window.location.href) as unknown as Location;
5586+
location.assign = jest.fn();
55865587
location.replace = jest.fn();
55875588
delete (window as any).location;
55885589
window.location = location as unknown as Location;
@@ -5594,8 +5595,43 @@ describe("a router", () => {
55945595
formData: createFormData({}),
55955596
});
55965597

5598+
await A.actions.child.redirectReturn(url);
5599+
expect(window.location.assign).toHaveBeenCalledWith(url);
5600+
expect(window.location.replace).not.toHaveBeenCalled();
5601+
5602+
window.location = oldLocation;
5603+
}
5604+
});
5605+
5606+
it("processes external redirects if window is present (replace)", async () => {
5607+
let urls = [
5608+
"http://remix.run/blog",
5609+
"https://remix.run/blog",
5610+
"//remix.run/blog",
5611+
"app://whatever",
5612+
];
5613+
5614+
for (let url of urls) {
5615+
// This is gross, don't blame me, blame SO :)
5616+
// https://stackoverflow.com/a/60697570
5617+
let oldLocation = window.location;
5618+
const location = new URL(window.location.href) as unknown as Location;
5619+
location.assign = jest.fn();
5620+
location.replace = jest.fn();
5621+
delete (window as any).location;
5622+
window.location = location as unknown as Location;
5623+
5624+
let t = setup({ routes: REDIRECT_ROUTES });
5625+
5626+
let A = await t.navigate("/parent/child", {
5627+
formMethod: "post",
5628+
formData: createFormData({}),
5629+
replace: true,
5630+
});
5631+
55975632
await A.actions.child.redirectReturn(url);
55985633
expect(window.location.replace).toHaveBeenCalledWith(url);
5634+
expect(window.location.assign).not.toHaveBeenCalled();
55995635

56005636
window.location = oldLocation;
56015637
}

packages/router/router.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1604,7 +1604,11 @@ export function createRouter(init: RouterInit): Router {
16041604
typeof window !== "undefined" &&
16051605
typeof window.location !== "undefined"
16061606
) {
1607-
window.location.replace(redirect.location);
1607+
if (replace) {
1608+
window.location.replace(redirect.location);
1609+
} else {
1610+
window.location.assign(redirect.location);
1611+
}
16081612
return;
16091613
}
16101614

0 commit comments

Comments
 (0)