How handle next-intl and middleware ?
Unanswered
California pilchard posted this in #help-forum
California pilchardOP
Okay I have a lot of problem with my middleware and
Btw I have a rewrite in
next-intl
. I dont know how can I handle locale rooting, with static file (in public
folder), and with robots.ts
and sitemap.ts
. My current middleware is like this :import { NextRequest, NextResponse } from 'next/server';
import createIntlMiddleware from 'next-intl/middleware';
import { createMiddlewareClient } from './lib/supabase/middleware';
import { routing } from './lib/i18n/routing';
const intlMiddleware = createIntlMiddleware(routing);
export async function middleware(request: NextRequest) {
let response = intlMiddleware(request);
const url = request.nextUrl.clone();
const localeMatch = url.pathname.split('/')[1];
const hasLocale = routing.locales.includes(localeMatch as any);
if (hasLocale) url.pathname = url.pathname.replace(`/${localeMatch}`, '');
// IMPORTANT: Avoid writing any logic between createServerClient and
// supabase.auth.getUser(). A simple mistake could make it very hard to debug
// issues with users being randomly logged out.
const supabase = createMiddlewareClient({ request, response });
const {
data: { user },
} = await supabase.auth.getUser();
/**
* Check locale if user is logged in
*/
const localeHeader = response.headers.get('x-middleware-request-x-next-intl-locale');
const { data: config } = await supabase.rpc('get_config', {
user_id: user?.id,
}).single();
if (user && config?.user_language && routing.locales.includes(config.user_language)) {
const wrongLocale =
(hasLocale && localeMatch !== config.user_language) ||
(localeHeader && localeHeader !== config.user_language);
if (wrongLocale) {
url.pathname = `/${config.user_language}${url.pathname}`;
return (NextResponse.redirect(url));
}
}
/**
* Check maintenance mode
*
* If the app is in maintenance mode, redirect all users to the maintenance page
* If the app is not in maintenance mode, redirect all users to the home page
*
*/
if (config?.maintenance_mode && url.pathname !== '/maintenance' && process.env.NODE_ENV !== 'development') {
url.pathname = `/maintenance`;
return (NextResponse.redirect(url));
} else if (url.pathname === '/maintenance' && !config?.maintenance_mode) {
url.pathname = '/';
return (NextResponse.redirect(url));
}
/**
* Redirect user if not logged in
*/
const anonUserOnly = [
'/auth'
];
if (user && anonUserOnly.some((path) => url.pathname.startsWith(path))) {
// if /auth/login and there is redirect query param, go to redirect
if (url.pathname === '/auth/login' && url.searchParams.has('redirect'))
return (NextResponse.redirect(new URL(url.searchParams.get('redirect')!, request.url)));
url.pathname = '/';
url.search = '';
return (NextResponse.redirect(url));
}
/**
* Redirect user if logged in
*/
const authentifiedUserOnly = [
'/collection',
'/feed',
'/settings',
];
if (!user && authentifiedUserOnly.some((path) => url.pathname.startsWith(path))) {
url.pathname = '/auth/login';
url.searchParams.set('redirect', request.nextUrl.pathname);
return (NextResponse.redirect(url));
}
/**
* Redirect user if not premium
*/
const premiumUserOnly = [
'/feed/cast-crew',
];
if (user && !config?.user_premium && premiumUserOnly.some((path) => url.pathname.startsWith(path))) {
url.pathname = '/upgrade';
return (NextResponse.redirect(url));
}
return (response);
}
export const config = {
matcher: [
'/((?!api|_next|_vercel|.*\\..*).*)',
// User pages
'/@:username/:path*',
],
};
Btw I have a rewrite in
next.config.ts
:async rewrites() {
return [
{
source: '/:lang/@:username/:path*',
destination: '/:lang/user/:username/:path*',
},
];
},
2 Replies
California pilchardOP
So my folder are :
tree -L 2 src/app
src/app
├── [lang]
│ ├── (app)
│ ├── (maintenance)
│ └── layout.tsx
├── api
│ ├── revalidate
│ └── stripe
├── robots.ts
└── sitemaps
└── sitemap.ts
robots.txt
is working on /robots.txt
, but /sitemaps/sitemap.yml
go to /[lang]/(app)/layout.ts
California pilchardOP
Ive change my matcher by :
matcher: [ `/((?!api|_next|_vercel|favicon\\.ico|manifest\\.webmanifest|robots\\.txt|sitemaps/|opensearch\\.xml|assets/|.*\\.(?:json|xml|js)$).*)`,
],