0

I want to hide the default locale in NextJS, i.e by default domain.com should work. But if user lands on domain.com/en, this should also work.

My folder structure:

src/app/[locale]/...

src/app/blog/[slug]

Blog and posts should work without locale.

src/app/i18n/routing.ts:

import { defineRouting } from 'next-intl/routing'
import { createNavigation } from 'next-intl/navigation'
import { DEFAULT_LOCALE, SUPPORTED_LOCALES } from '../../app.config'

export const routing = defineRouting({
  // A list of all locales that are supported
  locales: SUPPORTED_LOCALES,
  // Used when no locale matches
  defaultLocale: DEFAULT_LOCALE,
})

// Lightweight wrappers around Next.js' navigation APIs
// that will consider the routing configuration
export const { Link, redirect, usePathname, useRouter, getPathname } = createNavigation(routing)

src/app/i18n/request.ts:

import { getRequestConfig } from 'next-intl/server'
import { routing } from './routing'
import { Locale } from '@/types/types'

export default getRequestConfig(async ({ requestLocale }) => {
  // This typically corresponds to the `[locale]` segment
  let locale = await requestLocale

  // Ensure that a valid locale is used
  if (!locale || !routing.locales.includes(locale as Locale)) {
    locale = routing.defaultLocale
  }

  return {
    locale,
    messages: (await import(`../../messages/${locale}.json`)).default,
  }
})

src/app/middleware.ts:

import createMiddleware from 'next-intl/middleware'
import { routing } from './i18n/routing'

export default createMiddleware(routing)

export const config = {
  // Match only internationalized pathnames
  matcher: ['/', '/(en|de|es|fr|it|pt|ru|uk|id|da|nl|hi|ko|ja|zh)/:path*'],
}

I tried using localePrefix:'as-needed' in routing.ts and matcher: ['/((?!api|_next|_vercel|.*\\..*).*)'] in middleware.ts. Making these changes works for all paths inside src/app/[locale] also default locale gets hidden as expected but src/app/blog and src/app/blog/[slug] does not work, giving a 404 error. How to make blog work, blog should be outside [locale] as I don't want i18n for blog paths and articles.

1 Answer 1

0

I made it work using the below matcher in middleware.ts in NextJS 15 app

export const config = {
  matcher: ['/((?!api|_next|_vercel|.*\\..*|blog(?:/.*)?).*)'],
}

So this is how my files look now:

src/app/i18n/routing.ts:

import { defineRouting } from 'next-intl/routing'
import { createNavigation } from 'next-intl/navigation'
import { DEFAULT_LOCALE, SUPPORTED_LOCALES } from '../../app.config'

export const routing = defineRouting({
  // A list of all locales that are supported
  locales: SUPPORTED_LOCALES,
  // Used when no locale matches
  defaultLocale: DEFAULT_LOCALE,
  localePrefix: 'as-needed',
})

// Lightweight wrappers around Next.js' navigation APIs
// that will consider the routing configuration
export const { Link, redirect, usePathname, useRouter, getPathname } = createNavigation(routing)

src/app/i18n/request.ts:

import { getRequestConfig } from 'next-intl/server'
import { routing } from './routing'
import { Locale } from '@/types/types'

export default getRequestConfig(async ({ requestLocale }) => {
  // This typically corresponds to the `[locale]` segment
  let locale = await requestLocale

  // Ensure that a valid locale is used
  if (!locale || !routing.locales.includes(locale as Locale)) {
    locale = routing.defaultLocale
  }

  return {
    locale,
    messages: (await import(`../../messages/${locale}.json`)).default,
  }
})

src/app/middleware.ts:

import createMiddleware from 'next-intl/middleware'
import { routing } from './i18n/routing'

export default createMiddleware(routing)

export const config = {
  // Match only internationalized pathnames, excluding /blog and /blog/article-slug etc.
  matcher: ['/((?!api|_next|_vercel|.*\\..*|blog(?:/.*)?).*)'],
  // matcher: ['/', '/(en|de|es|fr|it|pt|ru|uk|id|da|nl|hi|ko|ja|zh)/:path*'],
}
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.