ixartz/Next-js-Boilerplate

Should Intl middleware be applied to API routes?

sunxyw opened this issue ยท 7 comments

Problem

Glad to see you added i18n to this boilerplate.

I noticed in middleware.ts that intlMiddleware in beforeAuth will be applied on every request, even if it is an API route.

export default authMiddleware({
publicRoutes: (req: NextRequest) =>
!req.nextUrl.pathname.includes('/dashboard'),
ignoredRoutes: ['/api/guestbook'],
// By default, the middleware will return a 401 response for all routes `/api/*` when the user is signed out.
// But, for `/api/guestbook`, we want unauthenticated users to be able to access it.
beforeAuth: (req) => {
// Execute next-intl middleware before Clerk's auth middleware
return intlMiddleware(req);
},

Since the API route does not contain the locale parameter, this causes a 404 to be returned when using intlMiddleware.

The example API route /api/guestbook is placed in the ignore list, therefore does not apply any middleware, perhaps causing you to overlook this issue.

Reproduce

Removing /api/guestbook from ignoredRoutes should reproduce the issue. (which mark it as public route)

Potential Fix

I simply added a condition to it to only execute in non-API routes, not sure if there is a better solution.

beforeAuth: (req) => {
    // Execute next-intl middleware before Clerk's auth middleware
    if (!req.nextUrl.pathname.includes('/api')) {
      return intlMiddleware(req);
    }
    return undefined;
  },

I just apply change following the official documentation from next-intl and Clerk. Applying without giving a thought. Indeed, it can create an issue for /api route

I just recheck the official documentation from next-intl, if I'm not wrong, they never mention about Route Handlers. I think Everybody will should have the same issue using next-intl, this not specific to the boilerplate, right?

Another solution is to place /api/guestbook inside [locale] folder, also not sure if it's working and not sure it's a good solution.

You potential fix can be a solution, does it have some side effect?

Even I never do translation in /api, I think most of the users will expect to have translation also available in Route Handler. So, they can also translate in Router Handler by moving it inside [locale], what do you think?

One of the official example, the route handler is inside [locale]: https://github.com/amannn/next-intl/blob/4572f9666e3ba2da81e78851967865e5e860fd3d/examples/example-app-router-playground/src/app/%5Blocale%5D/api/route.ts

You potential fix can be a solution, does it have some side effect?

At least in my current use, it doesn't have any visible issues.

I found this page in the documentation: https://next-intl-docs.vercel.app/docs/environments/metadata-route-handlers#route-handlers

I briefly looked at the documentation and the example. I think it only requires that we pass the locale into the getTranslations function, and it doesn't matter where the locale is obtained from.

So I think both of them (extracting locale from header or searchParams, or putting Route Handler into [locale]) are feasible solutions.


The cause of the problem is probably that Intl Middleware will try to rewrite all requests to /en, which works fine in [locale], but since the Route Handler does not inside [locale], this will cause a 404 error. Changing localePrefix to always makes this behavior more obvious.

I think both of the following two solutions can solve this:

  1. Skip Intl Middleware for API Routes and get the locale from header or other sources.
  2. Move API Routes into [locale] and get the locale from route segment.

Perhaps the 2. is a more intuitive one for regular users? Not sure.

Perhaps the 2. is a more intuitive one for regular users? Not sure.

I also think it's more intuitive and regular users.

Already not a huge fan about these 2 lines in the middleware: https://github.com/ixartz/Next-js-Boilerplate/blob/main/src/middleware.ts#L15-L16. So, if we can avoid make any custom change in the middleware, it would be great.

Do you think you can open a PR for the 2. solution?

Do you think you can open a PR for the 2. solution?

Sure.

๐ŸŽ‰ This issue has been resolved in version 3.30.1 ๐ŸŽ‰

The release is available on GitHub release

Your semantic-release bot ๐Ÿ“ฆ๐Ÿš€