Next.js中切换默认语言环境及内部页面语言切换异常问题解决
Let's break down the problems in your current code and fix them one by one:
1. Hardcoded Redirects Cause 404s on Internal Pages
Your current onChangeLanguage function pushes fixed paths ('ar' or '/'), which works fine on the homepage but breaks on internal routes like /settings/products—it ends up pointing to /settings/ar instead of the correct /ar/settings/products.
2. State Doesn't Sync with Router Locale
You initialize the language state with router.locale, but when the router's locale changes after switching languages, the state doesn't update automatically. This leads to incorrect checkbox checked states.
3. Switching Back to Default Language Fails
When switching from Arabic to English on internal Arabic pages (like /ar/settings/location/edit/<UUID>), you need to properly remove the locale prefix instead of pushing /.
Updated NavBar Component Code
Here's the fixed version of your component:
import { useRouter } from "next/router" import { useTranslation } from 'next-i18next' import { useState, useEffect } from 'react' const NavBar = ({...props}) => { const router = useRouter() const { t } = useTranslation('navbar'); const [language, setLanguage] = useState(router.locale) // Sync state with router locale changes useEffect(() => { setLanguage(router.locale) }, [router.locale]) const onChangeLanguage = (targetLocale) => (e) => { e.preventDefault() // Get current route details to preserve the page path const { pathname, query } = router // Let Next.js handle locale routing automatically router.push({ pathname, query }, undefined, { locale: targetLocale }) } return ( <> {/* ... your existing NavBar content ... */} <div className="form-check form-check-inline"> <input type="checkbox" className="form-check-input" id="en" onClick={onChangeLanguage('en')} value="en" checked={language === 'en'} // Use controlled state for accurate checkbox status /> <label className="form-check-label" htmlFor="en">English</label> </div> <div className="form-check form-check-inline"> <input type="checkbox" className="form-check-input" id="ar" onClick={onChangeLanguage('ar')} value="ar" checked={language === 'ar'} /> <label className="form-check-label" htmlFor="ar">Arabic</label> </div> </> ) } export default NavBar;
Key Changes Explained
- Dynamic Locale Routing: Instead of hardcoding paths, we use
router.pushwith thelocaleoption. Next.js automatically handles adding/removing the locale prefix based on your i18n config. For example:- On
/settings/products(English), switching to Arabic takes you to/ar/settings/products - On
/ar/settings/location/edit/123, switching to English takes you to/settings/location/edit/123
- On
- Sync State with Router: The
useEffectupdates thelanguagestate wheneverrouter.localechanges, ensuring checkboxes always reflect the active language. - Controlled Checkboxes: Replaced
defaultCheckedwithcheckedto make checkboxes controlled components, so their state stays in sync with the actual locale.
Quick Check for next.config.js
Ensure your i18n configuration is correctly set up in next.config.js:
module.exports = { i18n: { locales: ['en', 'ar'], defaultLocale: 'en', }, }
This approach works for all route types, including dynamic routes like edit/[...id].js, since we preserve the query object when pushing the new route.
内容的提问来源于stack exchange,提问作者Deep Kakkar

