I’m Anna. I built a page that makes it more fun to search or randomly select a city and learn a few things about it.
I have a family member that loves to read books by authors that lived in a place before she visits the place and so originally I made this for her and it only returned the authors. Then I added the reddit users sentiments and the interesting facts. Except the word interesting is overused so I call them strange facts, although they’re leaning closer to normal facts, but shh.
I’m a product manager by day that loves graphic design and Vercel has made it so I can combine the two in a way that I would have never thought possible without some solid software engineering skills.
There’s a hard rule that “internet voices” must be verbatim lifts from real Reddit posts, not LLM paraphrases. Stage 1 of the pipeline names plausible subreddits; Stage 5 fetches their top posts and runs a verification gate (verbatim string match, sentence-boundary check, content-safety filter, distinct-subreddit rule). If nothing passes, the section ships empty rather than fabricated.
Feedback welcome: especially curious whether the “no paraphrase fallback” rule reads as a feature or a missing piece when you hit a city with sparse coverage. Try a well known city like Lisbon or Buenos Aires for a robust result. Spin the globe to get an obscure city and see what sparse coverage looks like.
City Notes is a per-city literary page: type a city, get a curated set of quotes from writers who have experienced the city you’re searching, plus a few internet voices and strange facts.
Notes on how it’s built (full transparency, claude helped me write these bullet points):
Next.js 15 (App Router) + React 19 on Vercel Fluid Compute. Neon Postgres for the cache layer. Tailwind with minimal shadcn primitives — most of the UI is custom typography rather than components.
LLM via the Vercel AI SDK through AI Gateway (anthropic/claude-sonnet-4-6), no hardwired provider SDK. The model assembles and verifies sources; it doesn’t write the body copy.
Two-tier cache. content_json per city in Postgres with a 7-day TTL. Author-tier verdicts and per-author/per-city relationship judgments are cached separately so we don’t re-spend tokens on Pessoa every time someone loads Lisbon.
Sources fan out across Goodreads, Wikiquote, Project Gutenberg, Google Books snippets, Reddit JSON, Wikipedia. Each quote carries author, work, year, source URL, and a relationship chip (born / lived / partial / passed / imagined) derived from biographical context.
Favorites are auth-less — localStorage for personal state, a single (city_slug, count) table for the global counter, one-heart-per-device throttle.
Build order: hand-build Lisbon first with no LLM and no DB, lock the typography and feel, then add two more hand-built cities to stress-test the template, then I wired up generation and shared the page out for others to experience.