if the ip address of the user entering the site is blocked, I want to redirect to a different page such as /blocked and not access the site. I wanted to create a fetch request on my middleware and run other codes according to the result, but next-intl gave the error “Unable to find next-intl locale because the middleware didn't run on this request.”
what do I need to do to control banned users via api? waiting for your advice
import createMiddleware from 'next-intl/middleware';
import { defaultLocale, locales, pathnames } from "./config/lang-config";
import withAuth from 'next-auth/middleware';
import { NextRequest, NextResponse } from 'next/server';
import { getProfile } from './services/authQueries';
const privatePages = [
'/profile',
'/settings',
'/settings/*',
'/wallet',
'/wallet/*',
'/auth/logout',
];
const intlMiddleware = createMiddleware({
defaultLocale,
locales,
localePrefix: "as-needed",
pathnames,
localeDetection: true,
});
const authMiddleware = withAuth(
// Note that this callback is only invoked if
// the `authorized` callback has returned `true`
// and not for pages listed in `pages`.
function onSuccess(req) {
return intlMiddleware(req);
},
{
callbacks: {
authorized: async ({ token }: { token: any }) => {
const accessToken = token?.tokenData?.token || token?.token as string;
if (token) {
try {
const res = await getProfile(accessToken as string, 'en');
if (res.isSucceed) {
token.user = res.data;
return true;
} else {
throw new Error(res.message);
}
} catch (error) {
if (error instanceof Error) {
console.error(error.message);
} else {
console.error('An unknown error occurred');
}
return false;
}
} else {
return false;
}
},
},
pages: {
signIn: '/',
}
}
);
const env = process.env.NODE_ENV;
const blockedCountries = ['US', 'UK'];
export default function middleware(req: NextRequest) {
const res = NextResponse.next()
const pathname = req.nextUrl.pathname
// Skip this middleware in development or if the path is international
if (env !== 'development' && pathname !== '/blocked') {
const country = req.geo?.country || req.headers.get('cloudfront-viewer-country') || req.headers.get('x-vercel-ip-country');
if (blockedCountries.includes(country ?? '')) {
return NextResponse.redirect(new URL('/blocked', req.url))
}
}
const privatePathnameRegex = RegExp(
`^(/(${locales.join('|')}))?(${privatePages
.flatMap((p) => {
// for '*'
return p.replace(/\*/g, '.*');
})
.map((p) => (p === '/' ? ['', '/'] : p))
.join('|')})/?$`,
'i'
);
const isPrivatePage = privatePathnameRegex.test(req.nextUrl.pathname);
if (!isPrivatePage) {
const country = req.geo?.country || req.headers.get('cloudfront-viewer-country') || req.headers.get('x-vercel-ip-country');
const response = intlMiddleware(req);
response.cookies.set("client-counry", country || '');
return response;
} else {
return (authMiddleware as any)(req);
}
}
export const config = {
matcher: [
// Enable a redirect to a matching locale at the root
'/',
// Set a cookie to remember the previous locale for
// all requests that have a locale prefix
'/(en-US)/:path*',
// Enable redirects that add missing locales
// (e.g. `/pathnames` -> `/en/pathnames`)
'/((?!api|_next|_vercel|.*\\..*).*)'
]
};
I sent an API request on Middleware and redirected the user with NextResponse according to the incoming data, but I got the following error "Unable to find next-intl locale because the middleware didn't run on this request."