Skip to main content
RapidDev - Software Development Agency
lovable-issues

Resolving Routing Issues in Lovable with React Router

Lovable uses React Router with BrowserRouter for client-side navigation. To set up routing correctly, wrap your app in BrowserRouter in main.tsx, define routes with Route components inside a Routes wrapper, use the Link component (not anchor tags) for internal navigation, and use the useNavigate hook for programmatic redirects. If you see 'Failed to resolve import react-router-dom,' ask Lovable to add the package to your project.

Book a free consultation
4.9Clutch rating
600+Happy partners
17+Countries served
190+Team members
Intermediate9 min read~10 minAll Lovable versions (React Router v6+)March 2026RapidDev Engineering Team
TL;DR

Lovable uses React Router with BrowserRouter for client-side navigation. To set up routing correctly, wrap your app in BrowserRouter in main.tsx, define routes with Route components inside a Routes wrapper, use the Link component (not anchor tags) for internal navigation, and use the useNavigate hook for programmatic redirects. If you see 'Failed to resolve import react-router-dom,' ask Lovable to add the package to your project.

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> component

You 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

1

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.

Before
typescript
// main.tsx — missing BrowserRouter
import 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>
);
After
typescript
// main.tsx — BrowserRouter wrapping the app
import 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.

2

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.

Before
typescript
// 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>
);
After
typescript
// 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.

3

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.

Before
typescript
// 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>
);
After
typescript
// 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.

4

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.

Before
typescript
// 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
};
After
typescript
// 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

src/App.tsx
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";
8
9// Standard Lovable App.tsx with correct React Router v6 routing
10const App = () => {
11 return (
12 <div className="min-h-screen bg-background">
13 {/* Navbar is outside Routes so it appears on every page */}
14 <Navbar />
15
16 {/* 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>
24
25 {/* Toast notifications available on all pages */}
26 <Toaster />
27 </div>
28 );
29};
30
31export 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.

ChatGPT Prompt

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

Lovable Prompt

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 my Lovable app reload the whole page when I click a link?

You are using an HTML anchor tag (<a href>) instead of React Router's Link component. Anchor tags cause a full browser reload. Replace them with <Link to="/path"> from react-router-dom to get smooth client-side navigation.

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?

This is a hosting-level issue, not a React Router code issue. When you refresh, the browser requests the URL from the server, which does not know about your React routes. You need to configure SPA fallback routing on your hosting platform. See our guide on fixing 404 errors on page refresh.

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.

RapidDev

Talk to an Expert

Our team has built 600+ apps. Get personalized help with your issue.

Book a free consultation

Need help with your Lovable project?

Our experts have built 600+ apps and can solve your issue fast. Book a free consultation — no strings attached.

Book a free consultation

We put the rapid in RapidDev

Need a dedicated strategic tech and growth partner? Discover what RapidDev can do for your business! Book a call with our team to schedule a free, no-obligation consultation. We'll discuss your project and provide a custom quote at no cost.