Most of the things work fine, but when following the tutorial here for setting up next-intl with i18n routing it fails specifically at the createMiddleware part. My guess is that it's happening because of the fact that I am trying to mix the config.matcher part.
This is how the middleware looks now:
// ./src/middleware.ts
import { NextRequest, NextResponse } from 'next/server';
import { createClient } from '@/prismicio';
import createMiddleware from 'next-intl/middleware';
export default createMiddleware({
// A list of all locales that are supported
locales: ['en', 'ro'],
// Used when no locale matches
defaultLocale: 'ro'
});
export async function middleware(request: NextRequest) {
const client = createClient();
const repository = await client.getRepository();
const locales = repository.languages.map((lang) => lang.id);
const defaultLocale = locales[0];
// Check if there is any supported locale in the pathname
const { pathname } = request.nextUrl;
const pathnameIsMissingLocale = locales.every(
(locale) => !pathname.startsWith(`/${locale}/`) && pathname !== `/${locale}`
);
// Redirect to default locale if there is no supported locale prefix
if (pathnameIsMissingLocale) {
return NextResponse.rewrite(
new URL(`/${defaultLocale}${pathname}`, request.url)
);
}
}
export const config = {
matcher: [
/*
* Match all request paths except for the ones starting with:
* - api (API routes)
* - _next/static (static files)
* - _next/image (image optimization files)
* - images directory in /public (public static images)
*/
'/((?!api|_next/static|_next/image|images).*)',
],
};
The error I am getting is the following:
lang ro
Unable to find `next-intl` locale because the middleware didn't run on this request. See https://next-intl-docs.vercel.app/docs/routing/middleware#unable-to-find-locale. The `notFound()` function will be called as a result.
GET / 404 in 57ms
What I am trying to achieve is the following:
default lang "ro" should be reachable without any "path". While any other languages like "en-us" should be reachable with the language path.
In prismic my locales are set under "ro" and "en-us".
Thank you for reaching out. Here are some suggestions and insights that might help you resolve the issue with your middleware setup for internationalization:
Key Points from the Knowledge Base:
Locale Detection and Redirection:
When using Sub-path Routing, the user would be redirected to /fr if the locale is detected as fr.
When using Domain Routing, the user would be redirected to example.fr if the domain handles the fr locale by default.
The default locale does not have a prefix.
Middleware Configuration:
The middleware should check if there is any supported locale in the pathname and redirect to the default locale if there is no supported locale prefix.
Ensure all special files inside the app are nested under app/[lang].
Suggestions for Your Middleware:
Combining Middleware Functions:
It seems you are trying to combine the createMiddleware from next-intl with your custom middleware logic. Ensure that both middleware functions are compatible and do not conflict with each other.
Default Locale Handling:
Ensure that the default locale (ro) is correctly handled without a path prefix, while other locales like en should have the language path.
Example Middleware Configuration:
Here is an example of how you might configure your middleware to achieve the desired behavior:
// ./src/middleware.ts
import { NextRequest, NextResponse } from 'next/server';
import { createClient } from '@/prismicio';
import createMiddleware from 'next-intl/middleware';
const intlMiddleware = createMiddleware({
// A list of all locales that are supported
locales: ['en', 'ro'],
// Used when no locale matches
defaultLocale: 'ro'
});
export async function middleware(request: NextRequest) {
const client = createClient();
const repository = await client.getRepository();
const locales = repository.languages.map((lang) => lang.id);
const defaultLocale = locales[0];
// Check if there is any supported locale in the pathname
const { pathname } = request.nextUrl;
const pathnameIsMissingLocale = locales.every(
(locale) => !pathname.startsWith(`/${locale}/`) && pathname !== `/${locale}`
);
// Redirect to default locale if there is no supported locale prefix
if (pathnameIsMissingLocale) {
return NextResponse.rewrite(
new URL(`/${defaultLocale}${pathname}`, request.url)
);
}
// Run the next-intl middleware
return intlMiddleware(request);
}
export const config = {
matcher: [
/*
* Match all request paths except for the ones starting with:
* - api (API routes)
* - _next/static (static files)
* - _next/image (image optimization files)
* - images directory in /public (public static images)
*/
'/((?!api|_next/static|_next/image|images).*)',
],
};
Key Changes:
Combining Middleware: The custom middleware logic is combined with the next-intl middleware by calling intlMiddleware(request) at the end of the custom middleware function.
Default Locale Handling: The default locale (ro) is handled without a path prefix, while other locales like en are prefixed.
Ensure that your next.config.js is correctly set up with the i18n configuration.
If you continue to face issues, please provide more details about the specific error messages or behavior you are encountering, and I will be happy to assist further.
Loading mywebsite.com/ro/ works ok and also mywebsite.com/en/ but... (read below)
When accessing mywebsite.com/en/hello and calling await getLocale() from next-intl/server I expect it to return en (or en-us), but it currently returns still ro
Like said above, I would like mywebsite.com/ro/ to be called simply without the ro part as that is the default locale.
My teammate took a deep dive into next-intl and got everything working. They believe it behaves as the you want:
The default locale is not in the URL.
getLocale() works.
Prismic links work.
They uploaded an example repo that the user can use as a reference: prismic-next-intl-example. This is not an official example and may have bugs.
The example is set up for en-us and fr-fr locales. It maps en-us to the root URL and fr-fr to /fr.
Here are some important parts they highlighted for configuration:
Turn off localeDetection and alternateLinks in middleware.ts. localeDetection must be turned off if the default locale is not in the URL to avoid a redirect to another locale.
Update the middleware.ts matcher to include all routes.
Use a function to convert the URL's locale to Prismic's locale. This is necessary for URL locales that may not match a Prismic locale, such as en. Example functions are located in src/i18n/routing.ts.
Set up @prismicio/client routes using hard-coded URL overrides in prismicio.ts. This is needed to change locales from one form to another (e.g., en-us to en).