| name | nextjs-nextintl-localized-link |
| description | Fix broken locale routing in Next.js apps using next-intl. Use when: (1) Links
navigate without locale prefix (e.g., /dashboard instead of /en/dashboard), (2)
Language preference lost on navigation, (3) 404 errors due to missing locale in URL,
(4) Setting up new Next.js project with next-intl. Solves import of Link component
from wrong module - must use @/i18n/routing instead of next/link.
|
| author | Claude Code |
| version | 1.0.0 |
| date | "2026-01-22T00:00:00.000Z" |
Next.js next-intl Localized Link Component
Problem
When using next-intl for internationalization in Next.js, importing Link from
next/link breaks locale routing. Links will navigate without the locale prefix,
causing 404 errors or loss of language preference.
Example issue:
- Expected URL:
/en/admin/instructors/123
- Actual URL:
/admin/instructors/123 (missing locale prefix → 404)
Context / Trigger Conditions
Use the localized Link when:
- next-intl is configured with
localePrefix: "always" or "as-needed"
- Navigation breaks locale routing: Links work but URL loses locale prefix
- 404 errors on navigation despite routes existing
- Language preference resets when clicking internal links
- Setting up new components in a next-intl project
Solution
Step 1: Import from Localized Routing Module
❌ WRONG (standard Next.js Link):
import Link from "next/link";
✅ CORRECT (localized Link):
import { Link } from "@/i18n/routing";
Step 2: Use the Localized Link in Components
The API is identical to Next.js Link, but it automatically includes locale:
import { Link } from "@/i18n/routing";
export function MyComponent() {
return (
<Link href="/admin/instructors">
View Instructors
</Link>
);
}
What happens:
- In English locale: Renders
/en/admin/instructors
- In Urdu locale: Renders
/ur/admin/instructors
- Locale is automatically prepended based on current user's language
Step 3: Configure Routing Module (First-Time Setup)
If @/i18n/routing doesn't exist, create it:
File: src/i18n/routing.ts
import { createNavigation } from 'next-intl/navigation';
export const routing = {
locales: ['en', 'ur', 'ar', 'so'],
defaultLocale: 'en',
localePrefix: 'always' as const
};
export const { Link, redirect, usePathname, useRouter } =
createNavigation(routing);
Step 4: Update All Components
Search and replace across your codebase:
grep -r "import Link from \"next/link\"" apps/web/components/
Verification
After using the localized Link:
- ✅ URLs include locale prefix (e.g.,
/en/dashboard)
- ✅ Language preference preserved on navigation
- ✅ No 404 errors on internal links
- ✅ Locale switching works correctly
Example: Real-World Fix
Before (broken locale routing):
import Link from "next/link";
export function InstructorReviewCard({ instructor }: Props) {
return (
<Link href={`/admin/instructors/${instructor.id}`}>
View Details
</Link>
);
}
Issue: Link navigates to /admin/instructors/123 without locale prefix → 404
After (correct locale routing):
import { Link } from "@/i18n/routing";
export function InstructorReviewCard({ instructor }: Props) {
return (
<Link href={`/admin/instructors/${instructor.id}`}>
View Details
</Link>
);
}
Result: Link navigates to /en/admin/instructors/123 (or /ur/... based on locale)
Other Localized Navigation APIs
The createNavigation function provides more than just Link:
import { Link, redirect, usePathname, useRouter } from "@/i18n/routing";
<Link href="/dashboard">Dashboard</Link>
redirect('/login');
const pathname = usePathname();
const router = useRouter();
router.push('/settings');
Common Pitfalls
1. Mixing Imports
import Link from "next/link";
import { useRouter } from "@/i18n/routing";
Fix: Use all navigation APIs from @/i18n/routing
2. External Links
<a href="https://example.com">External Link</a>
Localized Link is only needed for internal navigation.
3. API Routes
fetch('/api/data')
Configuration Options
localePrefix Strategies
localePrefix: 'always'
localePrefix: 'as-needed'
Pathname Localization (Advanced)
export const routing = {
locales: ['en', 'de'],
defaultLocale: 'en',
pathnames: {
'/': '/',
'/about': {
en: '/about',
de: '/uber-uns'
}
}
};
With pathname localization:
- English:
<Link href="/about"> → /en/about
- German:
<Link href="/about"> → /de/uber-uns
Notes
- Type Safety: Localized Link is fully typed with TypeScript
- Performance: No runtime overhead - just wraps Next.js Link with locale logic
- Server Components: Works in both Server and Client Components
- Backward Compatible: Same API as Next.js Link (href, prefetch, etc.)
- Automatic Locale Detection: Uses locale from URL, cookies, or headers
References