Claude Code Boilerplate
FeaturesPricingBlogDocs
Get started →

Product

  • Features
  • Pricing
  • Skills

Compare

  • vs ShipFast
  • vs MakerKit
  • vs supastarter

Resources

  • Docs
  • Blog
  • Discord

Legal

  • License
  • Privacy Policy
  • Terms of Service
Claude Code Boilerplate

© 2026 Claude Code Boilerplate. All rights reserved.

← All posts

How to Add a Demo Mode to Your Next.js SaaS -- Let Prospects Try Before They Sign Up

September 13, 2026
nextjssaasauthboilerplateconversion

A visitor lands on your pricing page. They are interested. They click "Start free trial" and see a signup form.

Half of them close the tab.

Not because they did not want your product -- because they were not ready to hand over an email to something they had never actually used. Demo mode solves this. Instead of a friction wall, you offer a "Try the demo" button that drops the visitor directly into a working version of your app, no signup required. They explore, get value, and convert later with far less resistance.

Here is how to build it in a Next.js SaaS.

What a Demo Account Actually Is

A demo account is a real user account with a fixed set of seeded data -- realistic records that make the product feel alive without exposing any real user data. The session is:

  • Read-only or action-limited: visitors can explore but not delete records or change billing settings
  • Shared or per-visitor: the simplest version uses one shared demo account; advanced versions create a short-lived per-visitor clone
  • Time-limited: sessions expire after 30-60 minutes via JWT expiry

The simplest version -- a shared demo account with read-only middleware -- takes an afternoon to ship.

Why This Converts Better Than a Free Trial for Some Products

Free trials work when your product's value is obvious the moment you sign up. But if your product is visual, data-dependent, or complex -- a dashboard, a CRM, an analytics tool, a project manager -- visitors need to see realistic data before they trust the promise.

Demo mode moves the "aha moment" before the signup wall. Visitors experience the product, decide they want it, and sign up already motivated. That sequence converts better than asking for commitment upfront.

The tradeoff: you invest an afternoon seeding realistic data and wiring the demo login. For most B2B SaaS products, that pays back in the first month of signups.

The Pattern: Demo Token + Middleware Gate

The cleanest implementation uses the same JWT auth layer the Next.js SaaS Boilerplate already provides, with one addition: a demo role in the token payload.

When someone clicks "Try the demo":

  1. A server action issues a short-lived JWT with { role: 'demo', userId: '<demo-user-id>' }
  2. The token is stored as a cookie, the same way a normal auth session works
  3. Middleware reads the role flag and blocks mutating routes for demo sessions
  4. The visitor lands inside the real app with seeded data visible

Every read-only feature works. Write actions show a polite "Sign up to save changes" prompt instead of silently failing.

For more on how the JWT layer is structured, see JWT auth in Next.js App Router without NextAuth.

Seeding Demo Data With Drizzle

Your demo is only as compelling as the data inside it. Empty tables do not show value -- realistic records do. Add a seed script that runs after migrations:

// db/seed-demo.ts
const DEMO_USER_ID = 'demo-user-fixed-id'
 
await db.insert(projectTable).values([
  { id: DEMO_PROJECT_ID, name: 'Q4 Campaign', userId: DEMO_USER_ID },
  { id: uuid(), name: 'Website Redesign', userId: DEMO_USER_ID },
])
// Keep this idempotent -- check if demo user exists before inserting

Run it with npx tsx db/seed-demo.ts after each migration. Keep it idempotent so re-runs on Vercel preview deploys do not duplicate records.

Blocking Writes in Middleware

The guard is three lines in your existing middleware.ts:

const isDemo = payload?.role === 'demo'
const isMutation = ['POST', 'PUT', 'PATCH', 'DELETE'].includes(req.method ?? '')
if (isDemo && isMutation) {
  return NextResponse.json({ error: 'Sign up to save changes' }, { status: 403 })
}

On the client side, catch 403 responses and show a toast: "You are in demo mode -- [Sign up to continue]". That single prompt, shown at the exact moment a visitor wants to take action, is one of the highest-converting touchpoints in your entire funnel. The visitor is already sold -- they just tried to do the thing they came to do.

See user impersonation in Next.js for a related pattern using the same JWT-based identity switching.

What You Already Have in the Boilerplate

The Next.js SaaS Boilerplate ships with:

  • JWT auth with cookie-based sessions
  • Drizzle ORM with full schema control for seed scripts
  • Middleware already wired to read and validate tokens
  • Sonner toasts for showing action feedback

Adding demo mode on top means one seed script, three lines in middleware, and one server action for the demo login button. No new dependencies, no separate infrastructure.

One Afternoon, Real Conversions

If your SaaS shows its value through data or a visual interface, demo mode is one of the highest-ROI changes you can make to your landing page. Most founders delay it because they assume it is complex. With the JWT and Drizzle layers already in place, it is a focused afternoon build.

Pick a realistic dataset that shows your product at its best. Wire the demo login server action. Add the "Sign up to save" prompt on mutations. Ship it.

Get the Next.js SaaS Boilerplate and have demo mode live before the end of the week.