Next.js: Rewrite adds query param when re-appending a matched path param to the destination

Created on 29 Jul 2020  路  6Comments  路  Source: vercel/next.js

Bug report

Describe the bug

A rewrite from /source/:route* to http://my-api-server.example.org/destination/:route* forwards a request sent to /source/foo to http://my-api-server.example.org/destination/foo?route=foo. The extra query param will lead to issues especially with API servers as in REST this might represent a filter criteria.

To Reproduce

  1. Create a new next app

  2. Create a custom next.config.js:

module.exports = {
  async rewrites() {
    return [
      {
        source: "/api/:route*",
        destination: "https://postman-echo.com/:route*",
      },
    ];
  },
};

  1. Start next: yarn next dev

  2. Open up http://localhost:3000/api/get

  3. The results includes "url":"https://postman-echo.com/get?route=get"

Expected behavior

Params that are added to the destination path should not be included as a query param.

  1. The results includes "url":"https://postman-echo.com/get"

Screenshots

n/a

System information

  • Version of Next.js: 9.5.0
  • Version of Node.js: n/a

Additional context

n/a

bug 2 p0

Most helpful comment

Hi, this is the behavior currently since when rewriting the end-user doesn't see the query values so we make all params available in the query automatically.

After discussion it looks like it would make sense to not add the params to the query automatically for rewrites if it is already used in the destination so we will be investigating this behavior

All 6 comments

I'm seeing similar behavior, although in my case it's path, rather than route. Comparing your implementation & mine, the param appears to be chosen based on the config param name:

source: "/api/:route*",
destination: "https://postman-echo.com/:route*",

Because you're using :route* here, and we're using :path (which we copied straight from the docs), that's what gets appended as a query string. If it helps, a workaround could be to change that param name to something obvious to ignore and either ignoring it completely at the server side or just choosing something that won't conflict.

Hi, this is the behavior currently since when rewriting the end-user doesn't see the query values so we make all params available in the query automatically.

After discussion it looks like it would make sense to not add the params to the query automatically for rewrites if it is already used in the destination so we will be investigating this behavior

Stumbled upon the same issue and it bugged me for the last two days. Later in my local next build when appendParamsToQuery in rewrites was set to false resolved the issue.

https://github.com/vercel/next.js/blob/dcb69ee92f9d8bac28f7c53d7ded30919931cf3d/packages/next/next-server/server/next-server.ts#L588

But there seems to be another weird behavior. If the request URL has a trailing slash it's being ignored while proxying.
My next.config.js

{
    async rewrites() {
      return [
        {
          source: "/api/:path*",
          destination: "https://myservice.com/api/:path*",
        },
      ];
    }
  }

Request URL : http://localhost:3000/api/xyz/
Proxied URL : https://myservice.com/api/xyz (In my server logs)

And when I set trailingSlash to true in my next.config.js My request URL gets 308 to the same URL with trailing slash (Expected) but the page return 404.

Isn't this unusual @ijjk ?

Hi, this has been updated in the latest canary of Next.js (v9.5.3-canary.3), please upgrade and give it a try!

@pratheekhegde the issue you mentioned with the trailing slash and rewrites can be tracked in this issue https://github.com/vercel/next.js/issues/15700

Thank you @ijjk , I shall track it there.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

rauchg picture rauchg  路  208Comments

poyiding picture poyiding  路  73Comments

timneutkens picture timneutkens  路  72Comments

Timer picture Timer  路  60Comments

tomaswitek picture tomaswitek  路  73Comments