case study: building ottown, an ottawa city guide that publishes itself
ottown.ca is a guide to canada's capital — news, food and drink, real estate, arts, events, things to do. it publishes every day and nobody writes it.
this is real client work. the quotes are from the client's own google review, not from us.
the brief was a question
"came to yash with a half-formed idea for a news site that would basically update itself and i wasn't even sure it was doable."
that is the most honest kind of brief and the hardest to quote against. so the first work was not code, it was narrowing the idea until it could be priced without either side guessing.
some of what was asked for did not survive that conversation:
"there were a couple of things i asked for that she talked me out of and she was right about both."
talking a client out of scope is not a natural instinct for a shop paid to build things. it is the correct one when the feature costs money and makes the product worse.
what we built
the hard requirement was no manual editorial work. not "less" — none. a site that needs an editor every morning is a job, not a product, and the client did not want a job.
the pipeline:
- sourcing from rss feeds, instagram and reddit, so the input is broad enough that a quiet day on one channel does not mean an empty homepage.
- writing with claude, producing 400–600 word articles in the site's voice with ottawa-specific seo — length matched to what a local reader actually reads on a phone.
- imagery from pexels, selected per article, because a wall of text-only cards reads as abandoned.
- publication on an hourly launchd schedule, so the site fills through the day rather than dumping everything at 6am.
- the newsletter assembles from what went live and sends through resend.
next.js 16 on the front, supabase behind it, hosted on vercel.
the honest tradeoff
publishing without an editor is a real decision with real consequences, and it is worth naming rather than glossing.
what you gain is a site that runs at zero marginal effort. what you accept is that the writing step has no human between generation and publication, so the safety has to be built into the pipeline itself — narrow sourcing, constrained output length, a fixed voice, and the source retained rather than the model inventing from nothing. the alternative — a review queue — sounds safer and is, but it reintroduces exactly the daily obligation the project existed to remove. the client chose deliberately, knowing the tradeoff.
that is the conversation to have before building one of these, not after.
months later
a pipeline is only worth anything if it survives the day you stop watching it:
"site's been live a few months now and i barely touch it. articles go up daily on their own, newsletter sends itself, and it's fast on a phone which is where most of our readers are. had one problem after launch and she sorted it the same day."
"i barely touch it" was the specification. everything else served it.
how it was paid for
worth stating plainly, since the client raised it unprompted:
"price was fair and there were no surprises at the end, it was what we agreed on. she also didn't ask for the whole amount upfront. we paid in stages as parts of it got finished, which made it a lot easier for us and honestly made me trust the process more."
staged payment against delivered work is our default. it keeps the incentive pointed at shipping, and a client unhappy at stage two is not already paid in full.
if you are considering something similar
- what breaks when a source changes format? collection fails quietly unless it is built to fail loudly. this is the maintenance cost nobody quotes.
- what does it cost per month at rest? the build is one number. running it daily for a year — model calls, hosting, email — is the number that decides whether it is viable.
- do you want a review queue or not? both are defensible. pick on purpose, because retrofitting either into the other is real work.
we build these. if you have a half-formed idea and are not sure it is doable, that is a conversation worth having — it is how this one started.