最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - How to force Next.js to always redirect to a preferred user language? - Stack Overflow

programmeradmin4浏览0评论

Currently, Next.js makes a redirect to the user's language only from the root, so "/" bees "/fr-FR". But if a user accesses for example "/profile" route, it won't redirect him to the "/fr-FR/profile".

Is there a way to force Next to do these kinds of redirects?

Currently, Next.js makes a redirect to the user's language only from the root, so "/" bees "/fr-FR". But if a user accesses for example "/profile" route, it won't redirect him to the "/fr-FR/profile".

Is there a way to force Next to do these kinds of redirects?

Share Improve this question edited Jun 21, 2021 at 10:17 Gucal 9231 gold badge12 silver badges22 bronze badges asked May 12, 2021 at 10:40 Bohdan KontsedalBohdan Kontsedal 1513 silver badges12 bronze badges 2
  • 1 This is a highly rated feature request, github./vercel/next.js/discussions/18419 – AviKKi Commented Aug 9, 2021 at 23:59
  • Does this answer your question: How to enforce i18n locale slugs and achieve i18n consistency upon reload in Next.js?? – juliomalves Commented Jul 24, 2022 at 6:03
Add a ment  | 

5 Answers 5

Reset to default 1

For me the key was to set up my _middleware.ts the following way:

const PUBLIC_FILE = /\.(.*)$/ // anything having a file extension.
const getIsInternalRoute = (url: string) => {
    if (url.startsWith('/_next')) return true // next internal routes
    if (url.includes('/api/')) return true // nextjs api routes
    return PUBLIC_FILE.test(url) // static files
}

const handleLocaleRedirects = (req: NextRequest) => {
    const { pathname } = req.nextUrl
    const isPreloadRequest = req.method === 'HEAD'
    /*
    Due to several bugs with prefetching/middleware/i18n bination
    https://github./vercel/next.js/issues/35648
    https://github./vercel/next.js/issues/36100
    https://github./vercel/next.js/issues/40678

    we cannot redirect any prefetch requests. They get cached with the current locale which then causes
    infinite loop redirect when we click a link to change the locale.
    Possibly might be fixed in later NextJs versions (>=13), but I'd be really careful & skeptical here.
     */
    if (isPreloadRequest || getIsInternalRoute(pathname)) return

    const locale = req.cookies.NEXT_LOCALE || req.nextUrl.defaultLocale // locale you're supposed to have
    if (locale && req.nextUrl.locale !== locale) {
        req.nextUrl.locale = locale
        return NextResponse.redirect(req.nextUrl)
    }
}

export function middleware(req: NextRequest) {
    const maybeRedirectResponse = handleLocaleRedirects(req)
    if (maybeRedirectResponse) return maybeRedirectResponse

    const response = NextResponse.next()

    // perhaps other middleware logic here...

    return response
}

and set up the switcher link to set the cookie before redirecting to the new route, so the middleware already has the new NEXT_LOCALE value.

function LocaleSwitcher({ locale, children, ...props }) {
    const router = useRouter()
    const { pathname, asPath, query } = router

    const handleClick = e => {
        e.preventDefault()

        /*
        The locale cookie needs to be set before the page redirect, so the nextjs middleware already knows which locale is correct.
         */
        setCookie({}, 'NEXT_LOCALE', locale, {
            maxAge: 100 * 365 * 24 * 60 * 60, // 100 yrs
        })
        // change just the locale and maintain all other route information including href's query
        router.push({ pathname, query }, asPath, { locale })
    }

    return (
        <Link {...props} locale={locale} to={asPath} onClick={handleClick}>
            {children}
        </Link>
    )
}

This setup checks the user's locale from the cookie on every route and redirects them to the correct locale version of the site.

Check out this Page from the official NextJS Documentation:

Prefixing the Default Locale

It solves your problem by redirecting domain./example to domain./en/example

You can do it with middleware and NEXT_LOCALE cookie, when you change language you should set this cookie

document.cookie = `NEXT_LOCALE=${langugage};path=/`;

middleware.js

import { NextResponse } from "next/server";

export function middleware(request) {
  const localeCookie = request.cookies.get("NEXT_LOCALE");
  if (localeCookie !== undefined && request.nextUrl.locale !== localeCookie) {
    return NextResponse.redirect(new URL(`/${localeCookie}${request.nextUrl.pathname}`, request.url));
  }
}
export const config = { 
  matcher: ["/", "/about"], // paths on which middleware will work
};

https://nextjs/docs/advanced-features/i18n-routing#leveraging-the-next_locale-cookie

https://nextjs/docs/advanced-features/i18n-routing#prefixing-the-default-locale

https://nextjs/docs/advanced-features/middleware

https://nextjs/docs/messages/middleware-upgrade-guide

https://nextjs/docs/api-reference/next/server

This reference https://nextjs/docs/advanced-features/i18n-routing#transition-between-locales:

router.push(router.asPath, router.asPath, { locale: language });
Sub-path Routing
Sub-path Routing puts the locale in the url path.

With the above configuration en-US, fr, and nl-NL will be available to be routed to, and en-US is the default locale. If you have a pages/blog.js the following urls would be available:

//next.config.js
module.exports = {
  i18n: {
    locales: ['en-US', 'fr', 'nl-NL'],
    defaultLocale: 'en-US',
  },
}

/blog
/fr/blog
/nl-nl/blog
The default locale does not have a prefix.

from Nextjs docs
发布评论

评论列表(0)

  1. 暂无评论