Next.js Discord

Discord Forum

Middleware to call next-intl middleware after rewrite to apply the function to the accesed "domain"

Answered
MarkMiklos posted this in #help-forum
Open in Discord
Avatar
I have a middleware that basically does multi tenancy checks and if the domain is valid it runs a rewrite.

My only concern is that whenever the rewrite happens, then the intlMiddleware doesnt run, so the internationalization doesn't work on the different "domain".

What could be a possible solution?

Here is my middleware
import { NextResponse } from "next/server";
import createMiddleware from "next-intl/middleware";
import { localePrefix, locales } from "@/navigation";
import { cookies } from "next/headers";
import {getCompanyByDomain} from "@/actions/company";

const intlMiddleware = createMiddleware({
  defaultLocale: 'hu',
  localePrefix,
  locales
});

export default async function middleware(req: any) {

  const url = req.nextUrl;
  const pathname = url.pathname;

  const locale = cookies().get('NEXT_LOCALE')?.value

  // Get hostname (e.g., 'mike.com', 'test.mike.com')
  const hostname = req.headers.get("host");

  let currentHost;
  if (process.env.NODE_ENV === "production") {
    // Production logic remains the same
    const baseDomain = process.env.BASE_DOMAIN;
    currentHost = hostname?.replace(`.${baseDomain}`, "");
  } else {
    // Updated development logic
    currentHost = hostname?.split(":")[0].replace(".localhost", "");
  }
  console.log(currentHost)
  // If there's no currentHost, likely accessing the root domain, handle accordingly
  if (!currentHost) {
    // Continue to the next middleware or serve the root content
    return NextResponse.next();
  }

  const company = await getCompanyByDomain(currentHost);

  if (company?.data?.domain) {
    return NextResponse.rewrite(new URL(`/${locale}/${company?.data?.domain}`, req.url));
  }

  return intlMiddleware(req);
}

export const config = {
  matcher: ['/', '/((?!api|_next/static|_next/image|favicon.ico|sitemap.xml|robots.txt|.*\\.svg|.*\\.jpg|.*\\.png).*)'],
};
Answered by MarkMiklos
Okay i found the solution incase anyone was wondering, in the rewrite function after the url, you can define a middleware init.

return NextResponse.rewrite(new URL(`/${locale}/${company?.data?.domain}`, req.url), intlMiddleware(req));


So it does look like this now, and it works like a charm.
View full answer

5 Replies

Avatar
try to wrap the request into intl middleware in the beginning of middleware and return it at the end it seems the conditional logic above the default return affects the final result.
This way
const handleI18nRouting = createIntlMiddleware({
locales: ['en', 'ru', 'de'],
defaultLocale: 'en',
localePrefix: 'as-needed',
localeDetection: false,
alternateLinks: false,
});


export default async function middleware(request: NextRequest) {
const response = handleI18nRouting(request);
//lot of conditiaonal logic

return response;
}
In our projects it works well with a lot of conditions redirects and rewrites. With these versions of packages.
"next": "14.1",
"next-intl": "^3.12.0",
Avatar
It doesn't seem to work as i guess this part is basically doesn't let it through
 if (company?.data?.domain) {
    return NextResponse.rewrite(new URL(`/${locale}/${company?.data?.domain}`, req.url));
  }
Avatar
Okay i found the solution incase anyone was wondering, in the rewrite function after the url, you can define a middleware init.

return NextResponse.rewrite(new URL(`/${locale}/${company?.data?.domain}`, req.url), intlMiddleware(req));


So it does look like this now, and it works like a charm.
Answer