Inside Recent Visits: travel guides, an AI trip planner, and honest recommendations
How Recent Visits combines a Nepal travel publication, an AI assistant grounded in published guides, and a partner marketplace whose rules keep sponsored tours from crowding out good matches.
Padma Raj LamaPublished 4 min read

Recent Visits is a travel discovery and AI travel-assistance platform, starting with Nepal. I built it as a solo developer, and designed it as a platform rather than a blog with a chatbot bolted on. The product idea fits in one line: discover, explore, plan, match, connect. This article walks through what travellers can do, how the AI assistant stays accurate, and how paid listings are kept from distorting recommendations.
At a glance#
- What it is: Nepal travel guides, an AI trip-planning assistant, and a marketplace of verified travel agencies.
- Built with: one Next.js 16 app, Payload CMS, Supabase (Postgres, Auth, Storage, pgvector), and the Vercel AI SDK.
- Key rule: the AI never picks sponsored tours; a deterministic engine does, and sponsored results are always labelled.
What travellers can do#
- Browse destinations, treks, things to do, itineraries, tours, travel guides, and traveller stories.
- Plan a trip step by step on Plan your trip — regions, season, trekking, then matching with verified agencies.
- Ask Recent Visits AI questions and get suggested day-by-day itineraries.
- Search everything from one box; search works even without JavaScript.
- Contact a travel agency about a tour when they're ready to book.

One app, clear boundaries#
Recent Visits is a modular monolith: one Next.js 16 application hosts the public site, the Payload CMS admin, the AI assistant, and the partner portal, backed by a single Supabase Postgres database. One deployable keeps operations simple for a solo developer, while strict internal layers keep the code from tangling. Components only render, server actions validate input with Zod and call services, and services hold the business logic and data access.
- Content is modelled in Payload CMS (destinations, treks, itineraries, activities, guides, stories). Payload's tables live in their own
payloadschema, so Supabase's public APIs can never reach CMS internals. - Accounts use Supabase Auth for travellers and agency partners, while staff sign in to Payload's own admin.
- Media is stored in Supabase Storage through Payload's S3 adapter.
- Search mirrors every published document into a search table and combines Postgres full-text ranking with trigram title similarity, so near-miss spellings of place names still find results.
An AI assistant grounded in published content#
The assistant at /ai streams its answers, shows which tools it is using, and renders tour suggestions as recommendation cards. It answers from a knowledge base built from the site itself: one document per published destination, trek, activity, guide, story, partner profile, and tour, split into chunks and embedded with pgvector. Each document is hashed, so unchanged content is skipped when the index is rebuilt.
Models are reached through the Vercel AI SDK behind a provider abstraction, so Anthropic, OpenAI, or Google models can be swapped without touching product code.
Rules enforced in code, not in the prompt#
- The model never chooses sponsors. Tour suggestions come from a deterministic recommendation engine; the model only presents them, with a "Sponsored" label where it applies.
- Freshness travels with facts. Visa, permit, and safety answers carry the guide's verification status and official source, so the assistant can say when something should be double-checked.
- Retrieved text is untrusted. Passages and tool results are framed as data, and the assistant is told never to follow instructions inside them.
- Partner documents stay private. An agency's uploaded material can only be retrieved in that agency's own context.
- Usage is bounded. Anonymous visitors get 20 messages a day and signed-in users 150, with a spending budget per message that trims older history first.
Putting these rules in code matters because prompts can be argued with. A model can be talked out of an instruction; it cannot be talked out of data it never receives.
Recommendations that stay honest#
Travel agencies pay a flat listing fee to appear, and can pay to make a tour Featured. The recommendation engine applies hard rules before any ordering:
- A tour must fit the trip length within a tolerance — by default, one day either way.
- A tour must cover a destination the traveller named.
- Only tours that pass both rules and the minimum score are ordered.
- Featured tours go first within that list, and are always labelled.
Because eligibility is checked before payment is considered, a paid boost can never let a poor match in. A public "how we make money" page explains the model to travellers.

For travel agencies#
Agencies get a partner portal at /partner where they manage their profile, tours, and team (by invitation), see the enquiries they receive, and upload knowledge documents — including PDFs — that the assistant can use only for their own tours. Enquiry forms are protected with a honeypot field and rate limits, and notifications are sent by email through Resend. Staff verify agencies and review their offers in the CMS before anything goes live.
Quality and maintainability#
The codebase uses Zod for validation, Vitest for unit tests, and Playwright for end-to-end tests, with architecture decisions recorded as ADRs in the repository so the reasoning behind each choice survives.
Frequently asked questions#
Can sponsors pay to appear in AI answers?#
No. The assistant can only present tours chosen by the recommendation engine, which checks trip length and destination before considering whether a tour is Featured. Sponsored and Featured results are always labelled.
How does the assistant handle visa and permit questions?#
Answers carry the guide's verification status and official source, so the assistant can tell you when information should be confirmed with the authority before you travel.
Which destinations does Recent Visits cover?#
It starts with Nepal: destinations, treks, activities, itineraries, and tours from verified local agencies.
Read the full case study on the Recent Visits project page, or try it at recent-visit.com.
Related case study: read how it was built
Related articles

Product Building5 min read
How Ajako Taja turns scattered news feeds into short, sourced stories
A look inside Ajako Taja's pipeline: hourly feed ingestion, grouping items that cover the same story, AI-written summaries grounded in the sources, and the human checkpoints along the way.

Product Building4 min read
GuidedReel: an open-source script-to-video editor for web and desktop
What GuidedReel does, how one shared Remotion engine powers both a Next.js web app and an Electron desktop app, and the features that make short promo and social videos repeatable.