diff --git a/e2e-tests/adapters/cypress/e2e/redirects.cy.ts b/e2e-tests/adapters/cypress/e2e/redirects.cy.ts
index 2ef68bd05c522..08d9f4a9f19ac 100644
--- a/e2e-tests/adapters/cypress/e2e/redirects.cy.ts
+++ b/e2e-tests/adapters/cypress/e2e/redirects.cy.ts
@@ -1,6 +1,6 @@
import { applyTrailingSlashOption } from "../../utils"
-Cypress.on("uncaught:exception", (err) => {
+Cypress.on("uncaught:exception", err => {
if (err.message.includes("Minified React error")) {
return false
}
@@ -14,44 +14,149 @@ describe("Redirects", () => {
it("should redirect from non-existing page to existing", () => {
cy.visit(applyTrailingSlashOption(`/redirect`, TRAILING_SLASH), {
failOnStatusCode: false,
- }).waitForRouteChange()
- .assertRoute(applyTrailingSlashOption(`/routes/redirect/hit`, TRAILING_SLASH))
+ })
+ .waitForRouteChange()
+ .assertRoute(
+ applyTrailingSlashOption(`/routes/redirect/hit`, TRAILING_SLASH)
+ )
cy.get(`h1`).should(`have.text`, `Hit`)
})
it("should respect that pages take precedence over redirects", () => {
- cy.visit(applyTrailingSlashOption(`/routes/redirect/existing`, TRAILING_SLASH), {
- failOnStatusCode: false,
- }).waitForRouteChange()
- .assertRoute(applyTrailingSlashOption(`/routes/redirect/existing`, TRAILING_SLASH))
+ cy.visit(
+ applyTrailingSlashOption(`/routes/redirect/existing`, TRAILING_SLASH),
+ {
+ failOnStatusCode: false,
+ }
+ )
+ .waitForRouteChange()
+ .assertRoute(
+ applyTrailingSlashOption(`/routes/redirect/existing`, TRAILING_SLASH)
+ )
cy.get(`h1`).should(`have.text`, `Existing`)
})
+ it("should respect force redirect", () => {
+ cy.visit(
+ applyTrailingSlashOption(
+ `/routes/redirect/existing-force`,
+ TRAILING_SLASH
+ ),
+ {
+ failOnStatusCode: false,
+ }
+ )
+ .waitForRouteChange()
+ .assertRoute(
+ applyTrailingSlashOption(`/routes/redirect/hit`, TRAILING_SLASH)
+ )
+
+ cy.get(`h1`).should(`have.text`, `Hit`)
+ })
+ it("should respect country condition on redirect", () => {
+ cy.visit(
+ applyTrailingSlashOption(
+ `/routes/redirect/country-condition`,
+ TRAILING_SLASH
+ ),
+ {
+ failOnStatusCode: false,
+ headers: {
+ "x-nf-country": "us",
+ },
+ }
+ )
+ .waitForRouteChange()
+ .assertRoute(
+ applyTrailingSlashOption(`/routes/redirect/hit-us`, TRAILING_SLASH)
+ )
+
+ cy.get(`h1`).should(`have.text`, `Hit US`)
+
+ cy.visit(
+ applyTrailingSlashOption(
+ `/routes/redirect/country-condition`,
+ TRAILING_SLASH
+ ),
+ {
+ failOnStatusCode: false,
+ headers: {
+ "x-nf-country": "de",
+ },
+ }
+ )
+ .waitForRouteChange()
+ .assertRoute(
+ applyTrailingSlashOption(`/routes/redirect/hit-de`, TRAILING_SLASH)
+ )
+
+ cy.get(`h1`).should(`have.text`, `Hit DE`)
+
+ // testing fallback
+ cy.visit(
+ applyTrailingSlashOption(
+ `/routes/redirect/country-condition`,
+ TRAILING_SLASH
+ ),
+ {
+ failOnStatusCode: false,
+ headers: {
+ "x-nf-country": "fr",
+ },
+ }
+ )
+ .waitForRouteChange()
+ .assertRoute(
+ applyTrailingSlashOption(`/routes/redirect/hit`, TRAILING_SLASH)
+ )
+
+ cy.get(`h1`).should(`have.text`, `Hit`)
+ })
it("should support hash parameter on direct visit", () => {
- cy.visit(applyTrailingSlashOption(`/redirect`, TRAILING_SLASH) + `#anchor`, {
- failOnStatusCode: false,
- }).waitForRouteChange()
+ cy.visit(
+ applyTrailingSlashOption(`/redirect`, TRAILING_SLASH) + `#anchor`,
+ {
+ failOnStatusCode: false,
+ }
+ ).waitForRouteChange()
- cy.location(`pathname`).should(`equal`, applyTrailingSlashOption(`/routes/redirect/hit`, TRAILING_SLASH))
+ cy.location(`pathname`).should(
+ `equal`,
+ applyTrailingSlashOption(`/routes/redirect/hit`, TRAILING_SLASH)
+ )
cy.location(`hash`).should(`equal`, `#anchor`)
cy.location(`search`).should(`equal`, ``)
})
it("should support search parameter on direct visit", () => {
- cy.visit(applyTrailingSlashOption(`/redirect`, TRAILING_SLASH) + `?query_param=hello`, {
- failOnStatusCode: false,
- }).waitForRouteChange()
+ cy.visit(
+ applyTrailingSlashOption(`/redirect`, TRAILING_SLASH) +
+ `?query_param=hello`,
+ {
+ failOnStatusCode: false,
+ }
+ ).waitForRouteChange()
- cy.location(`pathname`).should(`equal`, applyTrailingSlashOption(`/routes/redirect/hit`, TRAILING_SLASH))
+ cy.location(`pathname`).should(
+ `equal`,
+ applyTrailingSlashOption(`/routes/redirect/hit`, TRAILING_SLASH)
+ )
cy.location(`hash`).should(`equal`, ``)
cy.location(`search`).should(`equal`, `?query_param=hello`)
})
it("should support search & hash parameter on direct visit", () => {
- cy.visit(applyTrailingSlashOption(`/redirect`, TRAILING_SLASH) + `?query_param=hello#anchor`, {
- failOnStatusCode: false,
- }).waitForRouteChange()
+ cy.visit(
+ applyTrailingSlashOption(`/redirect`, TRAILING_SLASH) +
+ `?query_param=hello#anchor`,
+ {
+ failOnStatusCode: false,
+ }
+ ).waitForRouteChange()
- cy.location(`pathname`).should(`equal`, applyTrailingSlashOption(`/routes/redirect/hit`, TRAILING_SLASH))
+ cy.location(`pathname`).should(
+ `equal`,
+ applyTrailingSlashOption(`/routes/redirect/hit`, TRAILING_SLASH)
+ )
cy.location(`hash`).should(`equal`, `#anchor`)
cy.location(`search`).should(`equal`, `?query_param=hello`)
})
-})
\ No newline at end of file
+})
diff --git a/e2e-tests/adapters/gatsby-node.ts b/e2e-tests/adapters/gatsby-node.ts
index 0df93fcc92857..85a9e3b2ca007 100644
--- a/e2e-tests/adapters/gatsby-node.ts
+++ b/e2e-tests/adapters/gatsby-node.ts
@@ -2,15 +2,57 @@ import * as path from "path"
import type { GatsbyNode, GatsbyConfig } from "gatsby"
import { applyTrailingSlashOption } from "./utils"
-const TRAILING_SLASH = (process.env.TRAILING_SLASH || `never`) as GatsbyConfig["trailingSlash"]
+const TRAILING_SLASH = (process.env.TRAILING_SLASH ||
+ `never`) as GatsbyConfig["trailingSlash"]
-export const createPages: GatsbyNode["createPages"] = ({ actions: { createRedirect, createSlice } }) => {
+export const createPages: GatsbyNode["createPages"] = ({
+ actions: { createRedirect, createSlice },
+}) => {
createRedirect({
fromPath: applyTrailingSlashOption("/redirect", TRAILING_SLASH),
toPath: applyTrailingSlashOption("/routes/redirect/hit", TRAILING_SLASH),
})
createRedirect({
- fromPath: applyTrailingSlashOption("/routes/redirect/existing", TRAILING_SLASH),
+ fromPath: applyTrailingSlashOption(
+ "/routes/redirect/existing",
+ TRAILING_SLASH
+ ),
+ toPath: applyTrailingSlashOption("/routes/redirect/hit", TRAILING_SLASH),
+ })
+ createRedirect({
+ fromPath: applyTrailingSlashOption(
+ "/routes/redirect/existing-force",
+ TRAILING_SLASH
+ ),
+ toPath: applyTrailingSlashOption("/routes/redirect/hit", TRAILING_SLASH),
+ force: true,
+ })
+ createRedirect({
+ fromPath: applyTrailingSlashOption(
+ "/routes/redirect/country-condition",
+ TRAILING_SLASH
+ ),
+ toPath: applyTrailingSlashOption("/routes/redirect/hit-us", TRAILING_SLASH),
+ conditions: {
+ country: ["us"],
+ },
+ })
+ createRedirect({
+ fromPath: applyTrailingSlashOption(
+ "/routes/redirect/country-condition",
+ TRAILING_SLASH
+ ),
+ toPath: applyTrailingSlashOption("/routes/redirect/hit-de", TRAILING_SLASH),
+ conditions: {
+ country: ["de"],
+ },
+ })
+ // fallback if not matching a country condition
+ createRedirect({
+ fromPath: applyTrailingSlashOption(
+ "/routes/redirect/country-condition",
+ TRAILING_SLASH
+ ),
toPath: applyTrailingSlashOption("/routes/redirect/hit", TRAILING_SLASH),
})
@@ -19,4 +61,4 @@ export const createPages: GatsbyNode["createPages"] = ({ actions: { createRedire
component: path.resolve(`./src/components/footer.jsx`),
context: {},
})
-}
\ No newline at end of file
+}
diff --git a/e2e-tests/adapters/scripts/deploy-and-run/netlify.mjs b/e2e-tests/adapters/scripts/deploy-and-run/netlify.mjs
index 9c9e5f1619643..ed09a06299eac 100644
--- a/e2e-tests/adapters/scripts/deploy-and-run/netlify.mjs
+++ b/e2e-tests/adapters/scripts/deploy-and-run/netlify.mjs
@@ -32,6 +32,8 @@ const deployInfo = JSON.parse(deployResults.stdout)
process.env.DEPLOY_URL = deployInfo.deploy_url
+console.log(`Deployed to ${deployInfo.deploy_url}`)
+
try {
await execa(`npm`, [`run`, npmScriptToRun], { stdio: `inherit` })
} finally {
diff --git a/e2e-tests/adapters/src/pages/routes/redirect/existing-force.jsx b/e2e-tests/adapters/src/pages/routes/redirect/existing-force.jsx
new file mode 100644
index 0000000000000..83a6399ab2535
--- /dev/null
+++ b/e2e-tests/adapters/src/pages/routes/redirect/existing-force.jsx
@@ -0,0 +1,14 @@
+import * as React from "react"
+import Layout from "../../../components/layout"
+
+const ExistingForcePage = () => {
+ return (
+ Existing Force
+