-
Notifications
You must be signed in to change notification settings - Fork 10.3k
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
Pass 'force' parameter for redirects #38640
Conversation
In the adapter, it seems like when |
https://docs.netlify.com/routing/redirects/redirect-options/#force-redirects Adding |
Can we add a unit test for this @jenae-janzen? Other tests are here: cc @pieh for guidance on this. |
packages/gatsby/src/redux/types.ts
Outdated
@@ -31,6 +31,7 @@ export interface IRedirect { | |||
redirectInBrowser?: boolean | |||
ignoreCase: boolean | |||
statusCode?: HttpStatusCode | |||
force?: boolean |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
force
is Netlify specific field - it has no meaning to Gatsby - it shouldn't be typed explicitly as this "type" of field is generally covered by [key: string]: any
below (as in it will accept any additional properties that might be used by specific platform
force?: boolean |
@@ -467,6 +467,7 @@ function getRoutesManifest(): RoutesManifest { | |||
(redirect.isPermanent | |||
? HTTP_STATUS_CODE.MOVED_PERMANENTLY_301 | |||
: HTTP_STATUS_CODE.FOUND_302), | |||
force: redirect.force, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Following on previous comment - as force
is example of a field that Gatsby itself doesn't use, I think that a bit more "robust" would be to pass all the fields in the redirect (apart of ones that are explicit).
Something along the lines of this:
// pick fields we explicitly handle, and pass remaining ones as "platform specific" fields
const { fromPath, toPath, statusCode, isPermanent, ignoreCase, redirectInBrowser, ...platformSpecificFields } = redirect
// note that `redirectInBrowser` field will be unused - if that is `true` there is redirect mechanism in browser runtime to handle the redirects (regardless of value of this field we always want all redirects handled by "the server")
addRoute({
path: fromPath,
// [...] rest of the fields we already have here adjusting for the fact we destructured `redirect` already
// so we can omit `redirect.` from most things
// pass any unknown platform specific fields so platform adapter can use them
...platformSpecificFields
})
I think this change would also help with the somewhat related conditions
issue not being honored (that might require additional look in https://github.com/gatsbyjs/gatsby/blob/master/packages/gatsby-adapter-netlify/src/route-handler.ts but there is code that was moved from previous plugins already so it might "just work" after actually passing conditions
in)
gatsby/packages/gatsby/src/utils/adapter/__tests__/fixtures/state.ts Lines 67 to 73 in 3af35ae
force: true and assertion would be that this field exist and has expected value in one of the routes in routesManifest .
Setup in gatsby/packages/gatsby/src/utils/adapter/__tests__/manager.ts Lines 48 to 56 in 3af35ae
trailingSlash for this that other tests are checking).
The other part of unit testing ideally is done in adapter unit tests (check if And finally for E2E we would need to add redirect here https://github.com/gatsbyjs/gatsby/blob/master/e2e-tests/adapters/gatsby-node.ts with gatsby/e2e-tests/adapters/cypress/e2e/redirects.cy.ts Lines 14 to 29 in 3af35ae
force: true we expect redirect to take precedense
|
// conditions: { language: [`ca`, `us`] }, | ||
// } | ||
|
||
// await handleRoutesManifest([redirects]) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Still trying to figure out how to test this, since handleRoutesManifest
doesn't return anything to check against. Using the debugger, I can see the status being set to 200!
within the method (and also parsing the conditions 🎉), but can't read the output injectEntries
writes to public/_redirects
from the test.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let's split handleRoutesManifest
into 2 functions - one that does most of the work and returns the _redirect
and _headers
content which we can assert and the other one (probably will keep existing name) that calls the new function and then call injectEntries
with results
That would allow for easy assertion (without creating some kind of spy, mocks or allowing function to actually write the files out and then read that file back).
Does that sound fine?
headers: BASE_HEADERS, | ||
platformSpecificFields, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
platformSpecificFields, | |
...platformSpecificFields, |
otherwise this would not really match this (public) type
gatsby/packages/gatsby/src/utils/adapter/types.ts
Lines 47 to 64 in 5dbcf9e
export interface IRedirectRoute extends IBaseRoute { | |
type: `redirect` | |
/** | |
* The redirect should happen from `path` to `toPath`. | |
*/ | |
toPath: string | |
/** | |
* HTTP status code that should be used for this redirect. | |
*/ | |
status: HttpStatusCode | |
ignoreCase?: boolean | |
/** | |
* HTTP headers that should be used for this redirect. | |
* @see http://www.gatsbyjs.com/docs/how-to/previews-deploys-hosting/headers/ | |
*/ | |
headers: IHeader["headers"] | |
[key: string]: unknown | |
} |
(technically it does matches it, but this is more that shape of redirect is more about having platform specific fields as top level fields and not have actual platformSpecificFields
field that is object with platform specific fields.
Also with this as-is the current code in this PR in packages/gatsby-adapter-netlify/src/route-handler.ts wouldn't actually work as it does expect force
field to be top-level field and not nested under platformSpecificFields
This change will need some adjustment in test added to packages/gatsby/src/utils/adapter/tests/manager.ts
Closing this one in favor of #38657 |
https://linear.app/netlify/issue/FRA-19/force-is-not-honoured
When a redirect is created, it can accept a force parameter that can trigger the redirect even if the
fromPath
matches a piece of content. However, this functionality isn't working with the Adapter, possibly because the parameter isn't being passed along into the routes handler.Description
Documentation
Tests
Related Issues
Fixes FRA-19