Serverless-next.js: Trailing slashes on root pages return 404

Created on 1 Jul 2020  路  15Comments  路  Source: serverless-nextjs/serverless-next.js

Is your feature request related to a problem? Please describe.
Accessing root pages with a trailing slash (often how links get formatted in applications and sites we push them out to) returns the 404 page.

Describe the solution you'd like
I can see that [email protected], which is currently in canary, solves or at least addresses this problem, so hopefully this is something that can be maintained here as well, if the next update brings with it some additional resources to manage by this component.

Describe alternatives you've considered
We have tried supplying a set of hard redirects in next.config.js using "exportPathMap", which works locally but not when deployed using the serverless-next.js component. We have considered adding another lambda@edge to the CloudFront inputs that can trim the slash before landing into the component's routing logic, however that would increase latency. We have also considered just re-uploading the routing logic and altering the normaliseUri function to trim the trailing slash before the page manifest is searched by the uri, which is a wooden solution obviously (second to forking this project for altering that one function).

Thank you for any insight on this! Any stopgap ideas would be very appreciated as well.

Relevant pull request here https://github.com/serverless-nextjs/serverless-next.js/pull/448

Most helpful comment

This is available now (and various bugs should be fixed), please try out the latest alpha (1.17.0-alpha.9) and let us know if there are issues.

All 15 comments

The immediate solution would indeed be to fork this project and merge #448 in. You can then deploy from local serverless-components (look at CONTRIBUTING.md for reference).
I see a PR was merged for Next 9.4.5 to add experimental: { trailingSlash: true, },. I see this was mostly implemented to be read on the next-server side and not something that would be reflected in the manifests (from my understanding) which is largely how this lib handles routing. If @danielcondemarin is good with it, I think we can prematurely start implementing this feature now. We can check if the experimental flag was set in the next.config.js and do the stuff from #448 if it's set to true.

I'd normally recommend holding off merging until it becomes stable. Having said that if someone wants to take a stab and start putting together a PR go for it 馃憤

Ah of course! That bit about the separation between server and manifest routing makes sense. Thanks @lone-cloud

We're heading to production in a few days for ~3000 users/hour. This component has been absolutely instrumental in helping us achieve this in a sane way. Thank you both for the effort. I'm hoping we can ignore the trailing slashes for a few days yet, but this will definitely come back to us shortly. If anyone manages to take a look at that in the next week, that'd be awesome, otherwise it might be time for me to learn something here and contribute back. I definitely appreciate and agree with your comments in the linked pull request about not wanting to stray from next.js feature parity @danielcondemarin. Is my understanding correct that since next is tackling this issue, the closed pull request is potentially relevant again? If not, what is missing that I could add?

My plan was to leave this one for you :)

From what I see, it will not be copy/pasta of #448, but similar.
This is the Next-side of the implementation for this task: https://github.com/vercel/next.js/pull/13333
The driving force for this feature will be whether the experimental.trailingSlash=true value is set in the deploying Next.js project's next.config.js. As the lambdas are stateless, you will want to persist this configuration to the manifest.json (this is typed as OriginRequestDefaultHandlerManifest) - this will be done in lambda-at-edge/build.ts. The trailingSlash handling logic should live in the default lambda (default-handler.ts)... I'm undecided whether it's needed for the api lambda too. Next.js handles the trailingSlash stuff using https://github.com/vercel/next.js/blob/canary/packages/next/client/normalize-trailing-slash.ts (there were some fixes since the original PR was released).

GitHub
The React Framework. Contribute to vercel/next.js development by creating an account on GitHub.

Perfect, I'll have a hack next week. Thanks for the info!

I just ran into that issue too. Reloading /some-page/ works locally with [email protected] and experimental: { trailingSlash: true } but fails when deployed.

Perfect, I'll have a hack next week. Thanks for the info!

@medv If you are interested I'll add you to our contributors slack channel! DM me on twitter for an invite.

@danielcondemarin yep definitely, can't message you there it seems (don't use twitter other than having an account - might be restricted from messaging for this reason), so send me a link through github or to my twitter and I'll jump in.

@medv Is there anything I can do to help?

Hey Guys, is this related to #522?

I tried to not normalise the uri because I realise that slash is replaced with /index and my nonDynamic manifest does not have /index. But it still won't return my index.html i'm super confused

{"buildId":"nC8YxrWkgAPIuu0XtI9vL","pages":{"ssr":{"dynamic":{},"nonDynamic":{"/_error":"pages/_error.js"}},"html":{"dynamic":{},"nonDynamic":{"/":"pages/index.html","/404":"pages/404.html"}}},"publicFiles":{"/RT-BlackWhite.png":"RT-BlackWhite.png","/RT-Favicon.png":"RT-Favicon.png","/RT-Transparent.png":"RT-Transparent.png","/RT-big-logo.png":"RT-big-logo.png","/RT-small.png":"RT-small.png","/RT-white-background.png":"RT-white-background.png","/RT.png":"RT.png","/personal.JPG":"personal.JPG"}}

Same issue here.

mysite.com/contact works but mysite.com/contact/ return 404.

It works well on my computer (dev), but doesn't after pushing to AWS Lambda in production.

I have tried

module.exports = {
  trailingSlash: true,
}

from the official doc: https://nextjs.org/docs/api-reference/next.config.js/trailing-slash

and

module.exports = {
  experimental: { trailingSlash: true }
}

without success

It didn't seem like anyone was continuing work on this (complete trailingSlash support) so I took a stab at it based on all the suggestions so far (e.g https://github.com/serverless-nextjs/serverless-next.js/issues/479#issuecomment-653158270). Hopefully covered all of the major cases.

PR: https://github.com/serverless-nextjs/serverless-next.js/pull/556.

This is available now (and various bugs should be fixed), please try out the latest alpha (1.17.0-alpha.9) and let us know if there are issues.

It works well for me! Thanks!

Thanks for confirming, I'll close this issue now, please do open new one in case there are further issues.

Was this page helpful?
0 / 5 - 0 ratings