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

Nextjs 12 not firing _middleware.ts file when NextResponse.rewrite() #36879

Closed
1 task done
drafenous opened this issue May 13, 2022 · 3 comments
Closed
1 task done

Nextjs 12 not firing _middleware.ts file when NextResponse.rewrite() #36879

drafenous opened this issue May 13, 2022 · 3 comments
Labels
bug Issue was opened via the bug report template. Middleware Related to Next.js Middleware.

Comments

@drafenous
Copy link

Verify canary release

  • I verified that the issue exists in Next.js canary release

Provide environment information

Operating System:
  Platform: linux
  Arch: x64
  Version: #1 SMP Wed Mar 2 00:30:59 UTC 2022
Binaries:
  Node: 16.14.0
  npm: 8.5.1
  Yarn: 1.22.18
  pnpm: N/A
Relevant packages:
  next: 12.1.7-canary.5
  react: 17.0.2
  react-dom: 17.0.2

What browser are you using? (if relevant)

Chrome 101.0.4951.54

How are you deploying your application? (if relevant)

in futher i will use Vercel

Describe the Bug

I'm creating a multi-tenant app, and when I create a main middleware to redirect the host to _sites/[site] path, the _middleware.ts file inside _sites/[site] is not firing.

Making some tests, the problem is when I use a rewirte method.

Here's my code:

file: pages/_middleware.ts

import { NextRequest, NextResponse } from 'next/server'

export default function middleware(req: NextRequest) {
  const url = req.nextUrl.clone() // clone the request url

  const { pathname } = req.nextUrl
  // Get hostname (e.g. vercel.com, test.vercel.app, etc.)
  const hostname = req.headers.get('host')

  // If localhost, assign the host value manually
  // If prod, get the custom domain/subdomain value by removing the root URL
  // (in the case of "test.vercel.app", "vercel.app" is the root URL)
  const currentHost =
    process.env.NODE_ENV == 'production'
      ? hostname?.replace(`.telecodeapp.com`, '').replace(`.telecode.app`, '') // PUT YOUR DOMAIN HERE
      : hostname?.replace(`.localhost:3000`, '')

  // Prevent security issues – users should not be able to canonically access
  // the pages/sites folder and its respective contents. This can also be done
  // via rewrites to a custom 404 page
  if (pathname.startsWith(`/_sites`)) {
    return new Response(null, { status: 404 })
  }

  if (
    !pathname.includes('.') && // exclude all files in the public folder
    !pathname.startsWith('/api') // exclude all API routes
  ) {
    // rewrite to the current hostname under the pages/sites folder
    // the main logic component will happen in pages/sites/[site]/index.tsx
    url.pathname = `/_sites/${currentHost}${pathname}`
    return NextResponse.rewrite(url)
  }
}

file: /pages/_sites/[site]/_middleware.ts

import { NextFetchEvent, NextRequest, NextResponse } from 'next/server'

export async function middleware(req: NextRequest, ev: NextFetchEvent) {
  console.log('hi there!')
}

This second file is not firing.

Expected Behavior

Run middlewares inside _sites/[site] folder.

To Reproduce

Create these files:

file: pages/_middleware.ts

import { NextRequest, NextResponse } from 'next/server'

export default function middleware(req: NextRequest) {
  const url = req.nextUrl.clone() // clone the request url

  const { pathname } = req.nextUrl
  // Get hostname (e.g. vercel.com, test.vercel.app, etc.)
  const hostname = req.headers.get('host')

  // If localhost, assign the host value manually
  // If prod, get the custom domain/subdomain value by removing the root URL
  // (in the case of "test.vercel.app", "vercel.app" is the root URL)
  const currentHost =
    process.env.NODE_ENV == 'production'
      ? hostname?.replace(`.telecodeapp.com`, '').replace(`.telecode.app`, '') // PUT YOUR DOMAIN HERE
      : hostname?.replace(`.localhost:3000`, '')

  // Prevent security issues – users should not be able to canonically access
  // the pages/sites folder and its respective contents. This can also be done
  // via rewrites to a custom 404 page
  if (pathname.startsWith(`/_sites`)) {
    return new Response(null, { status: 404 })
  }

  if (
    !pathname.includes('.') && // exclude all files in the public folder
    !pathname.startsWith('/api') // exclude all API routes
  ) {
    // rewrite to the current hostname under the pages/sites folder
    // the main logic component will happen in pages/sites/[site]/index.tsx
    url.pathname = `/_sites/${currentHost}${pathname}`
    return NextResponse.rewrite(url)
  }
}

file: /pages/_sites/[site]/_middleware.ts

import { NextFetchEvent, NextRequest, NextResponse } from 'next/server'

export async function middleware(req: NextRequest, ev: NextFetchEvent) {
  console.log('hi there!')
}

And try to access any url inside /pages/_sites/[site] folder.

@drafenous drafenous added the bug Issue was opened via the bug report template. label May 13, 2022
@drafenous drafenous changed the title Nextjs 12 no firing _middleware.ts file when NextResponse.rewrite() Nextjs 12 not firing _middleware.ts file when NextResponse.rewrite() May 13, 2022
@icyJoseph
Copy link
Contributor

icyJoseph commented May 13, 2022

Yeah, this is a bit odd. There was an open discussion here, without much conversation going on really, #36325.

In my case, I ended up using redirects and rewrites. I had a sub section of pages that didn't need rewrites, so I redirect to them, to trigger the middleware, at the price of unmasking the URL and triggering a page load on the client.

However, for this example https://github.com/vercel/examples/tree/main/edge-functions/hostname-rewrites, it is silently implied at the moment that there cannot be middleware further down.

Though, one could argue that you could still apply them from the top based on the path, but still, not good.

Would be nice to hear from the team about this.

@balazsorban44 balazsorban44 added the Middleware Related to Next.js Middleware. label May 13, 2022
@balazsorban44
Copy link
Member

@icyJoseph is right, nesting Middlewares is being deprecated: #36772

We will upgrade our examples as well as the documentation, but as this behavior will change soon, I recommend making sure you upgrade your Middleware according to this: https://github.com/vercel/next.js/blob/56dc9e11848d1d32a9f6a9a3346aa51aef4a47da/errors/nested-middleware.md

@github-actions
Copy link
Contributor

This closed issue has been automatically locked because it had no new activity for a month. If you are running into a similar issue, please create a new issue with the steps to reproduce. Thank you.

@github-actions github-actions bot locked as resolved and limited conversation to collaborators Jun 12, 2022
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
bug Issue was opened via the bug report template. Middleware Related to Next.js Middleware.
Projects
None yet
Development

No branches or pull requests

3 participants