Next.js中使用next-routes实现多语言动态路由的问题
I've run into this exact issue with next-routes before—here's what's going on and how to fix it:
Why Your Current Setup Fails
next-routes matches routes in the order you add them. Your two problematic routes:
/:lang?/:ticket/:lang?/:hotel
Have identical structural patterns: an optional language parameter followed by a single dynamic segment. When you visit /en/hotel, the router sees it matches the first rule (tickets) and treats hotel as the :ticket parameter value, hence the wrong page load.
Since you need to support dynamically added routes from a CMS, hardcoding every possible route isn't feasible. Here are two robust solutions:
Solution 1: Use a Universal Dynamic Page (Recommended for CMS-driven Routes)
This approach uses a single catch-all route to handle all language + slug combinations, then fetches content from your CMS to determine which page component to render.
Step 1: Update routes.js
Simplify your routing to only include the homepage and a universal dynamic route:
const routes = require('next-routes'); module.exports = routes() .add('index', '/:lang?') .add('dynamic-page', '/:lang?/:slug');
Step 2: Create a Universal Page Component
Make a pages/dynamic-page.js file that fetches CMS data and renders the correct component:
import { useRouter } from 'next/router'; import TicketsPage from './tickets'; import HotelPage from './hotel'; import NotFound from './404'; import useSWR from 'swr'; // Helper to fetch CMS data const fetcher = async (url) => { const res = await fetch(url); if (!res.ok) throw new Error('Failed to fetch page data'); return res.json(); }; const DynamicPage = () => { const router = useRouter(); const { lang = 'en', slug } = router.query; // Fetch page details from your CMS using slug and language const { data: pageData, error } = useSWR( slug ? `/api/cms/pages/${slug}?lang=${lang}` : null, fetcher ); if (error) return <NotFound />; if (!pageData) return <div>Loading...</div>; // Render the correct component based on CMS-defined page type switch(pageData.pageType) { case 'tickets': return <TicketsPage content={pageData.content} lang={lang} />; case 'hotel': return <HotelPage content={pageData.content} lang={lang} />; default: return <NotFound />; } }; export default DynamicPage;
Step 3: Update Your CMS API
Ensure your CMS exposes an endpoint that returns page metadata (including pageType) when given a slug and lang parameter.
Solution 2: Dynamically Generate Routes from CMS Data
If you prefer to keep separate page components (e.g., tickets.js, hotel.js) and can sync CMS routes at server startup, you can dynamically build your route rules:
Update routes.js
const routes = require('next-routes'); // Fetch route mappings from your CMS (replace with actual API call) const fetchCmsRoutes = async () => { const res = await fetch('https://your-cms-api.com/routes'); return res.json(); }; // Initialize router with homepage route const router = routes().add('index', '/:lang?'); // Dynamically add routes from CMS (async () => { const cmsRoutes = await fetchCmsRoutes(); cmsRoutes.forEach(route => { router.add(route.pageName, `/:lang?/${route.slug}`); }); })(); module.exports = router;
Note: This requires restarting your server whenever new routes are added to the CMS. For real-time route updates, Solution 1 is a better fit.
内容的提问来源于stack exchange,提问作者Javier Lopez

