next.js
next.js copied to clipboard
Presence of i18n config breaks multi-tenant's index page (404 Not Found)
Verify canary release
- [X] I verified that the issue exists in the latest Next.js canary release
Provide environment information
Operating System: Platform: darwin Arch: x64 Version: Darwin Kernel Version 21.4.0: Mon Feb 21 20:35:58 PST 2022; root:xnu-8020.101.4~2/RELEASE_ARM64_T6000 Binaries: Node: 14.18.3 npm: 8.5.1 Yarn: 1.22.18 pnpm: N/A Relevant packages: next: 13.0.3-canary.4 eslint-config-next: N/A react: 18.2.0 react-dom: 18.2.0
What browser are you using? (if relevant)
No response
How are you deploying your application? (if relevant)
No response
Describe the Bug
If there is i18n
config present in next.config.js
, then index (home) page unexpectedly ends with error 404 (Not Found). All other pages work just fine. Only index page is broken.
I've previously open an issue in the next-i18next
repository, however I was redirected here as it appears to be an error on the part of Next.js itself. To see the existing discussion, here is my original issue: https://github.com/i18next/next-i18next/issues/2019
Expected Behavior
The index
page should load just fine even with i18n
config present in next.config.js
.
Link to reproduction - Issues with a link to complete (but minimal) reproduction code will be addressed faster
https://github.com/patrik-simunic-cz/bug-nextjs-multitenant-i18n
To Reproduce
- Clone the repo
- Run
yarn dev
- Open the index page
http://localhost:3000
and you'll get 404 - Open different page
http://localhost:3000/works
and it will load totally fine (even with correct translations)
If you remove the i18n
config from next.config.js
file, then translations are broken (obviously), however you'll no longer get 404 on the index
page.
To add 1 more perplexing fact (as with regard to the minimal reproducible example):
I've added console.log to the middleware to see when it's invoked (and with what url). If I open some page (/works
) it works including different locales (/en/works
, /cs/works
) and the middleware is invoked. But when I open the index page and get 404, the middleware is not even invoked - it ends on 404 even before calling the middleware.
https://yourdomain/-> falls to 404 page if you access https://yourdomain/index -> works fine
@nir099 No, it doesn't... I've tried it and when you clone my bug reproduction, you can see that localhost:3000
falls to 404 and so does localhost:3000/index
. Even if it indeed would work, that still doesn't solve anything. Index page has to be accessible without explicitly specifying /index
in the path - but as the demo demonstrate, it doesn't even work with explicitly specifying /index
(although if you do specify /index
, the request at least reaches the middleware - but still ends in 404)
Alright, I'm one step closer, but still with no solution in sight. The 404 is gone if I create an index
page at the utmost top-level of pages (pages/index
) and it resolves to this page. But this is useless - it's a multi-tenant app, the index
page it should resolve to pages/web/[tenant]/index
, not pages/index
. For some reason, the presence of i18n
config in next.config.js
forces Next.js to bypass the middleware which rewrites everything to tenant-specific path:
import { NextRequest, NextResponse } from 'next/server'
const rootHost = 'localhost:3000'
export const config = {
matcher: [ '/((?!api|_next|locales|fonts|[\\w-]+\\.\\w+).*)' ],
}
export default (request: NextRequest) => {
const url = request.nextUrl
const hostname = request.headers.get('host') || rootHost
url.pathname = `/web/${hostname}${url.pathname}`
return NextResponse.rewrite(url)
}
Alright, issue solved. The problem is that the official matcher for multi-tenant application is absolutely incompatible with the very presence of i18n
config in next.config.js
file. You need to either fix this matcher:
export const config = {
matcher: [ '/((?!api|_next|fonts|examples|[\\w-]+\\.\\w+).*)' ],
}
or remove it and solve it programmatically within the middleware itself.
I'm leaving this issue open until someone from Vercel deigns to at least look at this issue and maybe consider at least adding a warning the the official Vercel guide for multi-tenant apps? And/or updating the official starter kit for multi-tenant apps?
This was just a colossal waste of time. A note that presence of i18n
changes the matcher behaviour would be nice....
I have the same problem. Someone from the Vercel team to help?
Hey @patrik-simunic-cz, very much appreciate your deep dive here and apologies for the bad experience. Agreed it could be more clear that using i18n routing configuration options might have conflicts with Middleware. We will update our guide/code to make sure of that note. Further, going forward in the app
directory future, we recommend using Middleware for i18n routing. You can view the new docs here: https://beta.nextjs.org/docs/guides/internationalization
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.