Next.js Discord

Discord Forum

Dynamic page slugs return incorrect parameters in production on Vercel #66520

Unanswered
Transvaal lion posted this in #help-forum
Open in Discord
Transvaal lionOP
After deploying my project to Vercel, I'm encountering an issue where dynamic page slugs, following the pattern app/[site]/[locale]/layout.tsx, are not behaving as expected. Instead of returning the rewritten parameters, they return [site] and [locale]. This problem only manifests in the production environment on Vercel; it does not occur in either local development or local production builds, which function correctly, therefore it's really hard to reproduce or make an Codesandbox op something similar.

We have middleware rewriting the incoming url the the param structure. So /tickets will be rewritten to /sitename/nl/tickets, as you can see in the attached image this is happening correctly (as said locally everything works fine in dev/prod, only on Vercel it breaks). The middl4ware code rewriting the url:

const newPath = `/${host}${
  
url.pathname.includes(locale) ? url.pathname : `/${locale}${url.pathname}`
}`;

url.pathname = newPath;
url.href = `${url.origin}${newPath}`;

const response = NextResponse.rewrite(url);


What makes it more strange is on Vercel these scenarios are being played out:

- app/[site]/[locale]/layout.tsx -> [site] and [locale] not rewritten, therefore we error to 500
- app/[site]/[locale]/[...slug]/page.tsx -> [site] and [locale] ARE rewritten, no issue
- app/[site]/[locale]/tickets/page.tsx -> [site] and [locale] not rewritten, therefore we error to 500
- app/[site]/[locale]/tickets/layout.tsx -> [site] and [locale] not rewritten, therefore we error to 500
- app/[site]/[locale]/tickets/[...slug]/page.tsx -> [site] and [locale] ARE rewritten, no issue

We also use pages and app directory alongside each other because we are slowly migrating the project over to app directory. We spend multiple days debugging and trying to fix the issue without any success. Hopefully anyone can point us towards why it doesn't work on specifically Vercel deployment or how we might be able to reproduce it local.

15 Replies

Swainson's Thrush
I'm not able to understand the problem. Can you be more precise and share what you are trying to achieve and where you are getting the error in the middleware file?
Transvaal lionOP
What part do you not understand if I may ask? I'm not sure how I can eleborate besides again explaining that I'm trying to rewrite urls so we receive specific params in the folder structure app/[site]/[locale]/layout.tsx .

So an incoming request for /tickets is rewritten to /[site]/[locale]/tickets using middleware. This is because we are using a monorepository serving multiple sites from one codebase.

The rewriting of the url with the correct params is happening correctly on localhost in both development and production builds, but is breaking after deploying to Vercel. After deployment app/[site]/[locale]/layout.tsx doesn't receive the params: {site, locale} as e.g. site = 'sitename' and locale = 'nl' but rather site = [site] and locale = [locale]. So the params are not being rewritten.

This is only happening on Vercel for the files/routes:
- app/[site]/[locale]/layout.tsx
- app/[site]/[locale]/tickets/page.tsx
- app/[site]/[locale]/tickets/layout.tsx

On the following routes we have no issue on Vercel and the params are being rewritten as expected:
- app/[site]/[locale]/[...slug]/page.tsx
- app/[site]/[locale]/tickets/[...slug]/page.tsx
Swainson's Thrush
I think app/[site]/[locale]/[...slug]/page.tsx is overiding your app/[site]/[locale]/tickets/page.tsx.
try app/unique/[site]/[locale]/tickets/page.tsx
Transvaal lionOP
Those are two different scenario's we tried to see where to bug exists. This is the structure we are running. Prefixing the whole site with a unique slug in the strucutre is not possible unfortunately
Swainson's Thrush
oh ok I get it now
try updating the nextJs version to the latest.
also can I look at your middleware file
const url = new URL("/auth/login", nextUrl);
url.searchParams.set("callbackUrl", nextUrl.pathname);
return Response.redirect(url);


This is how I'm managing callback redirections.
It works locally and on the server as well.
but I've deployed it on AWS Amplify.
Transvaal lionOP
NextJS is on the latest version already.

This is the middleware rewriting the urls. Note that only /tickets is now running in app router. The rest of the website is running on pages directory. We are planning to migrate everything in the near future.

export function withRedirectTicketshopToAppRouter(middleware: NextMiddleware) {
  return async (request: NextRequest, event: NextFetchEvent) => {
    const host = request.headers.get("host");

    const url = request.nextUrl.clone();
    if (!url.pathname.includes("tickets")) {
      return middleware(request, event);
    }

    let locale = fallbackLng;

    // if url includes any language
    if (url.href.includes("/en")) {
      locale = "en";
    } else if (url.href.includes("/nl")) {
      locale = "nl";
    }

    if (!locale && request.headers.get("locale")) {
      locale = request.headers.get("locale") as string;
    }

    const newPath = `/${host}${
      url.pathname.includes(locale) ? url.pathname : `/${locale}${url.pathname}`
    }`;

    url.pathname = newPath;
    url.href = `${url.origin}${newPath}`;

    // eslint-disable-next-line no-console
    console.log("redirect tickets middleware: ", {
      href: url.href,
      pathname: url.pathname,
      host: request.headers.get("host"),
    });

    const response = NextResponse.rewrite(url);
    return response;
  };
}
Swainson's Thrush
Hey, Is this still an issue?
If you want we can connect in a meeting and solve this together
but I'll only be available on sat & sun