Middleware `NextResponse.rewrite` 404ing when rewriting "/" with another route when deployed to Vercel
See original GitHub issueRun next info
(available from version 12.0.8 and up)
Operating System:
Platform: linux
Arch: x64
Version: #1 SMP Mon Oct 18 19:27:44 UTC 2021
Binaries:
Node: 14.18.0
npm: 6.14.15
Yarn: 1.22.17
pnpm: 6.24.4
Relevant packages:
next: 12.0.8-canary.18
react: 17.0.2
react-dom: 17.0.2
What version of Next.js are you using?
12.0.8-canary.18
What version of Node.js are you using?
14.18.0
What browser are you using?
Firefox
What operating system are you using?
Windows
How are you deploying your application?
Vercel
Describe the Bug
Using middleware, NextResponse.rewrite is not correctly rewriting a route with another existing route. Doing so results in a 404.
I am using i18n, but https://github.com/vercel/next.js/pull/31174 does not fix it.
Seems related to https://github.com/vercel/next.js/issues/30749
Here is my middleware file:
import { NextRequest, NextResponse } from "next/server";
import { CONSTANTS } from "src/utils/constants";
const ONE_YEAR_IN_MS = 3600 * 365 * 24 * 1000;
export function middleware(req: NextRequest) {
const expires = new Date(Date.now() + ONE_YEAR_IN_MS);
const initialVariant = req.cookies[CONSTANTS.RH_HOME_PAGE_TEST_COOKIE];
// Redirect direct traffic to our test variant
if (
(!initialVariant ||
initialVariant !== CONSTANTS.RH_HOME_PAGE_VARIANT_1_SLUG) &&
req.nextUrl.pathname === `/${CONSTANTS.RH_HOME_PAGE_VARIANT_1_SLUG}`
) {
return NextResponse.redirect(CONSTANTS.HOME_ROUTE);
}
// Home page AB testing
if (req.nextUrl.pathname === CONSTANTS.HOME_ROUTE) {
let variant = initialVariant;
// Determine the variant via a random split
if (!variant) {
const split: boolean = Math.random() >= 0.5;
variant = split
? CONSTANTS.RH_HOME_PAGE_VARIANT_1_SLUG
: CONSTANTS.RH_HOME_PAGE_ORIGINAL;
}
const res =
variant === CONSTANTS.RH_HOME_PAGE_ORIGINAL
? NextResponse.next()
: NextResponse.redirect(`/${variant}`, 307); // Temporary redirect
if (initialVariant !== variant) {
res.cookie(CONSTANTS.RH_HOME_PAGE_TEST_COOKIE, variant, { expires });
}
return res;
} else {
return NextResponse.next();
}
}
My next.config:
module.exports = {
productionBrowserSourceMaps: true,
outputFileTracing: false,
images: {
domains: [
"images.ctfassets.net",
"assets.ctfassets.net",
"videos.ctfassets.net",
"assets.zappyride.com",
],
},
i18n: {
locales: ["en", "es"],
defaultLocale: "en",
},
env: {},
webpack: (config, options) => {
if (!options.isServer) {
config.resolve.alias["@sentry/node"] = "@sentry/react";
}
// Only add sentry webpack plugin when sentry DSN is defined and the
// app is being deployed (NODE_ENV=production when making an optimized build
// for a deployed environment).
if (
process.env.NEXT_PUBLIC_SENTRY_DSN &&
process.env.NODE_ENV === "production"
) {
config.plugins.push(
new SentryWebpackPlugin({
include: ".next",
ignore: ["node_modules"],
urlPrefix: "~/_next",
release: process.env.VERCEL_GITHUB_COMMIT_SHA,
})
);
}
config.resolve.alias = {
...config.resolve.alias,
"@mui/styled-engine": "@mui/styled-engine-sc",
};
return config;
},
async redirects() {
if (process.env.ENVIRONMENT === "production") {
return [...productionRedirects, ...sharedRedirects];
} else {
return [...sharedRedirects];
}
},
async headers() {
return [
{
source: "/",
headers: [
{
key: "Cache-Control",
value: "s-maxage=1, stale-while-revalidate",
},
...securityHeaders,
],
},
{
source: "/:path*",
headers: [
{
key: "Cache-Control",
value: "s-maxage=1, stale-while-revalidate",
},
...securityHeaders,
],
},
{
source: "/fonts/Averta/(.*)",
headers: [
{
key: "Cache-Control",
value: "public, max-age=31536000, stale-while-revalidate",
},
...securityHeaders,
],
},
{
source: "/fonts/fontface.css",
headers: [
{
key: "Cache-Control",
value: "public, max-age=31536000, stale-while-revalidate",
},
...securityHeaders,
],
},
];
},
};
Expected Behavior
The rewrite should happen as it does locally on Vercel and not 404.
Issue Analytics
- State:
- Created 2 years ago
- Reactions:3
- Comments:21 (5 by maintainers)
Top Results From Across the Web
next.js - Vercel Edge Functions works locally and give 404 on ...
I'm trying to work with the new edge functions from Vercel next.js and it's not working on production, always gives a 404 error....
Read more >Rewrites - next.config.js
Rewrites allow you to map an incoming request path to a different destination path. Rewrites act as a URL proxy and mask the...
Read more >The What, When, Why And How Of Next.js' New Middleware ...
To achieve this you can conditionally return a 404 or rewrite the request to a “blocked” page. Vercel has an example of blocking...
Read more >Modifying Request Headers in Middleware - Vercel
Learn to add/update/delete request headers in a middleware. ... You can also set request headers in NextResponse.rewrite return NextResponse.next({ request: ...
Read more >Vercel | Miguel Minoldo
Then we've to create the middleware.ts file in the root of src. The code here is quite simple, we get the site name...
Read more >Top Related Medium Post
No results found
Top Related StackOverflow Question
No results found
Troubleshoot Live Code
Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start FreeTop Related Reddit Thread
No results found
Top Related Hackernoon Post
No results found
Top Related Tweet
No results found
Top Related Dev.to Post
No results found
Top Related Hashnode Post
No results found
Top GitHub Comments
Yes works locally, not deployed.
Stack is latest Next, i18n configured with two locales, Contentful CMS. Redirect works like a charm, rewrite causes 404.
@balazsorban44 seems similar. Here is my updated middleware:
Essentially, I am trying to perform an AB test using the original home route (“/”) and a variant (“/variant-home-refresh”). I am able to see the variant if I navigate to the route directly, however any time the original route is rewritten, the home page 404s and any links to “/” do not work throughout the site (logo, etc.).
I definitely think this could be related to i18n.