Help with Integrating next-intl in a Multi-Tenant Next.js App
Unanswered
Saltwater Crocodile posted this in #help-forum
Saltwater CrocodileOP
Hi everyone,
I’m currently working on a multi-tenant application in Next.js, and I’m having trouble integrating next-intl for internationalization (i18n). Here’s the structure of my app, along with the challenges I’m facing.
Project Context:
Multi-tenant app where tenants are identified by subdomains (e.g., tenant1.example.com, tenant2.example.com).
I need to implement internationalization (i18n) for different languages.
Using Next.js App Router with the following file structure:
app
└── [locale]
└── [domain]
└── page.js
I’m currently working on a multi-tenant application in Next.js, and I’m having trouble integrating next-intl for internationalization (i18n). Here’s the structure of my app, along with the challenges I’m facing.
Project Context:
Multi-tenant app where tenants are identified by subdomains (e.g., tenant1.example.com, tenant2.example.com).
I need to implement internationalization (i18n) for different languages.
Using Next.js App Router with the following file structure:
app
└── [locale]
└── [domain]
└── page.js
1 Reply
Saltwater CrocodileOP
import { NextResponse } from "next/server";
import subdomains from "./subdomains.json";
export const config = {
matcher: ["/((?!api/|_next/|_static/|_vercel|[\w-]+\.\w+).*)"],
};
export default async function middleware(req) {
const url = new URL(req.url);
const hostname = req.headers.get("host") || "";
// Define list of allowed domains
// (including localhost and your deployed domain)
const allowedDomains = [
"localhost:3000",
"localhost:3002",
"example.com"
];
// Check if the current hostname is in the list of allowed domains
const isAllowedDomain = allowedDomains.some((domain) =>
hostname.includes(domain)
);
// Extract the potential subdomain from the URL
const subdomain = hostname.split(".")[0];
// If user is on an allowed domain and it's not a subdomain, allow the request
if (isAllowedDomain && !subdomains.some((d) => d.subdomain === subdomain)) {
return NextResponse.next();
}
const subdomainData = subdomains.find((d) => d.subdomain === subdomain);
if (subdomainData) {
// Rewrite the URL to a dynamic path based on the subdomain
const response = NextResponse.rewrite(
new URL(
);
// Set a custom header to pass tenant information
response.cookies.set("tenant", subdomainData.subdomain, { path: "/" });
return response;
}
return new Response(null, { status: 404 });
}
import subdomains from "./subdomains.json";
export const config = {
matcher: ["/((?!api/|_next/|_static/|_vercel|[\w-]+\.\w+).*)"],
};
export default async function middleware(req) {
const url = new URL(req.url);
const hostname = req.headers.get("host") || "";
// Define list of allowed domains
// (including localhost and your deployed domain)
const allowedDomains = [
"localhost:3000",
"localhost:3002",
"example.com"
];
// Check if the current hostname is in the list of allowed domains
const isAllowedDomain = allowedDomains.some((domain) =>
hostname.includes(domain)
);
// Extract the potential subdomain from the URL
const subdomain = hostname.split(".")[0];
// If user is on an allowed domain and it's not a subdomain, allow the request
if (isAllowedDomain && !subdomains.some((d) => d.subdomain === subdomain)) {
return NextResponse.next();
}
const subdomainData = subdomains.find((d) => d.subdomain === subdomain);
if (subdomainData) {
// Rewrite the URL to a dynamic path based on the subdomain
const response = NextResponse.rewrite(
new URL(
/${subdomain}${url.pathname}
, req.url));
// Set a custom header to pass tenant information
response.cookies.set("tenant", subdomainData.subdomain, { path: "/" });
return response;
}
return new Response(null, { status: 404 });
}