next.jsmiddlewarenext-intl

next js internationalization and auth


I have a problem in setting up route middleware and internationalization in next js and laravel . I want to do is that if there is no token , user can not go other page by typing from url .So I added middleware . But that's showing as like this error . This is my middleware code .

import { NextResponse } from "next/server";
import { isPathStartsWithBackSlash } from "./app/utils/checkUrlTypes";
import createMiddleware from "next-intl/middleware";

const locales = ["en", "mm", "jp"];
const defaultLocale = "mm";
const i18nMiddleware = createMiddleware({ locales, defaultLocale });

export function middleware(request) {
  const pathName = request.nextUrl.pathname;
  console.log("pathName", pathName);
  // Internationalization logic (using next-intl)
  i18nMiddleware(request); // Execute internationalization middleware first

  // Authentication logic
  if (isPathStartsWithBackSlash(pathName)) {
    const cookies = request.headers.get("cookie");
    const hasCookie = cookies && cookies.includes("IncomeController");
    if (!hasCookie) {
      console.log("no cookie");
      return NextResponse.redirect(new URL("/404", request.url));
    }
  }

  // Continue with the default behavior
  return NextResponse.next();
}

export const config = {
  matcher: ["/", "/(mm|jp|en)/:path*"],
};

If I changed this code , the route is worked . But cannot protect route by typing from Url.

//TODO ADD route middleware for internationalization
import createMiddleware from "next-intl/middleware";
import { NextResponse } from "next/server";

let locales = ["en", "mm", "jp"];

const middleware = createMiddleware({
  // Add locales you want in the app
  locales: ["en", "mm", "jp"],

  // Default locale if no match
  defaultLocale: "mm",
});

export default middleware;

export const config = {
  // Match only internationalized pathnames
  matcher: ["/", "/(mm|jp|en)/:path*"],
};

This is my next js folder structure folder structure

This is layout.jsx layout.jsx

Please kindly help me . I took 1 week for this and still counting. Thank you for your time.

This works also . But cannot do internationalization.

middleware.jsx

import { NextResponse } from 'next/server';
import { isPathStartsWithBackSlash } from './libs/checkUrlTypes'

export function middleware(request) {
  const pathName = request.nextUrl.pathname

  // Check if the requested URL matches a protected route
  if (isPathStartsWithBackSlash(pathName)) {
    // Check if the cookie exists in the request headers
    const cookies = request.headers.get('cookie');
    const hasCookie = cookies && cookies.includes('IncomeController');
    if (!hasCookie) {
      // If the cookie is not present, redirect to the unauthorized page
      return NextResponse.redirect(new URL('/404', request.url));
    }
  }
  // If the request doesn't match a protected route or the user is authenticated, continue with the default behavior
  return NextResponse.next();
}

export const config = {
  matcher: ['/:path*'],
};

Solution

  • I got with this . If you have same problem , please reference this

    Gist Link

    config.js

    export const locales = ["mm", "en", "jp"];
    
    export const defaultLocale = "mm";
    

    i18n-config.js

    export const i18n = {
    
    locales: ["mm", "en", "jp"],
      defaultLocale: "mm",
    };
    
    export const I18nConfig = i18n;
    
    export const Locale = I18nConfig["locales"];
    

    i18n.js

    import { notFound } from "next/navigation";
    import { getRequestConfig } from "next-intl/server";
    import enMessages from "../messages/en.json";
    import mmMessages from "../messages/mm.json";
    import jpMessages from "../messages/jp.json";
    
    const messages = {
      en: enMessages,
      mm: mmMessages,
      jp: jpMessages,
    };
    
    export default getRequestConfig(async ({ locale }) => {
      if (!(locale in messages)) notFound();
    
      return {
        messages: messages[locale],
      };
    });