Build a fullstack blog with the Next.js 16 App Router, Prisma, Sign in with Vercel, and Prisma Postgres from the Vercel Marketplace. The app starts with hardcoded content, then adds a managed Postgres database, Vercel account authentication, Server Actions, drafts, publishing, and deployment to Vercel.
To follow this tutorial, you need:
- Node.js 20.19 or later
- A Vercel account
- A GitHub account
- npm, which is included with Node.js
Create a Next.js 16 project from the starter repository:
Move into the project and start the development server:
Open http://localhost:3000. The starter app uses the App Router and renders a hardcoded blog feed from lib/posts.ts.
The starter uses these files:
app/layout.tsx: The root layout and navigationapp/page.tsx: The public feed pageapp/posts/[id]/page.tsx: The post detail pagecomponents/post-card.tsx: The post preview componentlib/posts.ts: Temporary hardcoded post data
You will replace the hardcoded data with Prisma Postgres and Prisma ORM in the next steps.
Use Prisma Postgres, a serverless Postgres provider in the Vercel Marketplace, as the database for this app.
First, create a GitHub repository for your project and push the starter code:
Then create a Vercel project from that repository. After the project exists, open the Storage tab in the Vercel dashboard and select the Connect Database button. Choose Prisma from the Marketplace providers.
Connect the database to the Vercel project. The Prisma integration adds a database environment variable to the project:
DATABASE_URL: The connection string for application queries
For Prisma schema commands, you can optionally set DIRECT_URL to a direct connection string copied from Prisma Console. If DIRECT_URL is not set, this guide falls back to DATABASE_URL.
Install the Vercel CLI and pull the Vercel project environment variables into your local project:
Your local .env file now contains the database connection strings that Prisma and the app will use.
Install Prisma, Prisma Client, the pg adapter for Prisma, and dotenv:
Add a postinstall script to package.json so Prisma Client is generated during installs and Vercel builds:
Create a prisma directory and add prisma/schema.prisma:
Prisma 7 configures database connection strings in prisma.config.ts instead of the datasource block. Create prisma.config.ts in the project root:
The Prisma CLI uses DIRECT_URL when you provide it because schema commands should use a direct database connection. The application uses DATABASE_URL through the Prisma pg adapter.
Update .gitignore so the generated Prisma Client is not committed:
Push the schema to Prisma Postgres and generate Prisma Client:
Create lib/prisma.ts to instantiate Prisma Client with the Prisma pg adapter:
Replace the hardcoded feed with a Prisma query.
Update components/post-card.tsx:
Update app/page.tsx:
Update app/posts/[id]/page.tsx:
You can add sample data in Prisma Studio:
Create a User with a placeholder vercelId, such as demo-user, then create a published Post and connect it to that user. Refresh http://localhost:3000 to see the database-backed feed.
Sign in with Vercel lets users authenticate with their Vercel account. The app will redirect users to Vercel's authorization endpoint, exchange the returned code for tokens, verify the ID Token, and store the access token in an HTTP-only cookie.
Install jose to verify the ID Token signature:
Create a Sign in with Vercel App in the Vercel dashboard:
- Open your team's Settings page.
- Select Apps.
- Select the Create button.
- Enter an app name and slug.
- Select the Save button.
- Generate a client secret.
- Add
http://localhost:3000/api/auth/callbackto Authorization Callback URLs. - Enable the
openid,email, andprofilescopes in Permissions.
Add the App credentials to .env:
Create app/api/auth/authorize/route.ts to start the OAuth flow:
Create app/api/auth/callback/route.ts to exchange the authorization code for tokens and sync the Vercel user into Prisma Postgres:
Create lib/auth.ts to read the access token cookie, request Vercel user info, and return the matching database user:
Create app/api/auth/signout/route.ts to revoke the access token and clear the cookie:
Create app/auth/error/page.tsx for failed sign-in attempts:
Update app/layout.tsx to show login, logout, draft, and new post controls:
Restart the development server and select the Sign in with Vercel button. After Vercel redirects back to the app, the callback route creates or updates the user record in Prisma Postgres through Prisma.
Server Actions let your forms mutate data without creating separate API Route files.
Create app/actions.ts:
Create app/create/page.tsx:
Create app/drafts/page.tsx:
Update app/posts/[id]/page.tsx so authors can publish and delete their posts:
Add the form and button styles to app/globals.css:
Restart the development server, sign in with Vercel, create a draft, publish it, and delete it.
Before deploying, add your production callback URL to the Sign in with Vercel App in the Vercel dashboard:
In the Vercel dashboard, confirm that your project has these environment variables:
DATABASE_URLDIRECT_URL(optional, for Prisma schema commands)NEXT_PUBLIC_VERCEL_APP_CLIENT_IDVERCEL_APP_CLIENT_SECRET
If you connected Prisma Postgres from the Storage tab, Vercel adds DATABASE_URL for you. Add the Sign in with Vercel variables from the App's Manage page before deploying. If you use a direct connection string from Prisma Console, add it as DIRECT_URL.
Commit and push your changes:
Create a deployment from the Vercel dashboard or with the Vercel CLI:
After the deployment completes, open the production URL and test the Sign in with Vercel flow.
You built and deployed a fullstack blog with Next.js 16, the App Router, Prisma, Sign in with Vercel, Prisma Postgres, and Vercel. The final example app is available in the `final` branch of the example repository.