Lovable apps use React Router (react-router-dom) inside a single BrowserRouter. Most routing bugs come from a second router, plain <a> tags that reload the page, routes defined outside <Routes>, or a missing package. Fix them by keeping one BrowserRouter in main.tsx, using <Link> and useNavigate, and declaring every route in App.tsx. If routes 404 only after a page refresh, that is a hosting fallback issue, covered separately.
| Fact | Value |
|---|---|
| Tool | Lovable |
| Difficulty | Intermediate |
| Time required | ~10 min |
| Compatibility | All Lovable versions (React Router v6+) |
| Last updated | October 2026 |
Routing error or hosting error? Check this first
Two different problems look alike:
- The route breaks inside the app (blank page, wrong component, full reload on click). That is a React Router problem: follow this guide.
- The route works when you click a link but returns 404 when you refresh or open the URL directly. That is a server fallback problem on your host (Netlify, Vercel or a custom domain). Follow the guide to fix 404 errors on page refresh in Lovable instead.
Routing checklist for Lovable projects
| Check | What good looks like |
|---|---|
| One router | Exactly one <BrowserRouter> in main.tsx, none in components |
| All routes declared | Every page is a <Route path=... element=...> inside <Routes> in App.tsx |
| Internal links | <Link to="/pricing"> everywhere, never <a href="/pricing"> |
| Redirects | const navigate = useNavigate(); navigate('/dashboard') after async work |
| Catch-all | <Route path="*" element={<NotFound />} /> as the last route |
| Package | react-router-dom listed in package.json dependencies |
Building deeper navigation? See nested routes in Lovable and dynamic routes without errors.
Why routing breaks in Lovable React Router projects
Lovable generates single-page applications (SPAs) that use React Router for navigation. Instead of loading a new HTML page for each URL, React Router intercepts navigation and swaps out components on the client side. This gives you fast, smooth transitions — but it also means routing must be configured correctly in your React code. The most common routing issue is using standard HTML anchor tags (<a href="/about">) instead of React Router's Link component. An anchor tag causes a full page reload, which bypasses React Router entirely and can lead to flash-of-blank-content or lost application state. React Router's Link component navigates without reloading the page. Another frequent problem is the route definition structure. React Router v6 (which Lovable uses) requires routes to be defined inside a Routes wrapper component. Each Route specifies a path and the component to render. If routes are defined incorrectly — for example, nesting Route components without an Outlet in the parent — child routes will not render. Lovable's AI sometimes generates routing code that mixes v5 and v6 syntax, leading to confusing errors.
- Using HTML <a> tags instead of React Router's <Link> component for internal navigation
- Missing BrowserRouter wrapper in main.tsx or App.tsx
- Route path definitions that do not match the URLs being navigated to
- Mixing React Router v5 syntax (Switch, component prop) with v6 (Routes, element prop)
- Missing Outlet component in parent routes, causing nested child routes to not render
Error messages you might see
Failed to resolve import "react-router-dom" from "src/main.jsx". Does the file exist?The react-router-dom package is not installed in your project. This happens with new projects or after dependency cleanup. Ask Lovable to add react-router-dom to the project dependencies.
useNavigate() may be used only in the context of a <Router> componentYou are calling useNavigate (or useParams, useLocation) outside of a BrowserRouter wrapper. Make sure BrowserRouter wraps your entire App component in main.tsx.
No routes matched location "/some-path"React Router could not find a Route definition matching the URL. Check your route paths — they must start with / and match exactly. If you see this on refresh, it may also be a hosting SPA fallback issue (see the fixing-404-errors page).
[Switch] is not exported from 'react-router-dom'Your code uses React Router v5 syntax, but Lovable installs v6. In v6, Switch was replaced by Routes, and the component prop on Route was replaced by element. Update the syntax accordingly.
Before you start
- A Lovable project with react-router-dom installed (Lovable adds this by default for multi-page apps)
- At least two page components to navigate between (e.g., Home and About)
- Understanding that Lovable apps are SPAs — all navigation happens on the client side without full page reloads
How to fix it
Ensure BrowserRouter wraps your app in main.tsx
BrowserRouter provides the routing context that all React Router hooks and components depend on
Open main.tsx (the entry point of your Lovable project). Check that the App component is wrapped in BrowserRouter. If it is missing, the entire routing system will not work and any hook like useNavigate or useParams will throw an error. Lovable usually adds this automatically, but it can be lost during refactors.
// main.tsx — missing BrowserRouterimport React from "react";import ReactDOM from "react-dom/client";import App from "./App";import "./index.css";ReactDOM.createRoot(document.getElementById("root")!).render( <React.StrictMode> <App /> </React.StrictMode>);// main.tsx — BrowserRouter wrapping the appimport React from "react";import ReactDOM from "react-dom/client";import { BrowserRouter } from "react-router-dom";import App from "./App";import "./index.css";ReactDOM.createRoot(document.getElementById("root")!).render( <React.StrictMode> <BrowserRouter> <App /> </BrowserRouter> </React.StrictMode>);Expected result: No more 'useNavigate may be used only in the context of a Router' errors. Route components render correctly.
Define routes using React Router v6 syntax
Lovable uses React Router v6 which has different syntax from v5 — mixing them causes build errors
In your App.tsx, define routes inside a Routes component. Each Route takes a path prop and an element prop (not component, which was v5). The path defines the URL and element defines the React component to render. For a catch-all 404 page, use path="*". If Lovable generated v5-style code with Switch or component=, update it to v6 syntax.
// App.tsx — React Router v5 syntax (broken in Lovable)import { Switch, Route } from "react-router-dom";import Home from "./pages/Home";import About from "./pages/About";const App = () => ( <Switch> <Route exact path="/" component={Home} /> <Route path="/about" component={About} /> </Switch>);// App.tsx — React Router v6 syntax (correct for Lovable)import { Routes, Route } from "react-router-dom";import Home from "./pages/Home";import About from "./pages/About";import NotFound from "./pages/NotFound";const App = () => ( <Routes> <Route path="/" element={<Home />} /> <Route path="/about" element={<About />} /> <Route path="*" element={<NotFound />} /> </Routes>);Expected result: Navigation between pages works correctly. The URL changes and the correct page component renders without a full page reload.
Replace anchor tags with Link components for internal navigation
HTML anchor tags cause full page reloads, which break SPA navigation and lose application state
Search your components for <a href="/..."> tags that link to internal pages. Replace them with React Router's Link component, which navigates on the client side without reloading the page. Import Link from react-router-dom. For styled navigation using shadcn/ui buttons, use the asChild pattern with Link inside a Button. This preserves the button styling while using client-side navigation.
// Navbar.tsx — using HTML anchors (causes full reload)const Navbar = () => ( <nav className="flex gap-4 p-4"> <a href="/">Home</a> <a href="/about">About</a> <a href="/dashboard">Dashboard</a> </nav>);// Navbar.tsx — using React Router Link (SPA navigation)import { Link } from "react-router-dom";const Navbar = () => ( <nav className="flex gap-4 p-4"> <Link to="/" className="hover:underline">Home</Link> <Link to="/about" className="hover:underline">About</Link> <Link to="/dashboard" className="hover:underline">Dashboard</Link> </nav>);Expected result: Clicking navigation links changes the URL and renders the new page instantly without a white flash or full page reload.
Use useNavigate for programmatic navigation
Sometimes you need to redirect users after an action (form submit, login) rather than on a click
Import the useNavigate hook from react-router-dom. Call it inside your component to get a navigate function, then call navigate('/path') to redirect. This is commonly used after form submissions, successful login, or completing a multi-step flow. Make sure the component using useNavigate is rendered inside the BrowserRouter context. If you need to handle complex redirect flows across multiple generated components, RapidDev's engineers have solved this pattern across 600+ Lovable projects.
// LoginForm.tsx — using window.location (breaks SPA)const handleLogin = async () => { await supabase.auth.signInWithPassword({ email, password }); window.location.href = "/dashboard"; // Full page reload — loses all React state};// LoginForm.tsx — using useNavigate (preserves SPA state)import { useNavigate } from "react-router-dom";const LoginForm = () => { const navigate = useNavigate(); const handleLogin = async () => { const { error } = await supabase.auth.signInWithPassword({ email, password }); if (!error) { navigate("/dashboard"); // Client-side redirect, no reload } };};Expected result: After login, the user is redirected to /dashboard without a page reload. Application state and auth context are preserved.
Complete code example
1import { Routes, Route } from "react-router-dom";2import { Toaster } from "@/components/ui/toaster";3import Navbar from "@/components/Navbar";4import Home from "@/pages/Home";5import About from "@/pages/About";6import Dashboard from "@/pages/Dashboard";7import NotFound from "@/pages/NotFound";89// Standard Lovable App.tsx with correct React Router v6 routing10const App = () => {11 return (12 <div className="min-h-screen bg-background">13 {/* Navbar is outside Routes so it appears on every page */}14 <Navbar />1516 {/* All routes defined inside a single Routes wrapper */}17 <Routes>18 <Route path="/" element={<Home />} />19 <Route path="/about" element={<About />} />20 <Route path="/dashboard" element={<Dashboard />} />21 {/* Catch-all route for 404 pages */}22 <Route path="*" element={<NotFound />} />23 </Routes>2425 {/* Toast notifications available on all pages */}26 <Toaster />27 </div>28 );29};3031export default App;Best practices to prevent this
- Always use Link from react-router-dom for internal navigation — never use HTML <a> tags for links within your app
- Keep BrowserRouter in main.tsx wrapping the entire App component — do not nest multiple BrowserRouter instances
- Use React Router v6 syntax (Routes, Route with element prop) since Lovable installs v6 by default
- Add a catch-all Route with path="*" that renders a NotFound component for unmatched URLs
- Place shared layout components (Navbar, Footer) outside the Routes wrapper so they appear on every page
- Use useNavigate for programmatic redirects after actions like form submissions or login
- For nested routes, use Outlet in the parent layout component to render child route content
- Test navigation by clicking through all links and also by typing URLs directly in the browser address bar
Still stuck?
Copy one of these prompts to get a personalized, step-by-step explanation.
My Lovable (lovable.dev) project has routing issues with React Router. The project uses Vite + React + TypeScript + React Router v6. Here is my current App.tsx with route definitions: [paste your App.tsx here] And here is my main.tsx: [paste your main.tsx here] The problem is: [describe what happens — wrong page renders, blank page, error message] Please: 1. Check if BrowserRouter is correctly wrapping the app 2. Verify all routes use v6 syntax (Routes/Route with element, not Switch/component) 3. Check for any Link vs anchor tag issues 4. Show me the corrected files
My app's navigation is broken. Please check @src/App.tsx and @src/main.tsx to verify that BrowserRouter is wrapping the app in main.tsx, all routes use React Router v6 syntax with Routes and Route element prop (not Switch or component), and all internal navigation uses Link from react-router-dom instead of HTML anchor tags. Fix any issues you find and add a catch-all 404 route if one is missing.
Frequently asked questions
Does Lovable use React Router?
Yes. Lovable generates projects with React Router v6 and BrowserRouter for client-side routing. Routes are defined in App.tsx using the Routes and Route components, and navigation uses the Link component and useNavigate hook.
How do I fix 'Failed to resolve import react-router-dom' in Lovable?
This means the react-router-dom package is not installed. Ask Lovable in Agent Mode: 'Add react-router-dom to the project dependencies.' Lovable will update package.json and install the package automatically.
What version of React Router does Lovable use?
Lovable uses React Router v6. This version uses Routes instead of Switch, element instead of component on Route, and requires useNavigate instead of useHistory. If you see v5 syntax in your code, it needs to be updated.
Why does Lovable reload the whole page when I click a link?
The link is a plain <a href> tag. Replace it with React Router's <Link to> component so navigation stays inside the single-page app and state is kept.
How do I redirect after form submission in Lovable?
Import useNavigate from react-router-dom and call navigate('/target-page') after your form submission logic completes. Do not use window.location.href, which causes a full page reload and loses React state.
Why do my routes work on click but show 404 on page refresh?
That is a hosting fallback issue, not a React Router bug: the server does not know your client-side routes. Follow our guide to fix 404 errors on page refresh in Lovable.
What if I can't fix routing issues myself?
Routing problems that involve nested routes, dynamic parameters, protected routes, and redirect logic across multiple components can be tricky. RapidDev's engineers have set up routing architectures across 600+ Lovable projects and can resolve complex routing issues efficiently.
How do I add a new page to a Lovable app without breaking navigation?
Ask Lovable to create the page component and register it as a <Route> inside the existing <Routes> block in App.tsx, then link to it with <Link>. Tell it not to add a second BrowserRouter.
Talk to an Expert
Our team has built 1,000+ apps. Get personalized help with your issue.
Book a free consultation