Disclosure: this post is by the Wanloria team (free, no ads, no affiliate links). It was drafted with AI assistance and fact-checked against the live site, per dev.to's guidelines on AI-assisted posts.
TL;DR: Wanloria is a free, bilingual (ES/EN) travel web app: verified places in 71 cities, 1-3 day itineraries with times, "free things" lists, signposted hiking trails with GPX and a weekly "this weekend" page. We built it largely by pair-programming with Claude Code and Cursor. The interesting part isn't the AI, though. It's the rules we gave it so it couldn't make things up.
Most "things to do in X" pages are rewritten from other "things to do in X" pages. We wanted every fact on a page (opening hours, price, website, whether a trail is circular) to trace back to a source, or not be shown at all.
/lugar/wiki-Q1140249/templo-de-debod and /lugar/osm-r4544509/museo-cerralbo.
Descriptions are generated by an LLM only from the verified fields of that place, never copying sentences from the source. If a fact isn't verified, the template doesn't render it. Every description is reviewed before it's published.
Hiking time follows DIN 33466, with no stops:
// DIN 33466: 4 km/h on the flat, 300 m/h up, 500 m/h down.
function dinHours(km, ascentM, descentM) {
const horizontal = km / 4;
const vertical = ascentM / 300 + descentM / 500;
return Math.max(horizontal, vertical) + Math.min(horizontal, vertical) / 2;
}
dinHours(12.6, 493, 395); // 4.37 h → shown as "4 h 20 min"
That's exactly what the live page for the PR-C 164 near Barcelona shows (12.6 km, +493 m, 4 h 20 min, MIDE 3/5). Difficulty uses the MIDE 1-5 effort scale. Trails are only published if they're signposted (GR/PR/SL or equivalent), within 18 km of the city, doable in a day, and if the OSM geometry matches the official distance. Loose stages of long-distance routes are dropped.
Itineraries split a city's top places by area, order each day from most important to nearest, and estimate walking as straight-line distance + 30 % for streets at 4.5 km/h, with a lunch break. Visit duration is estimated by place type (a big museum isn't a viewpoint) and adjusted when the place publishes its own figure.
The app itself is a SPA, but every public page (city, place, trail, 1/2/3-day plan, collections like /gratis and /museos, and /este-finde) is server-rendered HTML with JSON-LD ( TouristAttraction, ItemList, FAQPage, BreadcrumbList), hreflang es/en and a sitemap of ~7,000 URLs. There's also an llms.txt and a llms-full.txt with the core facts per city, each linking to its page.
Verification is only as good as the field it verifies. One real example: a museum whose general ticket costs €3 but is free on Sundays got tagged "free", because the source said "entrada gratuita…" for certain time slots. The fix we're moving to is a richer price model (free, free_at_times, paid) rather than a boolean. Elevation from a 90 m model can be ±10 % off a GPS track. Opening hours drift, so every place page keeps the source link and users can report errors to hola@wanloria.cloud.
Feedback very welcome, especially on the price model and the trail filters.