Skip to content
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

feat(gatsby): ignore case option in create redirect #29742

Merged
merged 13 commits into from
Feb 25, 2021
Merged
12 changes: 12 additions & 0 deletions e2e-tests/production-runtime/cypress/integration/redirects.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
describe(`Redirects`, () => {
it(`are case insensitive when ignoreCase is set to true`, () => {
cy.visit(`/Longue-PAGE`, { failOnStatusCode: false }).waitForRouteChange()

cy.get(`h1`).invoke(`text`).should(`contain`, `Hi from the long page`)
})
it(`are case sensitive when ignoreCase is set to false`, () => {
cy.visit(`/PAGINA-larga`, { failOnStatusCode: false }).waitForRouteChange()

cy.get(`h1`).invoke(`text`).should(`contain`, `NOT FOUND`)
})
})
18 changes: 17 additions & 1 deletion e2e-tests/production-runtime/gatsby-node.js
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ exports.sourceNodes = ({ actions, createNodeId }) => {
})
}

exports.createPages = ({ actions: { createPage } }) => {
exports.createPages = ({ actions: { createPage, createRedirect } }) => {
createPage({
path: `/안녕`,
component: path.resolve(`src/pages/page-2.js`),
Expand Down Expand Up @@ -124,6 +124,22 @@ exports.createPages = ({ actions: { createPage } }) => {
path: `/page-from-cache/`,
component: path.resolve(`./.cache/static-page-from-cache.js`),
})

createRedirect({
fromPath: "/pagina-larga",
toPath: "/long-page",
isPermanent: true,
redirectInBrowser: true,
ignoreCase: false,
})

createRedirect({
fromPath: "/Longue-Page",
toPath: "/long-page",
isPermanent: true,
redirectInBrowser: true,
ignoreCase: true,
})
}

exports.onCreatePage = ({ page, actions }) => {
Expand Down
25 changes: 19 additions & 6 deletions packages/gatsby/cache-dir/navigation.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,23 @@ import { globalHistory } from "@reach/router/lib/history"
import { parsePath } from "gatsby-link"

// Convert to a map for faster lookup in maybeRedirect()
const redirectMap = redirects.reduce((map, redirect) => {
map[redirect.fromPath] = redirect
return map
}, {})

const redirectMap = new Map()
const redirectIgnoreCaseMap = new Map()

redirects.forEach(redirect => {
if (redirect.ignoreCase) {
redirectIgnoreCaseMap.set(redirect.fromPath, redirect)
} else {
redirectMap.set(redirect.fromPath, redirect)
}
})

function maybeRedirect(pathname) {
const redirect = redirectMap[pathname]
let redirect = redirectMap.get(pathname)
if (!redirect) {
redirect = redirectIgnoreCaseMap.get(pathname.toLowerCase())
}

if (redirect != null) {
if (process.env.NODE_ENV !== `production`) {
Expand Down Expand Up @@ -62,7 +72,10 @@ const navigate = (to, options = {}) => {
}

let { pathname } = parsePath(to)
const redirect = redirectMap[pathname]
let redirect = redirectMap.get(pathname)
if (!redirect) {
redirect = redirectIgnoreCaseMap.get(pathname.toLowerCase())
}

// If we're redirecting, just replace the passed in pathname
// to the one we want to redirect to.
Expand Down
1 change: 1 addition & 0 deletions packages/gatsby/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1256,6 +1256,7 @@ export interface Actions {
redirectInBrowser?: boolean
force?: boolean
statusCode?: number
ignoreCase?: boolean
[key: string]: unknown
},
plugin?: ActionPlugin
Expand Down
10 changes: 9 additions & 1 deletion packages/gatsby/src/bootstrap/redirects-writer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,15 @@ export const writeRedirects = async (): Promise<void> => {
const browserRedirects = redirects
.filter(r => r.redirectInBrowser)
// eslint-disable-next-line @typescript-eslint/no-unused-vars
.map(({ redirectInBrowser, isPermanent, ...rest }) => rest)
.map(
({ redirectInBrowser, isPermanent, ignoreCase, fromPath, ...rest }) => {
return {
fromPath: ignoreCase ? fromPath.toLowerCase() : fromPath,
ignoreCase,
...rest,
}
}
)

const newHash = crypto
.createHash(`md5`)
Expand Down
52 changes: 0 additions & 52 deletions packages/gatsby/src/query/redirects-writer.ts

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ exports[`Add redirects allows you to add redirects 1`] = `
Object {
"payload": Object {
"fromPath": "/old/hello-world",
"ignoreCase": false,
"isPermanent": false,
"redirectInBrowser": false,
"toPath": "/new/hello-world",
Expand All @@ -16,6 +17,7 @@ exports[`Add redirects create redirects as permanent 1`] = `
Object {
"payload": Object {
"fromPath": "/old/hello-world",
"ignoreCase": false,
"isPermanent": true,
"redirectInBrowser": false,
"toPath": "/new/hello-world",
Expand All @@ -28,6 +30,7 @@ exports[`Add redirects creates redirects from the URL starts with // 1`] = `
Object {
"payload": Object {
"fromPath": "//example.com",
"ignoreCase": false,
"isPermanent": false,
"redirectInBrowser": false,
"toPath": "/new/hello-world-2",
Expand All @@ -40,6 +43,7 @@ exports[`Add redirects creates redirects from the URL starts with ftp 1`] = `
Object {
"payload": Object {
"fromPath": "ftp://example.com",
"ignoreCase": false,
"isPermanent": false,
"redirectInBrowser": false,
"toPath": "/new/hello-world-3",
Expand All @@ -52,6 +56,7 @@ exports[`Add redirects creates redirects from the URL starts with http 1`] = `
Object {
"payload": Object {
"fromPath": "http://example.com",
"ignoreCase": false,
"isPermanent": false,
"redirectInBrowser": false,
"toPath": "/new/hello-world-1",
Expand All @@ -64,6 +69,7 @@ exports[`Add redirects creates redirects from the URL starts with https 1`] = `
Object {
"payload": Object {
"fromPath": "https://example.com",
"ignoreCase": false,
"isPermanent": false,
"redirectInBrowser": false,
"toPath": "/new/hello-world-0",
Expand All @@ -76,6 +82,7 @@ exports[`Add redirects creates redirects from the URL starts with mailto 1`] = `
Object {
"payload": Object {
"fromPath": "mailto:[email protected]",
"ignoreCase": false,
"isPermanent": false,
"redirectInBrowser": false,
"toPath": "/new/hello-world-4",
Expand All @@ -88,6 +95,7 @@ exports[`Add redirects creates redirects to the URL starts with // 1`] = `
Object {
"payload": Object {
"fromPath": "/old/hello-world-2",
"ignoreCase": false,
"isPermanent": false,
"redirectInBrowser": false,
"toPath": "//example.com",
Expand All @@ -100,6 +108,7 @@ exports[`Add redirects creates redirects to the URL starts with ftp 1`] = `
Object {
"payload": Object {
"fromPath": "/old/hello-world-3",
"ignoreCase": false,
"isPermanent": false,
"redirectInBrowser": false,
"toPath": "ftp://example.com",
Expand All @@ -112,6 +121,7 @@ exports[`Add redirects creates redirects to the URL starts with http 1`] = `
Object {
"payload": Object {
"fromPath": "/old/hello-world-1",
"ignoreCase": false,
"isPermanent": false,
"redirectInBrowser": false,
"toPath": "http://example.com",
Expand All @@ -124,6 +134,7 @@ exports[`Add redirects creates redirects to the URL starts with https 1`] = `
Object {
"payload": Object {
"fromPath": "/old/hello-world-0",
"ignoreCase": false,
"isPermanent": false,
"redirectInBrowser": false,
"toPath": "https://example.com",
Expand All @@ -136,6 +147,7 @@ exports[`Add redirects creates redirects to the URL starts with mailto 1`] = `
Object {
"payload": Object {
"fromPath": "/old/hello-world-4",
"ignoreCase": false,
"isPermanent": false,
"redirectInBrowser": false,
"toPath": "mailto:[email protected]",
Expand All @@ -148,6 +160,7 @@ exports[`Add redirects creates redirects with in-browser redirect option 1`] = `
Object {
"payload": Object {
"fromPath": "/old/hello-world",
"ignoreCase": false,
"isPermanent": false,
"redirectInBrowser": true,
"toPath": "/new/hello-world",
Expand All @@ -160,6 +173,7 @@ exports[`Add redirects with path prefixs allows you to add redirects 1`] = `
Object {
"payload": Object {
"fromPath": "/blog/old/hello-world",
"ignoreCase": false,
"isPermanent": false,
"redirectInBrowser": false,
"toPath": "/blog/new/hello-world",
Expand All @@ -172,6 +186,7 @@ exports[`Add redirects with path prefixs create redirects as permanent 1`] = `
Object {
"payload": Object {
"fromPath": "/blog/old/hello-world",
"ignoreCase": false,
"isPermanent": true,
"redirectInBrowser": false,
"toPath": "/blog/new/hello-world",
Expand All @@ -184,6 +199,7 @@ exports[`Add redirects with path prefixs creates redirects from the URL starts w
Object {
"payload": Object {
"fromPath": "//example.com",
"ignoreCase": false,
"isPermanent": false,
"redirectInBrowser": false,
"toPath": "/blog/new/hello-world-2",
Expand All @@ -196,6 +212,7 @@ exports[`Add redirects with path prefixs creates redirects from the URL starts w
Object {
"payload": Object {
"fromPath": "ftp://example.com",
"ignoreCase": false,
"isPermanent": false,
"redirectInBrowser": false,
"toPath": "/blog/new/hello-world-3",
Expand All @@ -208,6 +225,7 @@ exports[`Add redirects with path prefixs creates redirects from the URL starts w
Object {
"payload": Object {
"fromPath": "http://example.com",
"ignoreCase": false,
"isPermanent": false,
"redirectInBrowser": false,
"toPath": "/blog/new/hello-world-1",
Expand All @@ -220,6 +238,7 @@ exports[`Add redirects with path prefixs creates redirects from the URL starts w
Object {
"payload": Object {
"fromPath": "https://example.com",
"ignoreCase": false,
"isPermanent": false,
"redirectInBrowser": false,
"toPath": "/blog/new/hello-world-0",
Expand All @@ -232,6 +251,7 @@ exports[`Add redirects with path prefixs creates redirects from the URL starts w
Object {
"payload": Object {
"fromPath": "mailto:[email protected]",
"ignoreCase": false,
"isPermanent": false,
"redirectInBrowser": false,
"toPath": "/blog/new/hello-world-4",
Expand All @@ -244,6 +264,7 @@ exports[`Add redirects with path prefixs creates redirects to the URL starts wit
Object {
"payload": Object {
"fromPath": "/blog/old/hello-world-2",
"ignoreCase": false,
"isPermanent": false,
"redirectInBrowser": false,
"toPath": "//example.com",
Expand All @@ -256,6 +277,7 @@ exports[`Add redirects with path prefixs creates redirects to the URL starts wit
Object {
"payload": Object {
"fromPath": "/blog/old/hello-world-3",
"ignoreCase": false,
"isPermanent": false,
"redirectInBrowser": false,
"toPath": "ftp://example.com",
Expand All @@ -268,6 +290,7 @@ exports[`Add redirects with path prefixs creates redirects to the URL starts wit
Object {
"payload": Object {
"fromPath": "/blog/old/hello-world-1",
"ignoreCase": false,
"isPermanent": false,
"redirectInBrowser": false,
"toPath": "http://example.com",
Expand All @@ -280,6 +303,7 @@ exports[`Add redirects with path prefixs creates redirects to the URL starts wit
Object {
"payload": Object {
"fromPath": "/blog/old/hello-world-0",
"ignoreCase": false,
"isPermanent": false,
"redirectInBrowser": false,
"toPath": "https://example.com",
Expand All @@ -292,6 +316,7 @@ exports[`Add redirects with path prefixs creates redirects to the URL starts wit
Object {
"payload": Object {
"fromPath": "/blog/old/hello-world-4",
"ignoreCase": false,
"isPermanent": false,
"redirectInBrowser": false,
"toPath": "mailto:[email protected]",
Expand All @@ -304,6 +329,7 @@ exports[`Add redirects with path prefixs creates redirects with in-browser redir
Object {
"payload": Object {
"fromPath": "/blog/old/hello-world",
"ignoreCase": false,
"isPermanent": false,
"redirectInBrowser": true,
"toPath": "/blog/new/hello-world",
Expand Down
3 changes: 3 additions & 0 deletions packages/gatsby/src/redux/actions/public.js
Original file line number Diff line number Diff line change
Expand Up @@ -1299,6 +1299,7 @@ const maybeAddPathPrefix = (path, pathPrefix) => {
* @param {boolean} redirect.redirectInBrowser Redirects are generally for redirecting legacy URLs to their new configuration. If you can't update your UI for some reason, set `redirectInBrowser` to true and Gatsby will handle redirecting in the client as well.
* @param {boolean} redirect.force (Plugin-specific) Will trigger the redirect even if the `fromPath` matches a piece of content. This is not part of the Gatsby API, but implemented by (some) plugins that configure hosting provider redirects
* @param {number} redirect.statusCode (Plugin-specific) Manually set the HTTP status code. This allows you to create a rewrite (status code 200) or custom error page (status code 404). Note that this will override the `isPermanent` option which also sets the status code. This is not part of the Gatsby API, but implemented by (some) plugins that configure hosting provider redirects
* @param {boolean} redirect.ignoreCase (Plugin-specific) Ignore case when looking for redirects
* @example
* // Generally you create redirects while creating pages.
* exports.createPages = ({ graphql, actions }) => {
Expand All @@ -1314,6 +1315,7 @@ actions.createRedirect = ({
isPermanent = false,
redirectInBrowser = false,
toPath,
ignoreCase = false,
...rest
}) => {
let pathPrefix = ``
Expand All @@ -1326,6 +1328,7 @@ actions.createRedirect = ({
payload: {
fromPath: maybeAddPathPrefix(fromPath, pathPrefix),
isPermanent,
ignoreCase,
redirectInBrowser,
toPath: maybeAddPathPrefix(toPath, pathPrefix),
...rest,
Expand Down
Loading