I have a critical redirect issue on my project biomanage-next (domain: biomanage.it) that I cannot solve. My site uses an A-Record setup (not Vercel nameservers).
My Problem: Google is reporting redirect errors for www.biomanage.it and URLs with trailing slashes (like /en/). My “Test URL Live” in Google Search Console confirms that these redirects are not working (they return a 200 OK).
What I Did (The Final Solution): I have put all redirect logic into my middleware.js file, as this is the only file that should execute on an A-Record setup. I have removed all redirect logic from next.config.js and vercel.json to prevent conflicts.
The Problem: I have deployed this code (and cleared the cache on Vercel), but Google’s “Test URL Live” (and my own tests) show that this middleware is not running. Requests to https://www.biomanage.it/ and https://biomanage.it/en/ still return a 200 OK, not a 308 redirect.
It seems like my middleware.js file is being ignored or not deployed correctly, even though the deploy log says it’s complete.
Can you please investigate why my middleware redirects are not executing?
Here is my complete middleware.js file:
import { NextResponse } from ‘next/server’;
import Negotiator from ‘negotiator’;
import { match } from ‘@formatjs/intl-localematcher’;
let locales = \[‘en’, ‘it’\];
let defaultLocale = ‘it’;
function getLocale(request) {
const acceptLanguageHeader = request.headers.get(‘accept-language’);
const languages = acceptLanguageHeader ? new Negotiator({ headers: { ‘accept-language’: acceptLanguageHeader } }).languages() : [ ];
return match(languages, locales, defaultLocale);
}
export function middleware(request) {
const { pathname } = request.nextUrl;
const hostname = request.nextUrl.hostname;
if (
pathname.startsWith(‘/\_next/’) || pathname.startsWith(‘/api/’) ||
pathname.startsWith(‘/photo/’) || pathname.startsWith(‘/flags/’) ||
pathname.startsWith(‘/font/’) || pathname.includes(‘.’)
) {
return NextResponse.next();
}
// 2. Redirect www to non-www
if (hostname.startsWith(‘www.’)) {
const newUrl = request.nextUrl.clone();
newUrl.hostname = hostname.replace(‘www.’, ‘’);
return NextResponse.redirect(newUrl, 308);
}
// 3. Remove trailing slash
if (pathname.endsWith(‘/’) && pathname.length > 1) {
const newUrl = request.nextUrl.clone();
newUrl.pathname = pathname.slice(0, -1);
return NextResponse.redirect(newUrl, 308);
}
// 4. Language logic
const pathnameHasLocale = locales.some(
(locale) => pathname.startsWith(`/${locale}/`) || pathname === `/${locale}`
);
if (pathnameHasLocale) {
return NextResponse.next();
}
const locale = getLocale(request);
const url = request.nextUrl.clone();
url.pathname = `/${locale}${pathname}`;
return NextResponse.redirect(url);
}
export const config = {
matcher: \[
‘/((?!api|\_next|.+\\..+).\*)’,
\],
};