Demo Mode
Try ProductReady without login - explore features with sample data
Demo Mode
ProductReady includes a Demo Mode that lets you explore all features without creating an account or setting up a database. Perfect for:
- ๐ฏ Quick exploration - See features in action immediately
- ๐ฅ Demonstrations - Show your app to stakeholders
- ๐งช Testing - Try the UI and workflows without real data
- ๐ Learning - Understand how features work before implementation
No setup required! Demo mode works with mock data - no database, no authentication needed.
How to Use Demo Mode
Activate Demo Mode
Add ?demo=1 to any URL:
http://localhost:3000/dashboard?demo=1
http://localhost:3000/agent?demo=1Or use the Demo User Login on the sign-in page (see below).
What's Included in Demo Mode
When demo mode is active, you'll see:
โ Sample Data
- 5 demo agent tasks (various statuses: pending, in progress, completed, failed)
- 8 example blog posts (published and draft)
- 3 demo users
โ Full UI Access
- Dashboard with metrics
- Agent task management
- Blog post listing
- All navigation and layouts
โ Read-Only Operations
- View all demo content
- Browse and filter
- See UI interactions
โ ๏ธ Limitations
- Cannot create/edit/delete real data
- Changes show alerts but don't persist
- Database operations return mock data
Demo User Login
The sign-in page includes a "Try Demo Mode" button for instant access without credentials.
Go to Sign-In Page
Visit /sign-in or click "Sign In" from the landing page.
Click "Try Demo Mode"
Look for the blue button below the login form:
โโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ Sign in to ProductReady โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโค
โ Email: _______________ โ
โ Password: ___________ โ
โ [Sign In] โ
โ โ
โ โโโโโโโ OR โโโโโโโ โ
โ โ
โ [Try Demo Mode] โ Here โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโExplore Features
You'll be redirected to /dashboard?demo=1 with full access to demo content.
- Create agent tasks (alerts instead of saving)
- View sample blog posts
- Navigate all dashboard sections
- See how tRPC queries work
Demo Data Examples
Demo Agent Tasks
Demo mode includes 5 sample agent tasks:
// Sample demo agent tasks
[
{
title: "Create landing page with pricing section",
status: "completed",
priority: "high",
result: "Successfully generated landing page..."
},
{
title: "Generate blog post about Next.js 16",
status: "in_progress",
priority: "high"
},
{
title: "Create dashboard component with charts",
status: "pending",
priority: "medium"
},
// ... more tasks
]Demo Blog Posts (Example Feature)
8 example posts covering various topics:
- "Getting Started with ProductReady"
- "Understanding tRPC Type Safety"
- "Drizzle ORM Best Practices"
- "Building a Design System with CSS Variables"
- And more...
Note: Blog posts are an example feature to demonstrate CRUD operations. You can remove this feature or replace it with your own business logic.
Demo Users
3 demo users for testing:
- Alice Johnson (
alice@example.com) - Bob Smith (
bob@example.com) - Carol Williams (
carol@example.com)
Using Demo Mode in Your Code
Detect Demo Mode
import { isDemoMode } from '~/lib/demo';
export function MyComponent() {
const searchParams = useSearchParams();
const isDemo = isDemoMode(searchParams);
if (isDemo) {
return <DemoBanner />;
}
// Normal component
}tRPC with Demo Mode
All tRPC routers automatically detect demo mode from the context:
// Query automatically handles demo mode based on URL/headers
const { data } = trpc.agentTasks.list.useQuery({
limit: 20,
});
// Create with demo mode check
const createTask = trpc.agentTasks.create.useMutation({
onMutate: () => {
if (isDemo) {
alert('Demo mode: Sign in to create real agent tasks');
return;
}
}
});Server-Side Demo Detection
// In tRPC router
export const myRouter = createTRPCRouter({
list: publicProcedure
.input(z.object({
// No demo param needed in input
}))
.query(async ({ ctx, input }) => {
// Return mock data if context indicates demo mode
if (ctx.isDemo) {
return getDemoData();
}
// Real database query
return ctx.db.select().from(myTable);
}),
});Demo Banner Component
Demo mode shows a blue banner to indicate sample data:
{isDemo && (
<div className="rounded-lg border border-blue-200 bg-blue-50 p-4">
<div className="flex items-center gap-2">
<Bot className="h-5 w-5 text-blue-600" />
<div>
<p className="text-sm font-medium text-blue-900">
Demo Mode Active
</p>
<p className="text-sm text-blue-700">
Viewing sample data. Sign in to create real content.
</p>
</div>
</div>
</div>
)}Creating Your Own Demo Data
Add demo data in src/lib/demo.ts:
// Define your demo data
export const DEMO_PRODUCTS: Product[] = [
{
id: 1,
name: "Starter Plan",
price: 9.99,
features: ["Feature 1", "Feature 2"],
},
// ... more items
];
// Export getter function
export function getDemoProducts(): Product[] {
return DEMO_PRODUCTS;
}Use in tRPC router:
import { getDemoProducts } from '~/lib/demo';
export const productsRouter = createTRPCRouter({
list: publicProcedure
.input(z.object({ /* ... */ }))
.query(async ({ ctx, input }) => {
if (ctx.isDemo) {
return getDemoProducts();
}
return ctx.db.select().from(products);
}),
});Disabling Demo Mode
To disable demo mode in production:
// src/middleware.ts
export function middleware(request: NextRequest) {
const { searchParams } = request.nextUrl;
// Disable demo mode in production
if (process.env.NODE_ENV === 'production' && searchParams.get('demo')) {
const url = request.nextUrl.clone();
url.searchParams.delete('demo');
return NextResponse.redirect(url);
}
return NextResponse.next();
}Or hide the demo button:
{process.env.NODE_ENV !== 'production' && (
<Button onClick={goToDemo}>Try Demo Mode</Button>
)}Best Practices
โ Do
- Show demo banners - Make it clear when viewing sample data
- Disable mutations - Alert users instead of showing errors
- Use realistic data - Make demos convincing
- Match real schema - Keep demo types in sync with database
- Test demo mode - Ensure it works without database
โ Don't
- Don't mix demo and real data - Keep them separate
- Don't skip the banner - Users must know it's demo mode
- Don't allow partial saves - All or nothing in demo
- Don't expose sensitive data - Use generic demo content
- Don't forget to document - Explain what's mocked
Troubleshooting
Demo mode not working
Check:
- URL has
?demo=1parameter isDemoMode()function imported correctly- Demo data exists in
src/lib/demo.ts
Demo banner not showing
Check:
const searchParams = useSearchParams(); // โ Client component
const isDemo = isDemoMode(searchParams);Make sure component is marked "use client".
tRPC returns empty data
Check router:
.query(async ({ ctx, input }) => {
if (ctx.isDemo) { // โ Check context
return getDemoAgentTasks(); // โ Check function exists
}
// ...
})Next Steps
- Quick Start - Set up real database
- Authentication - Add user login
- tRPC Guide - Build your own API endpoints
Demo mode is perfect for exploring ProductReady risk-free. When ready, follow the Quick Start guide to set up your own app!