Discover. Plan. Go. — an AI-powered travel planning & booking SaaS: AI itinerary generator, multi-vendor tour marketplace, subscription billing, and a full admin panel in one Next.js app.
Trovo is a production-ready travel platform. It combines an AI itinerary generator, a multi-vendor tour marketplace, subscription billing (Stripe + PayPal), and a full admin panel — all in a single Next.js 16 app.
Buyers deploy it three ways (or all at once):
What you get: full TypeScript source, this documentation + a quick-start guide, an admin panel, a provider portal, a marketing landing page, realistic demo content, and a Vercel deployment guide.
Live demo: trovo.devsnack.dev
| Layer | Technology |
|---|---|
| Framework | Next.js 16 (App Router, SSR) |
| UI | React 19, TypeScript (strict), Tailwind CSS v4, shadcn/ui |
| ORM / DB | Prisma ORM + Neon PostgreSQL |
| Auth | NextAuth v5 (credentials + Google OAuth) |
| AI | Vercel AI SDK → OpenAI GPT-4o + Google Gemini 1.5 Pro |
| Maps / Weather | Google Maps (@vis.gl/react-google-maps) + Open-Meteo |
| Payments | Stripe + PayPal |
| Resend + React Email | |
| Images | Cloudflare R2 + sharp (WebP variants) |
| PDF / Rich text | Puppeteer + Tiptap |
| Realtime / Charts | SSE (trip collaboration) + Recharts |
| Deploy | Vercel · package manager pnpm |
app/ Next.js App Router — public, dashboard, admin, provider, API components/ shadcn/ui-based UI components lib/ Shared utilities & service clients (ai, plans, auth, paypal, …) prisma/ schema.prisma + migrations emails/ React Email templates docs/ PRD, launch, Stripe & deploy playbooks proxy.ts Route protection (Next 16's renamed middleware)
Route protection (proxy.ts): /dashboard/* requires auth, /provider/* requires a verified provider, /admin/* requires admin/moderator (and /admin/settings|billing|languages require admin only).
Trovo uses Neon PostgreSQL (serverless) with Prisma ORM — no extensions or pgvector required. The schema has ~30 models grouped by domain:
cp .env.example .env.local # then fill DATABASE_URL etc. pnpm db:migrate # create + apply schema (or db:push for prototyping) pnpm db:studio # browse the database
Trovo ships with two AI providers, admin-switchable at runtime via AdminSetting.ai_provider (factory in lib/ai.ts):
At least one of OPENAI_API_KEY / GOOGLE_AI_API_KEY is required. Free-plan users get gpt-4o-mini; Pro/Business get gpt-4o.
AdminSetting are encrypted at rest with AES-256 (lib/encryption.ts). Every AI route is rate-limited to 10 requests/hour per user.In the Google Cloud Console, enable both APIs:
Create two restricted keys (or reuse one):
GOOGLE_MAPS_API_KEY — server key, IP-restricted, Geocoding onlyNEXT_PUBLIC_GOOGLE_MAPS_API_KEY — public key, HTTP-referrer-restricted, Maps JS onlyOptional: create a custom Map Style and set NEXT_PUBLIC_GOOGLE_MAPS_MAP_ID for a branded dark map (required for Advanced Markers; falls back to legacy markers when empty).
Auth is NextAuth v5 with email/password credentials and optional Google OAuth.
AUTH_SECRET (openssl rand -base64 32) and AUTH_URL.GOOGLE_CLIENT_ID + GOOGLE_CLIENT_SECRET and add redirect URI <url>/api/auth/callback/google. Leave empty to hide the button.STRIPE_PRICE_* ids./api/webhooks/stripe subscribed to these 6 events:checkout.session.completed customer.subscription.created charge.refunded customer.subscription.updated invoice.payment_failed customer.subscription.deleted
Copy the signing secret into STRIPE_WEBHOOK_SECRET. Signatures are verified before any DB write. Local testing:
stripe listen --forward-to localhost:3000/api/webhooks/stripe
PayPal supports bookings (Orders API) and recurring subscriptions (Billing Subscriptions API); Lifetime stays Stripe-only. There is no dashboard UI for subscription plans — run the bundled script:
pnpm paypal:setup # creates the catalog product + 4 Plan IDs
Create a webhook at /api/webhooks/paypal (event list in .env.example) and set PAYPAL_WEBHOOK_ID. Set PAYPAL_ENV=live and re-run paypal:setup for production (sandbox Plan IDs don't work live).
Listing photos upload to Cloudflare R2; the server generates WebP variants with sharp.
R2_PUBLIC_URL.R2_ACCOUNT_ID, R2_ACCESS_KEY_ID, R2_SECRET_ACCESS_KEY, R2_BUCKET_NAME.Transactional + campaign email is sent via Resend (React Email templates). Used for booking confirmations, verify-email, password reset, newsletter campaigns, and trip-edit notifications.
RESEND_API_KEY and EMAIL_FROM. Without a key, email stub-logs to the console.RESEND_WEBHOOK_SECRET + endpoint /api/webhooks/resend for newsletter open/click tracking.All env vars are declared and validated with Zod in lib/env.ts; .env.example mirrors it with inline setup notes.
DATABASE_URL, AUTH_SECRET (≥16 chars), ENCRYPTION_KEY (exactly 64 hex chars), plus at least one of OPENAI_API_KEY / GOOGLE_AI_API_KEY.| Variable | Description |
|---|---|
NEXT_PUBLIC_APP_URL | Public base URL (baked at build time) |
NEXT_PUBLIC_APP_NAME | App name shown in UI (default Trovo) |
DATABASE_URL | Neon PostgreSQL connection string — required |
AUTH_SECRET | NextAuth session secret — required |
AUTH_URL | NextAuth base URL (match the deploy domain) |
ENCRYPTION_KEY | AES-256 key, 64 hex chars — required |
OPENAI_API_KEY | OpenAI key (one AI key required) |
GOOGLE_AI_API_KEY | Google Gemini key (alternative) |
GOOGLE_MAPS_API_KEY | Server key — Geocoding API |
NEXT_PUBLIC_GOOGLE_MAPS_API_KEY | Public key — Maps JavaScript API |
NEXT_PUBLIC_GOOGLE_MAPS_MAP_ID | Optional branded map style id |
STRIPE_SECRET_KEY / NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY | Stripe API keys |
STRIPE_WEBHOOK_SECRET | Stripe webhook signing secret |
STRIPE_PRICE_PRO_MONTHLY|PRO_YEARLY|BUSINESS_MONTHLY|BUSINESS_YEARLY|LIFETIME | The 5 Stripe price ids |
PAYPAL_ENV | sandbox (default) or live |
PAYPAL_CLIENT_ID / PAYPAL_CLIENT_SECRET | PayPal app credentials |
NEXT_PUBLIC_PAYPAL_CLIENT_ID | PayPal client id (browser SDK) |
PAYPAL_WEBHOOK_ID | PayPal webhook id (signature verification) |
PAYPAL_PLAN_PRO_MONTHLY|PRO_YEARLY|BUSINESS_MONTHLY|BUSINESS_YEARLY | The 4 PayPal Plan ids (pnpm paypal:setup) |
R2_ACCOUNT_ID / R2_ACCESS_KEY_ID / R2_SECRET_ACCESS_KEY | Cloudflare R2 credentials |
R2_BUCKET_NAME / R2_PUBLIC_URL | R2 bucket + public URL |
RESEND_API_KEY / EMAIL_FROM | Resend key + from-address |
RESEND_WEBHOOK_SECRET | Optional — newsletter open/click tracking |
GOOGLE_CLIENT_ID / GOOGLE_CLIENT_SECRET | Google OAuth (optional) |
PUPPETEER_EXECUTABLE_PATH | Optional — serverless Chromium for PDF export |
NEXT_PUBLIC_* vars are baked into the bundle at build time — set them in your host before building.At minimum Trovo needs three services — a PostgreSQL database, one AI provider key, and a Google Maps key. Everything else is optional and can be left disabled.
| Service | Powers | Required? | Cost model |
|---|---|---|---|
| OpenAI or Google Gemini | AI itineraries, refinement, packing lists | One of | Pay-as-you-go per request (your API key) |
| Google Maps | Maps + geocoding | Yes | Free monthly tier, then usage-based |
| PostgreSQL (Neon) | Application database | Yes | Free tier, paid for scale |
| Hosting (Vercel) | Running the app | Yes | Free tier, paid for production scale |
| Stripe & PayPal | Payments & subscriptions | Optional | Per-transaction processing fees |
| Cloudflare R2 | Image storage / uploads | Optional | Free tier, usage-based beyond |
| Resend | Transactional & campaign email | Optional | Free tier, usage-based beyond |
| Open-Meteo | Weather forecasts | Optional | Free — no key required |
Most of Trovo can be rebranded and managed without touching code, from the admin panel. Sign in with an admin account and open Admin → Settings or Admin → Branding. Changes apply at runtime — no redeploy needed.
#17cfb6 and amber #faa52e. The same design tokens also live in app/globals.css as --primary / --accent if you prefer to bake brand colors in at build time.app/globals.css and the app/ routes). Everything above — name, logos, colors, socials, and content — is admin-configurable at runtime.The admin panel at /admin is where you run the business day to day. Sign in with an Admin account. Here's each area and what it's for:
| Admin area | What you do there |
|---|---|
| Dashboard | At-a-glance revenue, users, bookings, and growth charts. |
| Users | View, search, change roles, and suspend accounts. |
| Providers | Review and approve / verify vendors who apply to sell tours. |
| Listings | Moderate marketplace tour listings (approve, hide, remove). |
| Bookings | See every booking and its status; handle cancellations / refunds. |
| Reviews | Moderate customer reviews and provider replies. |
| Revenue | Analytics dashboard with CSV export. |
| Payouts | Track what each provider is owed after your platform commission. |
| Promo codes | Create and manage discount codes. |
| Blog | Publish SEO content with a rich-text editor. |
| Newsletter | Compose and send email campaigns to subscribers. |
| Announcements | Site-wide banners for promos or notices. |
| Legal | Edit the Terms of Service and Privacy Policy pages. |
| Currencies | Enable currencies and set exchange rates / the default. |
| SEO | Per-page meta overrides; clear cached AI destination guides. |
| Branding | Logos, social links, footer (see the Customization guide). |
| Settings | AI provider + encrypted API keys, marketplace commission %, maintenance mode, site identity & colors. |
| Role | Can do |
|---|---|
| Admin | Everything, including the restricted Settings area (API keys, commission, maintenance). |
| Moderator | Day-to-day moderation — users, listings, bookings, reviews, content — but not platform Settings. |
| Provider | Their own listings, bookings, payouts, and profile, in a separate /provider portal. |
| User | Plan trips, book tours, and manage their own account. |
Trovo is built for Vercel.
pnpm build).NEXT_PUBLIC_* before the build).prisma migrate deploy.@sparticuz/chromium installed and PUPPETEER_EXECUTABLE_PATH pointed at its binary. See the full playbook in docs/DEPLOY.md.| # | Action |
|---|---|
| 1 | Set all environment variables in the host |
| 2 | Apply migrations (prisma migrate deploy) |
| 3 | Configure the Stripe webhook (6 events) + STRIPE_WEBHOOK_SECRET |
| 4 | Set PAYPAL_ENV=live, run pnpm paypal:setup, set the PayPal webhook + PAYPAL_WEBHOOK_ID |
| 5 | Set AUTH_URL + NEXT_PUBLIC_APP_URL to the real domain |
| 6 | Add the production Google OAuth redirect URI |
| 7 | Add the production domain to the Google Maps referrer restriction |
| 8 | Verify the Resend sending domain |
| Plan | Price | Highlights |
|---|---|---|
| Free | $0 | 3 AI itineraries/mo, GPT-4o-mini, weather + Google Maps, wishlist up to 10, browse & book marketplace tours |
| Pro | $9/mo · $89/yr · $199 lifetime | Unlimited AI itineraries, GPT-4o, PDF + packing-list export, up to 5 trip collaborators, embed widget, unlimited wishlist |
| Business | $29/mo · $290/yr | Everything in Pro + 20 collaborators + white-label branding + priority support |
No. You're buying the Trovo source code. AI (OpenAI / Gemini), Google Maps, payment processing, hosting, storage, and email run on your own accounts and are billed to you — see Costs & Third-Party Services. Most offer a free tier to start.
Yes. AI itineraries are optional. Without an AI key the planner is hidden and the rest of the platform — marketplace, bookings, content — works normally.
Yes. Leave the payment keys blank and checkout and subscriptions stay disabled. You can run Trovo as a pure trip planner or a free tour directory.
In v1.0 payouts are handled manually by the admin. Trovo tracks each provider's earnings minus your commission in Admin → Payouts; you pay them out via your own method. Automated instant payouts (Stripe Connect) are not part of v1.0.
Admins have full access including the restricted Settings area (API keys, commission, maintenance mode). Moderators handle day-to-day moderation — users, listings, bookings, reviews, content — but can't change platform settings.
There's no built-in cap — it scales with your database and hosting plan. The Free / Pro / Business plans only gate end-user features (AI usage, collaborators, and so on), not platform totals.
Yes. Change the name, logos, colors, social links, and footer from the admin panel with no code — see the Customization guide.
Yes. Plan pricing and feature gates live in lib/subscription-plans.ts and lib/plans.ts; the payment products themselves are configured in your Stripe / PayPal dashboards.
You can develop on Windows, macOS, or Linux (Node 20+ and pnpm). Production runs on any Node host; Vercel is the documented target.
Setup help and bug fixes by email — devsnack26@gmail.com. Custom feature development isn't included.
| Version | Notes |
|---|---|
| v1.1 | PayPal recurring subscriptions (Pro/Business monthly + yearly), trip collaboration (SSE presence + comments), embed widget, destination guides, affiliate links |
| v1.0 | Initial release — AI itinerary generator, tour marketplace, Stripe checkout + subscriptions, admin + provider portals, landing page, demo content |
Questions, setup help, or bug reports? We're happy to help.
devsnack26@gmail.com