Most Lovable apps are Vite + React + TypeScript + Tailwind + shadcn/ui with React Router and a Supabase backend. Converting to Next.js means swapping Vite for the Next App Router, moving React Router routes to the app/ directory, renaming VITE_ environment variables to NEXT_PUBLIC_, and deciding which data fetching moves to Server Components. Use the paste-ready conversion prompt below with an AI coding assistant (Cursor, Claude, or Lovable's Code tab) after you export the codebase, then work file-by-file. The gotchas are env-var prefixes, client-only browser APIs, and Supabase auth on the server.
| Fact | Value |
|---|---|
| Tool | Lovable |
| Difficulty | Advanced |
| Time required | ~1-2 days |
| Compatibility | Lovable projects on the Vite + React stack (and, with adjustments, TanStack Start projects) |
| Last updated | September 2026 |
Why convert a Lovable app to Next.js — and what actually changes
Lovable is excellent for going from idea to working app fast. But teams outgrow the default stack when they need server-side rendering for SEO, server-side data fetching, API routes co-located with the app, or simply a codebase that matches the rest of their Next.js infrastructure. That is when 'lovable to next.js conversion prompt' becomes a real search: people want a repeatable way to move the code across. Start by knowing your starting point. Apps created before mid-2026 are Vite single-page apps using React Router (BrowserRouter). Newer Lovable projects may already be on TanStack Start with SSR, which shortens the routing and data-fetching work. Either way, the backend is Supabase, and that part largely carries over unchanged — you keep the same database, auth, and storage, and only change how the frontend talks to them. The conversion itself is mechanical but detail-heavy: scaffold a Next.js App Router project, port components (they mostly move as-is because React, Tailwind, and shadcn/ui all work in Next), translate React Router routes into the app/ folder's file-based routing, rename environment variables from the VITE_ prefix to NEXT_PUBLIC_ (or drop the prefix for server-only secrets), and move any data fetching you want on the server into Server Components or Route Handlers. The prompt below drives an AI assistant through exactly these steps so you are reviewing diffs, not rewriting from scratch.
- SEO needs server-side rendering that a Vite SPA does not provide out of the box
- The team wants server-side data fetching, API routes, or Server Actions co-located with the app
- The codebase needs to match existing Next.js infrastructure and tooling
- React Router routes must be re-expressed as Next's file-based app/ routing
- Environment variables use the VITE_ prefix, which Next.js does not read
Error messages you might see
process.env.NEXT_PUBLIC_SUPABASE_URL is undefined after conversionLovable uses VITE_SUPABASE_URL. In Next.js, client-exposed vars must be prefixed NEXT_PUBLIC_. Rename the variables in .env.local and update every reference.
"window is not defined" / "document is not defined" during next buildVite SPAs run everything in the browser. In Next.js, components render on the server by default. Move browser-only code into a component marked "use client" or into a useEffect.
React Router routes 404 in Next.jsNext uses file-based routing, not <Routes>/<Route>. Each route must become a folder with a page.tsx under app/. Delete BrowserRouter and translate the route table into the app/ directory.
Before you start
- Your Lovable codebase exported (GitHub two-way sync, or Download codebase on a paid plan)
- Node.js 18+ locally and an AI coding assistant (Cursor, Claude, or Lovable's Code tab)
- Your Supabase project URL and keys (the backend does not change)
- A new empty git branch to convert into, so you can diff against the original
How to fix it
Export the Lovable codebase and scaffold a Next.js App Router project
You need the source locally and a clean Next.js target to move files into
Export via GitHub sync (GitHub icon -> Connect project) or Download codebase on a paid plan. Then scaffold the target: create a new Next.js app with the App Router, TypeScript, and Tailwind. Copy your src/components and shadcn/ui components across first — they move almost unchanged because React, Tailwind, and shadcn/ui all run in Next.
// Lovable: Vite entry// src/main.tsx -> ReactDOM.createRoot + <BrowserRouter>npx create-next-app@latest my-app --typescript --tailwind --app# then copy src/components/** into the new projectExpected result: A running Next.js project with your components present and Tailwind styling intact.
Translate React Router routes into the app/ directory
Next.js uses file-based routing; the React Router route table has no equivalent at runtime
For each <Route path="/x" element={<X/>} />, create app/x/page.tsx that renders the same component. Nested routes become nested folders; dynamic segments like /orders/:id become app/orders/[id]/page.tsx. Move the shared shell (providers, layout chrome) into app/layout.tsx. Remove BrowserRouter, Routes, and Route entirely, and replace React Router's Link/useNavigate with next/link and next/navigation.
<Route path="/orders/:id" element={<OrderDetail/>} />// app/orders/[id]/page.tsxexport default function OrderDetail({ params }: { params: { id: string } }) { /* ... */ }Expected result: Every route resolves through the app/ directory and navigation works with next/link.
Rename environment variables and re-wire the Supabase client
Next.js does not read VITE_ variables, and server code should use non-public secrets
In .env.local, rename VITE_SUPABASE_URL -> NEXT_PUBLIC_SUPABASE_URL and VITE_SUPABASE_PUBLISHABLE_KEY -> NEXT_PUBLIC_SUPABASE_ANON_KEY. Keep any service-role key server-only with no NEXT_PUBLIC_ prefix. Create a browser client for "use client" components and a server client for Server Components/Route Handlers. The Supabase database, auth, and storage themselves do not change — only how the frontend connects.
const url = import.meta.env.VITE_SUPABASE_URL;const url = process.env.NEXT_PUBLIC_SUPABASE_URL!;Expected result: The app connects to the same Supabase backend, with public keys on the client and secrets kept server-side.
Decide what moves to the server, and fix client-only code
SSR is the reason to convert, but browser-only code breaks when it runs on the server
Move data fetching you want server-rendered into Server Components (async components that call the Supabase server client) or Route Handlers under app/api. Mark interactive components with "use client". Wrap any window/document/localStorage access in a useEffect or a client component. For Supabase auth, use the SSR-aware pattern (cookie-based sessions) so the server can read the user. This is where a conversion earns its SEO and performance benefits. If your app has complex auth or real-time features and you want the migration done cleanly, RapidDev migrates Lovable apps to production Next.js codebases — someone converting out of Lovable usually needs engineering help exactly here.
// Vite SPA: all data fetched in the browser via useEffect// app/page.tsx (Server Component)export default async function Page() { const supabase = createServerClient(); const { data } = await supabase.from('orders').select('*'); return <OrdersTable rows={data ?? []} />;}Expected result: Pages render on the server with data present in the initial HTML, and interactive parts still work as client components.
Complete code example
1# Paste-ready conversion prompt23You are converting a Lovable app (Vite + React + TypeScript + Tailwind +4shadcn/ui, React Router, Supabase backend) to Next.js (App Router).5Work in small, reviewable steps and pause after each for my approval.67## Do this in order81. Inventory the project: list every React Router route (path -> component)9 and every file that reads import.meta.env. Do not change code yet.102. Scaffold routing: for each route, create app/<path>/page.tsx rendering the11 same component. Convert dynamic params (:id) to [id]. Move providers and12 shared layout into app/layout.tsx. Remove BrowserRouter/Routes/Route.13 Replace react-router Link/useNavigate with next/link and next/navigation.143. Environment: rename VITE_SUPABASE_URL -> NEXT_PUBLIC_SUPABASE_URL and15 VITE_SUPABASE_PUBLISHABLE_KEY -> NEXT_PUBLIC_SUPABASE_ANON_KEY. Replace16 every import.meta.env.X with process.env.X. Keep any service-role key17 server-only (no NEXT_PUBLIC_ prefix).184. Supabase clients: create a browser client for 'use client' components and19 an SSR/server client (cookie-based) for Server Components and Route20 Handlers. Do not change the database schema, auth, or storage.215. Server vs client: mark interactive components 'use client'. Move data22 fetching that should be server-rendered into async Server Components or23 app/api Route Handlers. Wrap any window/document/localStorage access in a24 client component or useEffect.256. Build: run next build, fix every 'window is not defined' and missing-env26 error, and report what changed.2728## Constraints29- Do not change the Supabase database, RLS policies, or auth provider.30- Keep all existing UI and shadcn/ui components; do not restyle.31- After each step, list the files you created or modified.3233Start with step 1 and wait for my confirmation.Best practices to prevent this
- Convert on a fresh branch so you can diff every change against the original Vite app
- Do it in steps (routing, env, clients, server/client split) and build after each — never in one giant prompt
- Keep the Supabase backend untouched; only change how the frontend connects to it
- Rename VITE_ vars to NEXT_PUBLIC_ for client use and keep secrets server-only with no public prefix
- Use the SSR-aware (cookie-based) Supabase auth pattern so Server Components can read the user
- Move only the data fetching that benefits from SSR to the server; leave interactive bits as client components
- Run next build early and often — most conversion bugs surface as 'window is not defined' or undefined env vars
Still stuck?
Copy one of these prompts to get a personalized, step-by-step explanation.
I'm converting a Lovable app (Vite + React + TypeScript + Tailwind + shadcn/ui, React Router, Supabase) to Next.js App Router. Given this file, rewrite it for Next.js: convert routing to the app/ directory, replace import.meta.env.VITE_* with process.env.NEXT_PUBLIC_*, and split server vs client correctly. Explain every change. Here is the file: [paste file]
Before converting, help me inventory this project for a Next.js migration: list every React Router route as path -> component, and every file that reads import.meta.env. Do not change any code yet — just produce the two lists so I can plan the conversion.
Frequently asked questions
Is there a single prompt that converts Lovable to Next.js automatically?
No single prompt does it in one shot reliably. The conversion touches routing, environment variables, data fetching, and auth, so the paste-ready prompt above drives an AI assistant through it in reviewable steps. You approve each step and fix build errors as they surface — that is far safer than one giant prompt.
Does my Supabase backend change when I move to Next.js?
No. The database, RLS policies, auth, and storage stay exactly as they are. You only change how the frontend connects: rename the env vars to the NEXT_PUBLIC_ prefix and use a server-side Supabase client in Server Components and Route Handlers.
What are the most common conversion errors?
Undefined environment variables (because Next.js ignores the VITE_ prefix), 'window is not defined' during next build (because components render on the server by default), and 404s on routes (because Next uses file-based routing instead of React Router). All three are covered in the steps above.
My Lovable app is on TanStack Start, not Vite — is this different?
Somewhat easier on routing and data fetching, since TanStack Start already does SSR. You still translate routes into Next's app/ directory and rename environment variables, but less client-only code needs rework. The same step-by-step prompt applies with minor adjustments.
Should I convert to Next.js or stay on Lovable?
Stay on Lovable while you are iterating on product and the SPA is good enough. Convert when you need SSR for SEO, server-side data fetching, or a codebase that matches your Next.js infrastructure. Weigh the one-time migration effort against ongoing Lovable credit costs.
Can RapidDev do the conversion for me?
Yes. Converting out of Lovable is exactly when teams need engineering help — auth on the server, data-fetching boundaries, and build issues are where DIY conversions stall. RapidDev migrates Lovable apps to production-grade Next.js codebases; book a free consultation at rapidevelopers.com.
Talk to an Expert
Our team has built 1,000+ apps. Get personalized help with your issue.
Book a free consultation