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

[Bug]: ISR in combination with nextjs rewrites not working #2129

Closed
3 tasks
terrabythia opened this issue May 21, 2023 · 4 comments
Closed
3 tasks

[Bug]: ISR in combination with nextjs rewrites not working #2129

terrabythia opened this issue May 21, 2023 · 4 comments
Labels

Comments

@terrabythia
Copy link

Summary

In a nextjs project when using a catch all directory structure (eg /pages/[...pages]/index.js) that uses ISR and combining it with a custom rewrites in next.config.js using SSR, the SSR page does not work correctly.

The ISR pages work correctly, but any pages that are part of a rewrite don't get the URL search params (context.query) passed in. Also, looking at Netlify's function logs, the logs that should be under "Next.js SSR Handler" appear under the "Next.js ISR handler", so it looks like there is a problem with the way the page is actually rendered.

I have verified that this problem does not occur locally and when deployed on either vercel.com or render.com.

A link to a reproduction repository

https://github.com/terrabythia/netlify-rewrite-test

Expected Result

Expected to see query params not set on any URL because the page is rendered using ISR, except for the url /render/ssr because it's rendered using SSR.

Actual Result

Netlify shows no query params on the page /render/ssr and is not actually rendering the page on every load (which is also showing in the function logs).

Any URL except the one in the rewrite works correctly on all platforms including Netlify.
Vercel: https://netlify-rewrite-test-eta.vercel.app/any/url
Render: https://netlify-rewrite-test.onrender.com/any/url
Netlify: https://netlify-rewrite-test-2.netlify.app/any/url

The url /render/ssr is part of the rewrites in next.config.js and works correctly on all platforms except Netlify (see query params):
Vercel: https://netlify-rewrite-test-eta.vercel.app/render/ssr?test=true
Render: https://netlify-rewrite-test.onrender.com/render/ssr?test=true
Netlify: https://netlify-rewrite-test-2.netlify.app/render/ssr?test=true

Steps to reproduce

  1. Add some catch-all directory structure (eg /pages/[...pages]/index.js) and use getStaticProps to render using ISR
  2. Add one rewrite to next.config.js that routes to another page component (eg /pages/ssr/[...pages]/index.js) which uses getServerSideProps to render using SSR.
  3. Go to the url that is in the rewrite and append any query params to the URL

Next Runtime version

13.3.4

Is your issue related to the app directory?

  • Yes, I am using the app directory

More information about your build

  • I am building using the CLI
  • I am building using file-based configuration (netlify.toml)

What OS are you using?

None

Your netlify.toml file

No response

Your public/_redirects file

No response

Your next.config.js file

`next.config.js`
const nextConfig = {
  reactStrictMode: true,
  rewrites: async () => [
    {
      source: '/render/ssr',
      destination: '/dynamic-pages/render/ssr',
      locale: false,
    }
  ]
}

module.exports = nextConfig

Builds logs (or link to your logs)

Build logs
9:52:56 AM: build-image version: 4b067841aaa59ef71931d3505b98c2bc3e63f36f (focal)
9:52:56 AM: buildbot version: 4b067841aaa59ef71931d3505b98c2bc3e63f36f
9:52:56 AM: Fetching cached dependencies
9:52:56 AM: Starting to download cache of 165.9MB
9:52:58 AM: Finished downloading cache in 1.715s
9:52:58 AM: Starting to extract cache
9:52:59 AM: Finished extracting cache in 1.132s
9:52:59 AM: Finished fetching cache in 2.909s
9:52:59 AM: Starting to prepare the repo for build
9:52:59 AM: Preparing Git Reference refs/heads/main
9:53:00 AM: Parsing package.json dependencies
9:53:01 AM: Starting to install dependencies
9:53:01 AM: Python version set to 3.8
9:53:01 AM: Attempting Ruby version 2.7.2, read from environment
9:53:02 AM: Using Ruby version 2.7.2
9:53:02 AM: Started restoring cached go cache
9:53:02 AM: Finished restoring cached go cache
9:53:02 AM: go version go1.19.9 linux/amd64
9:53:03 AM: Using PHP version 8.0
9:53:03 AM: Started restoring cached Node.js version
9:53:04 AM: Finished restoring cached Node.js version
9:53:04 AM: Attempting Node.js version '16.20.0' from .nvmrc
9:53:04 AM: v16.20.0 is already installed.
9:53:04 AM: Now using node v16.20.0 (npm v8.19.4)
9:53:04 AM: Enabling Node.js Corepack
9:53:05 AM: Started restoring cached build plugins
9:53:05 AM: Finished restoring cached build plugins
9:53:05 AM: Started restoring cached corepack dependencies
9:53:05 AM: Finished restoring cached corepack dependencies
9:53:05 AM: No npm workspaces detected
9:53:05 AM: Started restoring cached node modules
9:53:05 AM: Finished restoring cached node modules
9:53:05 AM: Installing npm packages using npm version 8.19.4
9:53:09 AM: removed 1 package, changed 6 packages, and audited 294 packages in 4s
9:53:09 AM: 124 packages are looking for funding
9:53:09 AM:   run `npm fund` for details
9:53:09 AM: found 0 vulnerabilities
9:53:09 AM: npm packages installed
9:53:09 AM: Install dependencies script success
9:53:09 AM: Starting build script
9:53:10 AM: Detected 1 framework(s)
9:53:10 AM: "next" at version "13.3.4"
9:53:10 AM: Section completed: initializing
9:53:11 AM: ​
9:53:11 AM: Netlify Build                                                 
9:53:11 AM: ────────────────────────────────────────────────────────────────
9:53:11 AM: ​
9:53:11 AM: ❯ Version
9:53:11 AM:   @netlify/build 29.11.5
9:53:11 AM: ​
9:53:11 AM: ❯ Flags
9:53:11 AM:   baseRelDir: true
9:53:11 AM:   buildId: 6469cdd30371f6000895777b
9:53:11 AM:   deployId: 6469cdd30371f6000895777d
9:53:11 AM: ​
9:53:11 AM: ❯ Current directory
9:53:11 AM:   /opt/build/repo
9:53:11 AM: ​
9:53:11 AM: ❯ Config file
9:53:11 AM:   No config file was defined: using default values.
9:53:11 AM: ​
9:53:11 AM: ❯ Context
9:53:11 AM:   production
9:53:12 AM: ​
9:53:12 AM: ❯ Using Next.js Runtime - v4.37.1
9:53:13 AM: ​
9:53:13 AM: @netlify/plugin-nextjs (onPreBuild event)                     
9:53:13 AM: ────────────────────────────────────────────────────────────────
9:53:13 AM: ​
9:53:13 AM: Next.js cache restored.
9:53:13 AM: Netlify configuration property "build.environment.NEXT_PRIVATE_TARGET" value changed.
9:53:13 AM: ​
9:53:13 AM: (@netlify/plugin-nextjs onPreBuild completed in 42ms)
9:53:13 AM: ​
9:53:13 AM: Build command from Netlify app                                
9:53:13 AM: ────────────────────────────────────────────────────────────────
9:53:13 AM: ​
9:53:13 AM: $ npm run build
9:53:13 AM: > netlify-rewrite-bugs@0.1.0 build
9:53:13 AM: > next build
9:53:13 AM: info  - Linting and checking validity of types...
9:53:14 AM: info  - Creating an optimized production build...
9:53:17 AM: info  - Compiled successfully
9:53:17 AM: info  - Collecting page data...
9:53:25 AM: info  - Generating static pages (0/3)
9:53:25 AM: info  - Generating static pages (3/3)
9:53:26 AM: info  - Finalizing page optimization...
9:53:26 AM: Route (pages)                              Size     First Load JS
9:53:26 AM: ┌ ○ /                                      4.49 kB        81.9 kB
9:53:26 AM: ├   └ css/32586a8b0a8a958d.css             1.73 kB
9:53:26 AM: ├   /_app                                  0 B            77.4 kB
9:53:26 AM: ├ ● /[...pages]                            360 B          77.7 kB
9:53:26 AM: ├ ○ /404                                   182 B          77.5 kB
9:53:26 AM: └ λ /dynamic-pages/[...pages]              377 B          77.7 kB
9:53:26 AM: + First Load JS shared by all              78.1 kB
9:53:26 AM:   ├ chunks/framework-2c79e2a64abdb08b.js   45.2 kB
9:53:26 AM:   ├ chunks/main-3ce5c97599c7ed01.js        31.1 kB
9:53:26 AM:   ├ chunks/pages/_app-7172e87d084d5d88.js  298 B
9:53:26 AM:   ├ chunks/webpack-8fa1640cc84ba8fe.js     750 B
9:53:26 AM:   └ css/876d048b5dab7c28.css               706 B
9:53:26 AM: λ  (Server)  server-side renders at runtime (uses getInitialProps or getServerSideProps)
9:53:26 AM: ○  (Static)  automatically rendered as static HTML (uses no initial props)
9:53:26 AM: ●  (SSG)     automatically generated as static HTML + JSON (uses getStaticProps)
9:53:26 AM: ​
9:53:26 AM: (build.command completed in 12.8s)
9:53:26 AM: ​
9:53:26 AM: @netlify/plugin-nextjs (onBuild event)                        
9:53:26 AM: ────────────────────────────────────────────────────────────────
9:53:26 AM: ​
9:53:26 AM: Patching /opt/build/repo/node_modules/next/dist/server/base-server.js
9:53:26 AM: Done
9:53:26 AM: Patching /opt/build/repo/node_modules/next/dist/server/next-server.js
9:53:26 AM: Done
9:53:26 AM: Moving static page files to serve from CDN...
9:53:26 AM: Moved 1 files
9:53:26 AM: You are not using Netlify Edge Functions for image format detection. Set env var "NEXT_FORCE_EDGE_IMAGES=true" to enable.
9:53:26 AM: Netlify configuration property "redirects" value changed to [
9:53:26 AM:   { from: '/_next/static/*', to: '/static/:splat', status: 200 },
9:53:26 AM:   {
9:53:26 AM:     from: '/_next/image*',
9:53:26 AM:     query: { url: ':url', w: ':width', q: ':quality' },
9:53:26 AM:     to: '/_ipx/w_:width,q_:quality/:url',
9:53:26 AM:     status: 301
9:53:26 AM:   },
9:53:26 AM:   { from: '/_ipx/*', to: '/.netlify/builders/_ipx', status: 200 },
9:53:26 AM:   { from: '/cache/*', to: '/404.html', status: 404, force: true },
9:53:26 AM:   { from: '/server/*', to: '/404.html', status: 404, force: true },
9:53:26 AM:   { from: '/serverless/*', to: '/404.html', status: 404, force: true },
9:53:26 AM:   { from: '/trace', to: '/404.html', status: 404, force: true },
9:53:26 AM:   { from: '/traces', to: '/404.html', status: 404, force: true },
9:53:26 AM:   {
9:53:26 AM:     from: '/routes-manifest.json',
9:53:26 AM:     to: '/404.html',
9:53:26 AM:     status: 404,
9:53:26 AM:     force: true
9:53:26 AM:   },
9:53:26 AM:   {
9:53:26 AM:     from: '/build-manifest.json',
9:53:26 AM:     to: '/404.html',
9:53:26 AM:     status: 404,
9:53:26 AM:     force: true
9:53:26 AM:   },
9:53:26 AM:   {
9:53:26 AM:     from: '/prerender-manifest.json',
9:53:26 AM:     to: '/404.html',
9:53:26 AM:     status: 404,
9:53:26 AM:     force: true
9:53:26 AM:   },
9:53:26 AM:   {
9:53:26 AM:     from: '/react-loadable-manifest.json',
9:53:26 AM:     to: '/404.html',
9:53:26 AM:     status: 404,
9:53:26 AM:     force: true
9:53:26 AM:   },
9:53:26 AM:   { from: '/BUILD_ID', to: '/404.html', status: 404, force: true },
9:53:26 AM:   {
9:53:26 AM:     from: '/api/*',
9:53:26 AM:     to: '/.netlify/functions/___netlify-handler',
9:53:26 AM:     status: 200
9:53:26 AM:   },
9:53:26 AM:   {
9:53:26 AM:     from: '/favicon.ico',
9:53:26 AM:     to: '/favicon.ico',
9:53:26 AM:     conditions: { Cookie: [Array] },
9:53:26 AM:     status: 200
9:53:26 AM:   },
9:53:26 AM:   {
9:53:26 AM:     from: '/next.svg',
9:53:26 AM:     to: '/next.svg',
9:53:26 AM:     conditions: { Cookie: [Array] },
9:53:26 AM:     status: 200
9:53:26 AM:   },
9:53:26 AM:   {
9:53:26 AM:     from: '/vercel.svg',
9:53:26 AM:     to: '/vercel.svg',
9:53:26 AM:     conditions: { Cookie: [Array] },
9:53:26 AM:     status: 200
9:53:26 AM:   },
9:53:26 AM:   {
9:53:26 AM:     from: '/*',
9:53:26 AM:     to: '/.netlify/functions/___netlify-handler',
9:53:26 AM:     status: 200,
9:53:26 AM:     conditions: { Cookie: [Array] },
9:53:26 AM:     force: true
9:53:26 AM:   },
9:53:26 AM:   {
9:53:26 AM:     from: '/_next/data/kk6KjCNMlS4JKyHLrbb4n/index.json',
9:53:26 AM:     to: '/.netlify/functions/___netlify-handler',
9:53:26 AM:     status: 200,
9:53:26 AM:     force: false
9:53:26 AM:   },
9:53:26 AM:   {
9:53:26 AM:     from: '/',
9:53:26 AM:     to: '/.netlify/functions/___netlify-handler',
9:53:26 AM:     status: 200,
9:53:26 AM:     force: false
9:53:26 AM:   },
9:53:26 AM:   {
9:53:26 AM:     from: '/_next/data/kk6KjCNMlS4JKyHLrbb4n/dynamic-pages/:pages/*',
9:53:26 AM:     to: '/.netlify/functions/___netlify-handler',
9:53:26 AM:     status: 200,
9:53:26 AM:     force: false
9:53:26 AM:   },
9:53:26 AM:   {
9:53:26 AM:     from: '/dynamic-pages/:pages/*',
9:53:26 AM:     to: '/.netlify/functions/___netlify-handler',
9:53:26 AM:     status: 200,
9:53:26 AM:     force: false
9:53:26 AM:   },
9:53:26 AM:   {
9:53:26 AM:     from: '/_next/data/kk6KjCNMlS4JKyHLrbb4n/:pages/*',
9:53:26 AM:     to: '/.netlify/builders/___netlify-odb-handler',
9:53:26 AM:     status: 200,
9:53:26 AM:     force: false
9:53:26 AM:   },
9:53:26 AM:   {
9:53:26 AM:     from: '/:pages/*',
9:53:26 AM:     to: '/.netlify/builders/___netlify-odb-handler',
9:53:26 AM:     status: 200,
9:53:26 AM:     force: false
9:53:26 AM:   },
9:53:26 AM:   {
9:53:26 AM:     from: '/*',
9:53:26 AM:     to: '/.netlify/functions/___netlify-handler',
9:53:26 AM:     status: 200
9:53:26 AM:   }
9:53:26 AM: ].
9:53:26 AM: ​
9:53:26 AM: (@netlify/plugin-nextjs onBuild completed in 66ms)
9:53:26 AM: ​
9:53:26 AM: Functions bundling                                            
9:53:26 AM: ────────────────────────────────────────────────────────────────
9:53:26 AM: ​
9:53:26 AM: Packaging Functions from .netlify/functions-internal directory:
9:53:26 AM:  - ___netlify-handler/___netlify-handler.js
9:53:26 AM:  - ___netlify-odb-handler/___netlify-odb-handler.js
9:53:26 AM:  - _ipx/_ipx.js
9:53:26 AM: ​
9:53:46 AM: ​
9:53:46 AM: (Functions bundling completed in 19.8s)
9:53:46 AM: ​
9:53:46 AM: Edge Functions bundling                                       
9:53:46 AM: ────────────────────────────────────────────────────────────────
9:53:46 AM: ​
9:53:46 AM: ​
9:53:46 AM: (Edge Functions bundling completed in 319ms)
9:53:46 AM: ​
9:53:46 AM: @netlify/plugin-nextjs (onPostBuild event)                    
9:53:46 AM: ────────────────────────────────────────────────────────────────
9:53:46 AM: ​
9:53:46 AM: Next.js cache saved.
9:53:46 AM: ​
9:53:46 AM: (@netlify/plugin-nextjs onPostBuild completed in 33ms)
9:53:46 AM: ​
9:53:46 AM: Deploy site                                                   
9:53:46 AM: ────────────────────────────────────────────────────────────────
9:53:46 AM: ​
9:53:46 AM: Starting to deploy site from '.next'
9:53:46 AM: Calculating files to upload
9:53:46 AM: 17 new files to upload
9:53:46 AM: 3 new functions to upload
9:53:54 AM: Section completed: deploying
9:53:54 AM: Site deploy was successfully initiated
9:53:54 AM: ​
9:53:54 AM: Starting post processing
9:53:54 AM: (Deploy site completed in 8s)
9:53:54 AM: ​
9:53:54 AM: Netlify Build Complete                                        
9:53:54 AM: ────────────────────────────────────────────────────────────────
9:53:54 AM: ​
9:53:54 AM: Skipping HTML post processing
9:53:54 AM: (Netlify Build completed in 42.6s)
9:53:54 AM: Post processing - header rules
9:53:54 AM: Post processing - redirect rules
9:53:55 AM: Caching artifacts
9:53:55 AM: Started saving node modules
9:53:55 AM: Finished saving node modules
9:53:55 AM: Post processing done
9:53:55 AM: Started saving build plugins
9:53:55 AM: Finished saving build plugins
9:53:55 AM: Section completed: postprocessing
9:53:55 AM: Started saving corepack cache
9:53:55 AM: Finished saving corepack cache
9:53:55 AM: Started saving pip cache
9:53:55 AM: Finished saving pip cache
9:53:55 AM: Started saving emacs cask dependencies
9:53:55 AM: Finished saving emacs cask dependencies
9:53:55 AM: Started saving maven dependencies
9:53:55 AM: Finished saving maven dependencies
9:53:55 AM: Started saving boot dependencies
9:53:55 AM: Finished saving boot dependencies
9:53:55 AM: Started saving rust rustup cache
9:53:55 AM: Finished saving rust rustup cache
9:53:55 AM: Started saving go dependencies
9:53:55 AM: Finished saving go dependencies
9:53:55 AM: Build script success
9:53:55 AM: Section completed: building
9:53:56 AM: Uploading Cache of size 165.0MB
9:53:56 AM: Site is live ✨
9:53:57 AM: Section completed: cleanup
9:53:57 AM: Finished processing build request in 1m0.611s

Function logs

ISR Function logs

(/render/ssr incorrectly gets logged in ISR while it should be rendered using SSR and appear in those logs)

May 21, 09:54:17 AM: ded95a07 INFO   [GET] /any/url (ODB)
May 21, 09:54:18 AM: ded95a07 Duration: 441.68 ms	Memory Usage: 116 MB	Init Duration: 525.37 ms
May 21, 09:54:25 AM: 9b6ccc91 INFO   [GET] /render/ssr (ODB)
May 21, 09:54:25 AM: 9b6ccc91 Duration: 42.10 ms	Memory Usage: 116 MB

.next JSON files

No response

@terrabythia terrabythia added the type: bug code to address defects in shipped code label May 21, 2023
@terrabythia terrabythia changed the title [Bug]: ISR incombination with nextjs rewrites not working [Bug]: ISR in combination with nextjs rewrites not working May 21, 2023
@terrabythia
Copy link
Author

After looking through the other issues I think this is the same issue as this one: #1821

However, I've added a lot of details and steps to reproduce so I think that justifies the "duplicate" issue.

@pieh
Copy link
Contributor

pieh commented Jun 2, 2023

Unfortunately currently it's not straight forward to handle this out of the box. Part of the problem is rewrite/redirect "stacking" which is currently not supported. We can't create rewrite/redirect the way you define it in next config, instead we would need to know wether target would be SSR or ISR and route to appropriate handler. Creating generic solution for this is not that feasible without rewrite/redirect stacking so instead we are working on stacking support which will allow to support this much easier.

The reason query params are stripped (at least in provided repro) is that it is being routed to ISR handler which does strip query params.

You can workaround this manually for now by adding following redirects to netlify.toml (for the provided reproduction):

[[redirects]]
  from = "/render/ssr"
  to = "/.netlify/functions/___netlify-handler"
  status = 200

[[redirects]]
  from = "/render/ssg"
  to = "/.netlify/functions/___netlify-odb-handler"
  status = 200

(/.netlify/functions/___netlify-handler is SSR handler, /.netlify/functions/___netlify-odb-handler is ISR handler - those function handle pathnames are fairly stable, but they are considered internals, not public so they might change)

@terrabythia
Copy link
Author

Thanks for your response.

I don't get your following remark though:

The reason query params are stripped (at least in provided repro) is that it is being routed to ISR handler which does strip query params.

It shouldn't be routed to ISR though right? Because I'm routing it to a SSR page with a rewrite. Or is that because of the limitation of Netlify not having stacking support right now?

Your workaround for now does seem to work, thanks!

@MarcL
Copy link
Contributor

MarcL commented Jul 10, 2023

I am closing this as the workaround has fixed the issue. We are looking at some changes to support rewrites like this soon. 👍

@MarcL MarcL closed this as completed Jul 10, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

4 participants