V0 generates Next.js App Router projects that can connect to external databases through API routes and server-side data fetching. Use Neon (serverless PostgreSQL), Supabase, or Upstash Redis via V0's one-click integrations in the Connect panel, or manually configure any database by storing connection strings in the Vars panel and querying from Server Components or API routes. Never import database clients in Client Components — all database access must happen server-side.
Why connecting databases to V0 UIs requires server-side patterns
V0 generates frontend UI components, but database connections must happen server-side to protect credentials and avoid exposing your database to the browser. In Next.js App Router, you have three server-side options: Server Components that fetch data directly during rendering, API routes in app/api/ that expose REST endpoints, and Server Actions that handle form submissions. V0's Connect panel offers one-click integrations for Neon, Supabase, and Upstash that automatically configure environment variables and install the required packages. For other databases, you add the connection string to the Vars panel and import the database client in server-only files.
- Database client imported in a Client Component ("use client"), exposing connection credentials to the browser
- Connection string hardcoded in source code instead of stored in the V0 Vars panel
- Missing "use server" annotation on Server Actions that perform database mutations
- Connection pool exhaustion from creating new database connections on every request instead of reusing them
- Environment variables not set in the Vercel project settings after deploying from V0
Error messages you might see
Error: Module "pg" cannot be imported from a Client Component module. It should only be used from a Server Component.You imported a Node.js database client (like pg, prisma, or drizzle) in a file with "use client". Database clients can only run server-side. Move the query to a Server Component, API route, or Server Action.
Error: connect ECONNREFUSED 127.0.0.1:5432The database connection string points to localhost, which does not exist in Vercel's serverless environment. Use the cloud database URL from your Neon, Supabase, or other hosted database provider.
Error: Too many connections - sorry, too many clients alreadyEach serverless function invocation creates a new database connection, quickly exceeding the connection limit. Use a connection pooler like Neon's pooled connection string or Supabase's connection pooler.
Before you start
- A V0 project that needs to display or manipulate data from an external database
- A hosted database (Neon, Supabase, PlanetScale, or Upstash) with a connection string
- Access to the V0 Connect panel or Vars panel for environment variable configuration
How to fix it
Use V0's Connect panel for one-click database integration
V0's Connect panel automatically installs the database SDK, configures environment variables, and scaffolds connection utilities for supported databases. This is faster and less error-prone than manual setup.
Use V0's Connect panel for one-click database integration
V0's Connect panel automatically installs the database SDK, configures environment variables, and scaffolds connection utilities for supported databases. This is faster and less error-prone than manual setup.
Open the V0 editor and click the Connect panel. Select your database provider (Neon, Supabase, or Upstash). Follow the authentication flow to connect your account. V0 automatically adds the connection string to your environment variables and installs the required package.
// No database connection configured// After connecting Neon via Connect panel:// - @neondatabase/serverless package installed// - DATABASE_URL added to Vars panel// - Connection utility created automaticallyExpected result: The database is connected and ready to query from Server Components and API routes.
Store the database connection string in the Vars panel
Database connection strings contain credentials that must never appear in source code. The Vars panel encrypts environment variables and makes them available at runtime.
Store the database connection string in the Vars panel
Database connection strings contain credentials that must never appear in source code. The Vars panel encrypts environment variables and makes them available at runtime.
For databases not supported by V0's Connect panel, click the Vars panel and add your connection string manually. Use a name like DATABASE_URL. Access it in your code via process.env.DATABASE_URL.
// Hardcoded connection string — NEVER do thisimport { neon } from "@neondatabase/serverless";const sql = neon("postgres://user:pass@host/db");// Using Vars panel environment variableimport { neon } from "@neondatabase/serverless";const sql = neon(process.env.DATABASE_URL!);Expected result: The database connection uses encrypted credentials from environment variables.
Query the database from a Server Component
Server Components in Next.js App Router run on the server and can directly access databases without exposing any credentials to the browser. Data is fetched during rendering and sent as HTML to the client.
Query the database from a Server Component
Server Components in Next.js App Router run on the server and can directly access databases without exposing any credentials to the browser. Data is fetched during rendering and sent as HTML to the client.
Create or modify a page.tsx (which is a Server Component by default in App Router) to query your database and render the results.
// Client Component trying to query database — fails"use client";import { neon } from "@neondatabase/serverless";export function ProductList() { // This cannot run in the browser const sql = neon(process.env.DATABASE_URL!);}// Server Component — queries database during renderingimport { neon } from "@neondatabase/serverless";import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card";export default async function ProductsPage() { const sql = neon(process.env.DATABASE_URL!); const products = await sql`SELECT id, name, price FROM products ORDER BY name`; return ( <div className="grid grid-cols-1 md:grid-cols-3 gap-4 p-6"> {products.map((product) => ( <Card key={product.id}> <CardHeader> <CardTitle>{product.name}</CardTitle> </CardHeader> <CardContent> <p className="text-2xl font-bold">${product.price}</p> </CardContent> </Card> ))} </div> );}Expected result: The page renders a grid of products fetched directly from the database.
Create an API route for client-side data fetching
When Client Components need to fetch data (for search, pagination, or real-time updates), they should call an API route that queries the database server-side, rather than importing the database client directly.
Create an API route for client-side data fetching
When Client Components need to fetch data (for search, pagination, or real-time updates), they should call an API route that queries the database server-side, rather than importing the database client directly.
Create an API route in app/api/ that queries the database and returns JSON. Call it from Client Components using fetch().
// No API route — client cannot fetch data// app/api/products/route.tsimport { neon } from "@neondatabase/serverless";import { NextResponse } from "next/server";export async function GET(request: Request) { const sql = neon(process.env.DATABASE_URL!); const { searchParams } = new URL(request.url); const category = searchParams.get("category"); const products = category ? await sql`SELECT * FROM products WHERE category = ${category}` : await sql`SELECT * FROM products`; return NextResponse.json(products);}Expected result: Client Components can fetch /api/products?category=electronics to get filtered product data.
Complete code example
1import { neon } from "@neondatabase/serverless";23// Create a reusable database query function4// This file should only be imported in Server Components,5// API routes, and Server Actions — never in "use client" files67export function getDb() {8 if (!process.env.DATABASE_URL) {9 throw new Error(10 "DATABASE_URL is not set. Add it in the V0 Vars panel."11 );12 }13 return neon(process.env.DATABASE_URL);14}1516// Type-safe query helpers17export async function getProducts() {18 const sql = getDb();19 return sql`SELECT id, name, description, price, category FROM products ORDER BY name`;20}2122export async function getProductById(id: string) {23 const sql = getDb();24 const rows = await sql`SELECT * FROM products WHERE id = ${id}`;25 return rows[0] ?? null;26}2728export async function createProduct(data: {29 name: string;30 description: string;31 price: number;32 category: string;33}) {34 const sql = getDb();35 const rows = await sql`36 INSERT INTO products (name, description, price, category)37 VALUES (${data.name}, ${data.description}, ${data.price}, ${data.category})38 RETURNING *39 `;40 return rows[0];41}Best practices to prevent this
- Never import database clients in files with "use client" — all database access must happen in Server Components, API routes, or Server Actions
- Store all database credentials in the V0 Vars panel and set them in Vercel's environment variables panel before deploying
- Use V0's Connect panel for Neon, Supabase, and Upstash — it handles installation and configuration automatically
- Use connection pooling (Neon's pooled connection string or Supabase's connection pooler) to avoid exhausting connection limits in serverless environments
- Create a shared lib/db.ts utility file to centralize database connection logic and avoid duplicating connection code
- For complex database architectures involving multiple databases, migrations, and ORM setup, RapidDev can configure the complete data layer
Still stuck?
Copy one of these prompts to get a personalized, step-by-step explanation.
I need to connect my V0 Next.js App Router project to a Neon PostgreSQL database. How do I set up the connection, query data in Server Components, and create API routes for client-side fetching? I want to avoid connection pool exhaustion in serverless.
Frequently asked questions
Which databases does V0 support with one-click integration?
V0's Connect panel supports Neon (serverless PostgreSQL), Supabase (PostgreSQL with auth and storage), and Upstash (Redis and Kafka). For other databases like PlanetScale, MongoDB, or CockroachDB, add the connection string manually via the Vars panel.
Can I use Prisma or Drizzle ORM with V0?
Yes. Ask V0 to set up Prisma or Drizzle in your project. The ORM client must only be imported in server-side code (Server Components, API routes, Server Actions). Store the DATABASE_URL in the Vars panel.
Why does my database connection fail after deploying to Vercel?
The most common cause is missing environment variables. The Vars panel sets variables for the V0 preview, but you must also set them in your Vercel project settings under Environment Variables for production deployment.
How do I avoid connection pool exhaustion with serverless functions?
Use a connection pooler: Neon provides a pooled connection string (ending in -pooler.region.neon.tech), and Supabase offers a connection pooler via Supavisor. These multiplex many serverless function connections through a small pool of actual database connections.
Can RapidDev set up a complete database layer for my V0 project?
Yes. RapidDev can design and implement the full database architecture including schema design, migrations, ORM configuration, server-side query patterns, and API routes for your V0 Next.js application.
Should I use Server Components or API routes to query the database?
Use Server Components for data that is rendered directly on the page during initial load. Use API routes for data that Client Components need to fetch dynamically, such as search results, paginated lists, or form submissions.
Talk to an Expert
Our team has built 600+ apps. Get personalized help with your issue.
Book a free consultation