RGuide
← Project index Case study / Founder · Product & Engineering

RGuide

Designing and engineering a map-first travel platform—and the data, publishing, media, localization, and growth systems that make it scale.

  • UI/UX
  • Product Design
  • Development
  • Data Systems
Role

Founder · Product & Engineering

Tools

Next.js · TypeScript · Supabase · PostGIS · MapLibre · Cloudflare R2

Deliverables

Product strategy · UX/UI · Design system · Data model · Publishing pipelines · Production build

Live platform footprint Travel knowledge,
mapped.

Published city guides connected through one geographic system

749Published entries
5,979Guide stops
4,950Canonical venues
11,362Source connections
24,813Hours records
7,364Localized records

RGuide turns researched city knowledge into a spatial product travelers can browse, trust, and use in place. I designed and engineered the complete platform—from the interaction model and responsive system to the database, publishing tools, media pipeline, localization, and production operations.

Explore the live product
593Commits
71Active build days
Apr 28 → Aug 10Prototype to platform
RGuide world explorer displayed on a desktop monitor

From Prototype to Platform

The product moved from a local-data map prototype to a production platform in 105 calendar days. Select a milestone—or watch the build advance—to follow the change in emphasis.

105 calendar days Prototype → product → platform 593 commits · 71 active days
01
Frame the experience

Built the split-screen explorer, responsive map behavior, route structure, and first local guide model.

Interaction

The governing decision stayed consistent: increase the structure behind the interface without increasing the complexity in front of the traveler.

The System at a Glance

The system is organized in layers. Open any layer below to see what it owns and why the separation matters.

01 Experience Map + route + responsive UI

A Next.js App Router interface keeps the map, destination hierarchy, filters, guide rail, selected guide, and selected place synchronized. URLs represent real product state, so an interaction can also become a shareable and indexable page.

  • Desktop split-screen and mobile sheet patterns
  • Map camera, boundary, marker, and guide-selection state
  • City, category, guide, event, venue, creator, and locale routes
02 Application Server reads + client state

Server components and scoped endpoints assemble only the destination and guide data a route needs. Zustand and focused React hooks handle transient explorer state, favorites, itinerary workspaces, and places-been behavior without turning the database into UI state.

  • Scoped app-data and editorial-guide reads
  • Authentication, profile, submission, and analytics endpoints
  • Static HTML and local fallbacks for graceful degradation
03 Data Normalized source of truth

Supabase/Postgres stores destinations, venues, editorial entries, stops, events, schedules, classifications, hours, media, and citations as reusable records. PostGIS points and boundary polygons turn the editorial model into a geographic one.

  • Relational records replace legacy blob-table workflows
  • Canonical venues share facts across many guides
  • Row-level policies separate public reading from controlled writes
04 Delivery Views + caches + media

Database views and versioned render caches transform normalized records into the stable card shape expected by the interface. Cloudflare R2 holds canonical imagery and responsive renditions, while local snapshots protect key destination and boundary experiences from upstream outages.

  • Normalized records → render view → versioned cache
  • Source image → canonical media → responsive renditions
  • Live data → scoped fallback → crawlable output
05 Operations Publish + verify + learn

Purpose-built scripts and runbooks make content operations repeatable. Guide publishing resolves entities, verifies structure and hours, ingests media, refreshes caches, and audits the final route. Localization, analytics, SEO, and event workflows use the same operational discipline.

  • Guide, event, media, hours, and translation pipelines
  • Schema, content-source, SEO, and publish verification
  • First-party click analytics and affiliate attribution

Designing the Data Model

The decisive implementation shift was separating authored meaning from rendered presentation. Early content could move quickly as local objects, but every new guide repeated destinations, venue facts, images, and sources. That made scale fragile: a venue closure or changed opening time could require edits in many unrelated lists.

The normalized model gives each fact one owner and lets guides compose those facts into an editorial point of view.

Production schema · core relationships

Canonical records converge through secure views, versioned caches, and localized delivery.

Geography destinations
parent_id → destinations destination_boundaries destination_translations
Editorial entries
destination_id → destinations entry_translations entry_render_cache
Join model entry_stops
entry_id → entries venue_id → venues event_occurrence_id → events
Canonical place venues
venue_hours · special_hours venue_media venue_taggings → venue_tags venue_translations
Spatial views destination_tree
boundaries_geojson
Provenance entity_sources
source_id → sources
Event system events
activations → occurrencesevent_media · event_translations
Typed taxonomy venue_tags
food · stay · nightlife
Security-invoker view entries_maplist
destinations + entries + stops + venues + sources
Versioned payload entry_render_cache
Locale payload localized_cache
Product surface explorer UI
Canonical truth Editorial meaning Derived delivery

This structure supports both reuse and editorial specificity. A venue owns its address, coordinates, operating state, classification, hours, and canonical media. A guide stop owns the reason that venue belongs in a particular story, its order, contextual copy, and journey timing. Updating shared truth no longer erases the authorial reason for inclusion.

A Typed Taxonomy Instead of Generic Tags

Food, nightlife, stay, nature, culture, activities, routes, and essentials need different filters. The schema therefore uses typed fields—lodging type, food service type, cuisine, nightlife type, music genre, price tier, and curated attribute vocabularies—rather than a single undifferentiated tag array.

That structure powers useful questions in the interface: Which neighborhoods are strongest for cocktail bars? Which stays are social but not party hostels? Which restaurants are reliable after midnight? The filtering model is a direct expression of the content model.

Building the Publishing Engine

Content quality depends on operations, not only copy. I created a repeatable pipeline that treats a guide as a dataset with editorial judgment.

01 Research

Define the user need, guide scope, authoritative sources, and minimum stop quality.

02 Resolve

Match destinations and reuse canonical venues before creating any new entity.

03 Structure

Write entries and ordered stops with classification, coordinates, sources, and hours.

04 Enrich

Ingest canonical media, responsive renditions, boundaries, and provider-backed details.

05 Publish

Generate render views, refresh current caches, and expose the guide through scoped routes.

06 Verify

Audit hours, sources, schema shape, media, URLs, SEO output, and live rendering.

The repository contains dedicated workflows for editorial guides, destination descriptions, city boundaries, venue hours, weekly events, R2 media, translation batches, cache refreshes, and verification. These are small operational products inside the product: each one defines inputs, quality gates, failure handling, and a deterministic output.

Product resilience

Built to stay useful when a service fails.

A travel guide should not disappear because a database or image service is temporarily slow. RGuide prepares a verified version of published content so the essential experience can remain available.

Normal operation 01

Serve the newest published version.

Structured destination, venue, hours, source, and media records are assembled into a frontend-ready guide. The interface requests only the city or guide the traveler is viewing.

Structured recordsPublished viewExplorer
If a service is interrupted 02

Use the last verified version.

Saved guide content, map boundaries, destination descriptions, and image fallbacks keep the page usable while the live service recovers.

Verified contentSaved map and mediaSame explorer
Why this mattered

Both paths deliver content in the same predictable structure. That let me replace the original all-in-one JSON records with a normalized data model in stages—without redesigning the guide cards, routes, or map interactions. The backup remains a read-only copy of published content, never a second place to edit it.

Production interface system

A reusable product language.

The wireframes isolate the logic behind the interface before the visual system is applied: geographic orientation stays visible, guides remain comparable, and every editorial claim resolves into a useful place.

Plate 01 / Structure

Two scales, one model

From product shell to guide detail
01Explorer layoutHomepage / persistent geographic context
  1. 01Browse by hierarchyThe left rail narrows the world into regions, countries, cities, and neighborhoods.
  2. 02Keep position visibleThe map remains present while the traveler changes scope or compares options.
  3. 03Filter consistentlyThe same category system follows the traveler through every geographic level.
  4. 04Compare before openingThe guide index summarizes the choice before revealing the full editorial route.
Persistent map
Guide index
Comparable guide cards
02Guide moduleMapListCardShell / editorial information hierarchy
  1. 01OrientName the guide, its category, scope, and available actions.
  2. 02Keep contextExpose adjacent guides without ejecting the traveler from the city.
  3. 03Explain and provePair editorial rationale with sources and an ordered visual route.
  4. 04Resolve to actionTurn the guide’s argument into a specific place a traveler can use.
Editorial rationale
Sources
Ordered places
  1. 1
  2. 2
  3. 3
  4. 4
  5. 5
  6. 6
Plate 02 / Foundations

Tokens and controls

Small rules establish system-wide behavior
01Category tokensLabel · icon · map color · POI color
Food#F59E0B Nightlife#6366F1 Culture#F43F5E Stay#0891B2 Nature#10B981 Activities#F97316 Routes#2563EB Essentials#7C3AED
02Action familyRest · hover · selected
03Map markersGuide stop · selected stop · nested POI
1 5 8 A
04Route hierarchyThe navigation model becomes the URL model
05Source proofEditorial claims keep visible provenance
Sourced
EGG
Eater, local publishers +2
Plate 03 / In production

The system in use

City orientation → expanded editorial guide
01City viewBarcelona / orientation and guide comparison
02Expanded guideEditorial rationale / sources / ordered places

The interface uses one consistent mental model across scales. The left side answers where am I? The map answers how does it relate spatially? The guide rail answers what is worth doing and why? Selecting a destination, neighborhood, category, guide, or place updates the other surfaces rather than creating disconnected navigation modes.

Interaction and Routing Work Together

  • City and neighborhood boundaries load only when they become relevant.
  • Guide markers, selected places, and the camera share one state model.
  • Expanded guides update the URL immediately, preserving the current destination and category context.
  • Each city, category, guide, event, and venue has crawlable server-rendered output in addition to the interactive explorer.
  • The responsive system reorganizes the same hierarchy into mobile controls and sheets rather than reducing it to a separate, weaker product.

Performance and Delivery Systems

Map products become slow when everything is treated as global. RGuide instead reduces work at every layer.

Scoped reads

Routes request the current city, destination, or guide instead of repeatedly loading the complete editorial catalog.

Deferred geography

Neighborhood scoring and boundary geometry wait until the user reaches the relevant destination scope.

Render caches

Normalized joins are converted into versioned, frontend-ready payloads with an explicit current-cache contract.

Responsive media

R2 ingestion creates canonical, deduplicated image records and right-sized renditions for cards and details.

Stable crawling

Metadata, sitemaps, canonical URLs, server output, and local fallbacks keep search access independent of client interaction.

Installable product

A web manifest and service worker turn the responsive site into an installable web app without forking the experience.

Systems for Growth

The same architecture supports product growth without turning the core explorer into an advertising shell.

  • Localization: normalized translation tables and locale-specific render caches preserve one canonical English record while delivering complete Spanish routes, metadata, and sitemaps.
  • SEO: city, category, query-focused guide, event, venue, country, and continent routes translate explorer state into useful entry points for search.
  • Analytics: first-party click collection batches events, records campaign context, and powers a protected internal dashboard while retaining a Vercel analytics layer.
  • Monetization: stay calls-to-action use city and guide context to create attributable affiliate routes without changing editorial ranking.
  • Participation: authentication, profiles, favorites, saved places, and controlled guide submission add user value while keeping public write paths gated.
Production traffic · Cumulative pageview growth

Pageview growth, actual to projected.

The solid line accumulates verified production pageviews. The dotted continuation projects the recent viewing rate forward four weeks.

Observed pageviews
7,912
Unique visitors
1,115
Four-week projection
9,332
Observed cumulative pageviews Projected cumulative pageviews Vercel Web Analytics · Production · Apr 28–Aug 12, 2026 · UTC Projection: trailing five complete-week average · +355/week
Implementation outcome

What the build proved.

RGuide proved that a travel platform can grow without making the traveler experience harder to use. From the first prototype to 749 published entries, the interface kept the same clear pattern while the system underneath became more structured and reusable.

01
Reusable foundation

Facts are stored once.

Destinations, venues, events, hours, sources, and images each have one shared record instead of being copied into every guide.

Correct a fact once; every guide that uses it receives the update.
02
Editorial layer

Guides add the meaning.

Editors can explain why a place matters, when to visit, and where it belongs in a route without rewriting its underlying facts.

Shared data stays accurate while every guide keeps its own point of view.
03
Fast delivery

The interface stays simple.

Focused APIs, ready-to-render views, responsive images, caches, and fallbacks keep the map fast as the catalog grows.

Travelers see a consistent product—not the complexity behind it.
The result

RGuide can add cities, languages, content, and contributors without redesigning the product for every destination. Editors get a dependable publishing system, and travelers get the same clear journey from world to street.

Live product walkthrough · 32 sec

World to street.

Navigation hierarchy

The same geographic model carries a traveler from broad orientation to a useful, editorially curated route.

WorldContinentCountryCityNeighborhoodGuide

  1. 01 Orient World

    Begin with a spatial overview of available travel knowledge.

  2. 02 Focus Europe

    Move from the global index into a browsable regional collection.

  3. 03 Narrow Spain

    Compare destinations through a country-level view.

  4. 04 Explore Barcelona

    Pair city context, live geography, and editorial guides.

  5. 05 Understand Neighborhoods

    Move between districts without losing city context.

  6. 06 Act Selected guide

    Open a curated route designed for use on the street.