Add new routes to a Lovable app by defining Route elements in App.tsx, creating the page component, and updating navigation links. Avoid breaking existing navigation by placing new routes before the catch-all wildcard route, using exact paths, and adding route guards for protected pages that require authentication.
Why adding new routes breaks existing navigation in Lovable
Lovable projects use React Router where route order matters. When you add a new route, it can intercept URLs meant for existing routes if the path pattern is too broad. For example, adding a route for /:anything before /dashboard means React Router matches /dashboard to the /:anything pattern instead of the specific /dashboard route. Another common issue is forgetting to update navigation components. You add the route and page component, but the sidebar or navbar still does not show a link to the new page. Users can only reach it by typing the URL directly. Protected routes add another layer. If the new page requires authentication but you do not wrap it in a route guard, unauthenticated users see broken or empty pages instead of being redirected to the login page.
- Route placed after the wildcard (*) catch-all — React Router never reaches it because * matches everything
- Broad path pattern intercepts existing routes — /:param matches /dashboard before the specific route can
- Navigation component not updated — no link to the new page exists in the sidebar or navbar
- Missing route guard — the new page requires auth but renders without checking session state
- Duplicate path definition — two routes with the same path cause unpredictable behavior
Error messages you might see
No routes matched location "/new-page"The Route definition for /new-page is missing from App.tsx. Add a Route element with path='/new-page' and the corresponding page component.
Existing page now shows a different component after adding a routeYour new route's path pattern is broader than the existing route, intercepting its URLs. Place specific paths before general patterns in your route list.
Navigation link does not highlight as active on the new pageThe NavLink or Link component uses a hardcoded check that does not include the new path. Update the active state logic to include the new route.
Before you start
- A Lovable project with React Router already configured (default for all Lovable projects)
- The page component you want to add (or you will create one)
- An understanding of which existing routes should be protected and which are public
How to fix it
Create the new page component
The Route element needs a component to render — create the page file first
Create the new page component
The Route element needs a component to render — create the page file first
Create a new file in src/pages/ for your page component. Follow the existing naming pattern in your project. Include a basic layout with a heading and placeholder content. If the page needs data, add loading and error states from the start.
1// src/pages/Pricing.tsx2export default function Pricing() {3 return (4 <div className="container mx-auto p-8">5 <h1 className="text-3xl font-bold mb-6">Pricing</h1>6 <p className="text-muted-foreground">Choose the plan that works for you.</p>7 </div>8 );9}Expected result: A new page component file exists in src/pages/ ready to be connected to a route.
Add the Route definition in App.tsx before the catch-all
React Router evaluates routes top to bottom — the catch-all (*) must be last or it will intercept all URLs
Add the Route definition in App.tsx before the catch-all
React Router evaluates routes top to bottom — the catch-all (*) must be last or it will intercept all URLs
Open src/App.tsx and add your new Route element inside the Routes block. Place it before any wildcard (*) catch-all route and after any more specific routes that share a similar path prefix. Import the page component at the top of the file.
<Routes> <Route path="/" element={<Index />} /> <Route path="/dashboard" element={<Dashboard />} /> <Route path="*" element={<NotFound />} /></Routes>import Pricing from "./pages/Pricing";<Routes> <Route path="/" element={<Index />} /> <Route path="/dashboard" element={<Dashboard />} /> <Route path="/pricing" element={<Pricing />} /> {/* Catch-all must be last */} <Route path="*" element={<NotFound />} /></Routes>Expected result: Visiting /pricing renders the Pricing component. All existing routes continue working as before.
Add a protected route wrapper for authenticated pages
Pages that require login should redirect unauthenticated users to the sign-in page instead of showing broken content
Add a protected route wrapper for authenticated pages
Pages that require login should redirect unauthenticated users to the sign-in page instead of showing broken content
If your new page requires authentication, wrap it in a ProtectedRoute component. This component checks for a valid session before rendering the page and redirects to /login if no session exists.
<Route path="/settings" element={<Settings />} /><Route path="/settings" element={ <ProtectedRoute> <Settings /> </ProtectedRoute> }/>Expected result: Unauthenticated users visiting /settings are redirected to /login. Authenticated users see the Settings page.
Update navigation components with the new route
Users need a visible link to find the new page — it should appear in the sidebar or navbar
Update navigation components with the new route
Users need a visible link to find the new page — it should appear in the sidebar or navbar
Open your navigation component (usually in src/components/Sidebar.tsx or src/components/Navbar.tsx). Add a Link or NavLink element for the new route. Use NavLink instead of Link if you want automatic active-state styling when the user is on that page. If your navigation involves multiple menus, route guards, and conditional rendering based on user roles across many components, RapidDev's engineers have built these navigation patterns across 600+ Lovable projects.
<nav> <NavLink to="/" className={navLinkClass}>Home</NavLink> <NavLink to="/dashboard" className={navLinkClass}>Dashboard</NavLink></nav>import { NavLink } from "react-router-dom";<nav> <NavLink to="/" className={({ isActive }) => isActive ? "text-primary font-bold" : "text-muted-foreground"}>Home</NavLink> <NavLink to="/dashboard" className={({ isActive }) => isActive ? "text-primary font-bold" : "text-muted-foreground"}>Dashboard</NavLink> <NavLink to="/pricing" className={({ isActive }) => isActive ? "text-primary font-bold" : "text-muted-foreground"}>Pricing</NavLink></nav>Expected result: The new page appears in the navigation with active state highlighting when the user is on that page.
Complete code example
1import { BrowserRouter, Routes, Route } from "react-router-dom";2import { AuthProvider } from "@/contexts/AuthContext";3import ProtectedRoute from "@/components/ProtectedRoute";4import Layout from "@/components/Layout";5import Index from "@/pages/Index";6import Login from "@/pages/Login";7import Dashboard from "@/pages/Dashboard";8import Pricing from "@/pages/Pricing";9import Settings from "@/pages/Settings";10import NotFound from "@/pages/NotFound";1112export default function App() {13 return (14 <AuthProvider>15 <BrowserRouter>16 <Routes>17 {/* Public routes */}18 <Route path="/" element={<Index />} />19 <Route path="/login" element={<Login />} />20 <Route path="/pricing" element={<Pricing />} />2122 {/* Protected routes — require authentication */}23 <Route element={<Layout />}>24 <Route25 path="/dashboard"26 element={27 <ProtectedRoute>28 <Dashboard />29 </ProtectedRoute>30 }31 />32 <Route33 path="/settings"34 element={35 <ProtectedRoute>36 <Settings />37 </ProtectedRoute>38 }39 />40 </Route>4142 {/* Catch-all for undefined routes — must be last */}43 <Route path="*" element={<NotFound />} />44 </Routes>45 </BrowserRouter>46 </AuthProvider>47 );48}Best practices to prevent this
- Always place the catch-all Route (path='*') as the last Route inside your Routes component
- Put specific paths (/dashboard) before pattern paths (/:id) to prevent interception
- Use NavLink instead of Link for navigation items — it provides automatic active state detection
- Wrap all authenticated pages in a ProtectedRoute component that checks for a valid session
- Group related routes under a shared Layout route using Outlet for consistent page structure
- Update your AGENTS.md when you add new routes so Lovable knows about the routing structure in future sessions
- Test new routes by typing the URL directly in the browser — not just by clicking links — to verify SPA fallback works
Still stuck?
Copy one of these prompts to get a personalized, step-by-step explanation.
I have a Lovable.dev project with React Router and I need to add new routes without breaking existing navigation. Here is my current App.tsx routing: [paste your Routes block] Here is my navigation component: [paste your nav component] I need to add these new pages: - [list new pages with their paths and whether they need auth] Please help me: 1. Add the Route definitions in the correct order 2. Create a ProtectedRoute wrapper if needed 3. Update the navigation component with links to the new pages 4. Ensure existing routes are not broken
Add a new /pricing page to my app. Create @src/pages/Pricing.tsx with a pricing cards layout using shadcn/ui Card components. Add the Route definition in @src/App.tsx before the catch-all route. Add a NavLink to the pricing page in @src/components/Navbar.tsx. This page should be public — no authentication required.
Frequently asked questions
How do I add a new page to my Lovable app?
Create a page component in src/pages/, add a Route element in App.tsx with the path and component, and add a link in your navigation component. Place the new Route before the catch-all (*) route.
Why did adding a route break my existing pages?
Your new route's path pattern is likely intercepting URLs meant for existing routes. Check that specific paths come before general patterns and that the catch-all route is last. React Router evaluates routes in order.
How do I make a route require login?
Wrap the route's element in a ProtectedRoute component that checks for a valid Supabase session. If no session exists, redirect to the login page. This prevents unauthenticated users from seeing protected content.
How do I add active state to navigation links?
Use NavLink instead of Link from react-router-dom. NavLink provides an isActive parameter in the className callback: className={({ isActive }) => isActive ? 'text-primary' : 'text-muted-foreground'}.
Can I redirect from one route to another?
Yes. Use the Navigate component from react-router-dom: <Route path='/old-path' element={<Navigate to='/new-path' replace />} />. The replace prop prevents the old path from appearing in browser history.
What if I can't fix this myself?
If your app needs complex routing with nested layouts, role-based route guards, and conditional navigation across many pages, RapidDev's engineers have built these patterns across 600+ Lovable projects.
Talk to an Expert
Our team has built 600+ apps. Get personalized help with your issue.
Book a free consultation