In this article, I share my experience fixing a subtle issue in a Next.js 14 project where route interceptors were silently ignored. The app still worked as an SPA β pages rendered and navigation occurred β but clicking on <Link> components bypassed the expected interceptors and triggered full navigations instead. After hours of debugging, I realized the issue wasnβt inside the app folder or React components, but stemmed from the internationalization (i18n) configuration.
π§© What happened?
I was using localized routing with next-i18next. Everything seemed configured correctly.
But suddenly:
- Navigation through
<Link>components was not intercepted by Next.js. - No errors appeared in the console.
- Copying the whole app folder into a fresh Next.js project didnβt solve the problem.
Turns out, the real issue was outside the app folder.
𧨠The root cause
It boiled down to a misconfigured or duplicated i18n setup:
- next-i18next.config.mjs contained the i18n config (locales, defaultLocale, etc).
- That config was spread into next.config.js via the spread operator.
- This sometimes caused Next.js to mishandle locale routing and break interceptors.
My custom i18n.js file looked like this:
// i18n.js
import { initReactI18next } from 'react-i18next';
import i18next from 'i18next';
import en from '../../public/locales/en/common.json';
import uk from '../../public/locales/uk/common.json';
import ru from '../../public/locales/ru/common.json';
i18next.use(initReactI18next).init({
resources: {
en: { common: en },
uk: { common: uk },
ru: { common: ru },
},
fallbackLng: 'en',
interpolation: {
escapeValue: false,
},
});
export default i18next;
And next.config.js looked like this:
// next.config.js
import nextI18NextConfig from './next-i18next.config.mjs';
/** @type {import('next').NextConfig} */
const nextConfig = {
...nextI18NextConfig,
reactStrictMode: true,
};
export default nextConfig;
π How I fixed it
In my case, I ended up:
- Deleting the custom i18n.js setup
- Deleting the .next folder (Next.js cache)
- Restarting the dev server
After that, the interceptors worked again.
If you want to try a more minimal fix, I recommend:
- Ensure next-i18next.config.mjs exports only the i18n config β avoid other settings or duplications.
- Import it cleanly into next.config.js.
- Make sure locales match in both files.
- Test navigation with and without locale prefixes in components.
π‘ Tip: If routing doesnβt behave as expected in Next.js, try deleting the .next folder. Cached data there can cause subtle and hard-to-diagnose bugs.
π§ What you can learn
- When navigation silently fails in a localized Next.js app, check your config files β not just your components.
- Don't assume the issue is in the app folder if the structure looks correct.
- Inconsistent or duplicated i18n config can silently break routing.
- Delete .next if all else fails β caching is sneaky.
π app folder structure
app/
βββ favicon.ico
βββ globals.css
βββ layout.tsx
βββ (dashboard)/
βββ (root)/
β βββ layout.tsx
β βββ page.tsx
β βββ @modal/
β β βββ default.tsx
β β βββ (.)product/
β β β βββ [id]/
β β β βββ page.tsx
β β βββ [...catchAll]/
β β βββ page.tsx
β βββ product/
β βββ [id]/
β βββ page.tsx
api/
βββ ingredients/
β βββ route.ts
βββ products/
βββ search/
βββ route.ts
β
Final thoughts
Next.js is powerful β but sometimes a single misconfigured file or leftover cache can silently break features like interceptors or routing.
If you're stuck with navigation bugs and use next-i18next, check your config, and donβt forget about .next.
Top comments (0)