Navigation APIs
The navigation APIs are only needed when you're using i18n routing.
next-intl
provides lightweight wrappers around Next.js' navigation APIs like <Link />
(opens in a new tab) and useRouter
(opens in a new tab) that automatically handle the user locale and pathnames behind the scenes.
Depending on if you're using the pathnames
setting, you can pick from one of these functions to create the corresponding navigation APIs:
createSharedPathnamesNavigation
: Pathnames are shared across all locales (default)createLocalizedPathnamesNavigation
: Pathnames are provided per locale (use withpathnames
)
These functions are typically called in a central module like src/routing.ts
in order to provide easy access to navigation APIs in your components and should receive a routing
configuration that is shared with the middleware.
import {createSharedPathnamesNavigation} from 'next-intl/navigation';
import {defineRouting} from 'next-intl/routing';
const routing = defineRouting(/* ... */);
export const {Link, redirect, usePathname, useRouter} =
createSharedPathnamesNavigation(routing);
What if the locales aren't known at build time?
In case you're building an app where locales can be added and removed at runtime, createSharedPathnamesNavigation
can be called without the locales
argument, therefore allowing any string that is encountered at runtime to be a valid locale.
In this case, you'd not use the defineRouting
function.
import {createSharedPathnamesNavigation} from 'next-intl/navigation';
export const {Link, redirect, usePathname, useRouter} =
createSharedPathnamesNavigation({
// ... potentially other routing
// config, but no `locales` ...
});
Note however that the locales
argument for the middleware is mandatory. However, you can provide the routing configuration for the middleware dynamically per request.
How can I ensure consistent usage of navigation APIs?
To ensure consistent usage in your app, you can consider linting for usage of these APIs.
APIs
Link
This component wraps next/link
(opens in a new tab) and automatically prefixes the href
with the either the current locale or a locale the user is switching to as necessary.
import {Link} from '@/routing';
// When the user is on `/en`, the link will point to `/en/about`
<Link href="/about">About</Link>
// You can override the `locale` to switch to another language
<Link href="/" locale="de">Switch to German</Link>
// Dynamic params need to be interpolated into the pathname
<Link href="/users/12">Susan</Link>
If you're providing the locale
prop, the hreflang
attribute will be set accordingly on the anchor tag.
How can I render a navigation link?
The useSelectedLayoutSegment
hook (opens in a new tab) from Next.js allows you to detect if a given child segment is active from within the parent layout. Since this returns an internal pathname, it can be matched against an href
that you can pass to Link
.
'use client';
import {useSelectedLayoutSegment} from 'next/navigation';
import {ComponentProps} from 'react';
import {Link} from '@/routing';
export default function NavigationLink({
href,
...rest
}: ComponentProps<typeof Link>) {
const selectedLayoutSegment = useSelectedLayoutSegment();
const pathname = selectedLayoutSegment ? `/${selectedLayoutSegment}` : '/';
const isActive = pathname === href;
return (
<Link
aria-current={isActive ? 'page' : undefined}
href={href}
style={{fontWeight: isActive ? 'bold' : 'normal'}}
{...rest}
/>
);
}
<nav>
<NavigationLink href="/">{t('home')}</NavigationLink>
<NavigationLink href="/about">{t('about')}</NavigationLink>
<NavigationLink href="/blog">{t('blog')}</NavigationLink>
</nav>
See also the Next.js docs on creating an active link component (opens in a new tab).
How does prefetching of localized links work?
Just like next/link
, by default all links are prefetched. The one exception to this is that links to other locales aren't prefetched, because this may result in prematurely overwriting the locale cookie.
useRouter
If you need to navigate programmatically, e.g. in an event handler, next-intl
provides a convience API that wraps useRouter
from Next.js (opens in a new tab) and automatically applies the locale of the user.
'use client';
import {useRouter} from '@/routing';
const router = useRouter();
// When the user is on `/en`, the router will navigate to `/en/about`
router.push('/about');
// You can override the `locale` to switch to another language
router.replace('/about', {locale: 'de'});
// Dynamic params need to be interpolated into the pathname
router.push('/users/12', {locale: 'de'});
How can I change the locale for the current page?
By combining usePathname
with useRouter
, you can change the locale for the current page programmatically.
'use client';
import {usePathname, useRouter} from '@/routing';
const pathname = usePathname();
const router = useRouter();
router.replace(pathname, {locale: 'de'});
usePathname
To retrieve the pathname without a potential locale prefix, you can call usePathname
.
'use client';
import {usePathname} from '@/routing';
// When the user is on `/en`, this will be `/`
const pathname = usePathname();
redirect
If you want to interrupt the render and redirect to another page, you can invoke the redirect
function. This wraps the redirect
function from Next.js (opens in a new tab) and automatically applies the current locale.
import {redirect} from '@/routing';
// When the user is on `/en`, this will be `/en/login`
redirect('/login');
// Dynamic params need to be interpolated into the pathname
router.push('/users/12');
permanentRedirect
(opens in a new tab)
is supported too.
getPathname
If you need to construct a particular pathname based on a locale, you can call the getPathname
function. This can for example be useful to retrieve a canonical link (opens in a new tab) for a page that accepts search params.
(This API is only available for localized pathnames, since it is not necessary for shared pathnames.)