Title Town PDX: a fan site that has to stay true after every final whistle

For Portland fans following the Fire, the Thorns and the Cascade.

Title Town PDX covers Portland's three pro women's teams for fans checking scores, rosters and how to get to the game. Every result makes yesterday's page wrong, so I stopped fixing pages by hand and built a site that corrects itself on a schedule, with checks that compare it to the league instead of to itself.

  • 2.6KCopilot citations in September 2026, about flat on August. The last complete month in Bing's export
  • 1.7KGoogle and Bing clicks in July 2026, the most in any complete month
  • 31updates shipped by the results bot from Sep 28 to Oct 13, 2026, none by hand

Visit Title Town PDX Read the story

The whole site, month by month

  • September vs August-43%290 search clicks, from 511
  • August vs July-70%511 search clicks, from 1.7K
  • Best month on recordJuly1.7K search clicks

Search clicks down 43% in September; the best month is still July.

Google Bing Under each month, the change from the month before. Complete months only. Google Search Console and Bing Webmaster Tools, data through .
Search clicks down 43% in September; the best month is still July.
MonthSearch clicksChange from the month before
April158first month
May502+218%
June1.5K+195%
July1.7K+15%
August511-70%
September290-43%

In Google's AI answers

AI Overview impressions down 13% in September, after a record August.

Under each month, the change from the month before. Complete months only. Google Search Console, Generative AI report (impressions, not clicks), exported by hand, data through .
AI Overview impressions down 13% in September, after a record August.
MonthAI Overview and AI Mode impressionsChange from the month before
August3.5Kfirst month
September3K-13%

A fan on a phone, and facts that expire

A Portland fan on a phone wants to know who plays tonight, where to watch, and whether the Fire are still in it. Three leagues, three venues, three schedules, and no single fan source covered the Fire (WNBA), the Thorns (NWSL) and the Cascade (AUSL) together. Portland is home, and I follow all three teams from Austin now, so I built the source I wanted.

The catch is that sports facts expire. A roster page is right on Tuesday and wrong after Wednesday's signing. A "season underway" line is true in July and false the morning after elimination. The real question was never how to write these pages once. It was how to keep them true without retyping them every week.

The readers who need that most are the ones AI answers send. In Bing's export, the query cited most was "portland fire roster": 3.5K citations, and this site was the source in 37% of the answers that cited anyone. A roster has to be right the day someone asks.

The query and its share are from Bing Webmaster Tools' AI Performance export, window ending Oct 11, 2026. A real search, quoted as Bing recorded it.

One events file, a sync that runs twice a day, and gates that look outward

One canonical events file holds every game for all three teams, and every page derives from it: records, form strips, schedules, banners, calendar feeds and the structured data search engines read. Change the file and the whole site moves with it.

Results flow in from ESPN on a schedule, 2 runs a day, matched on the game's stable event ID. In the live test before it shipped, matching on dates caught 2 of 8 games, because ESPN stamps an evening Pacific game a day ahead in UTC. Matching on IDs caught 8 of 8. An evening run was added later so a finished game stops showing as "today" on the night people search for the score.

Before anything ships
9 validation scripts and the unit tests run in the build

They check
Freshness, stale tense, roster parity, expired windows, results backfill, season phase

Proof they fire
3 scripts plant the defect and expect the gate to go red

A separate heartbeat runs on the morning schedule and fails on any played game the file hasn't recorded. The site's pages for the reader:

Counted in the site's own build configuration and scripts, read Oct 13, 2026.

Cited heavily during the season, then the season ended

Copilot citations about flat in September (-5% on August). Bing's export records how often a Copilot answer cited the site, month by month, through Oct 11, 2026.

Under each month, the change from the month before. Complete months only. Bing Webmaster Tools AI Performance export, pulled by hand, data through .
Copilot citations about flat in September (-5% on August).
MonthCopilot citationsChange from the month before
April935first month
May2K+116%
June4.9K+144%
July8.6K+75%
August2.8K-68%
September2.6K-5%

Two roster pages did most of that work: /fire/roster/ drew 8.3K citations and /cascade/roster/ drew 3.6K in the export window. Those are the pages the sync keeps current.

Search clicks followed the calendar. Google and Bing together sent 1.7K clicks in July 2026, the most of any complete month, and 290 in September 2026. The Cascade's season ended on Jul 23, 2026 and the Fire's on Sep 22, 2026, and a fan site's traffic goes where the games go. The report above shows every month.

It keeps updating itself. On Oct 13, 2026 the homepage led with the Oct 3, 2026 result, Thorns 2, Boston Legacy 4, and every commit to the repository from Sep 28 to Oct 13, 2026 came from the results bot: 31 of them, none by hand.

How I measured it. Copilot citations: Bing Webmaster Tools' AI Performance export, a manual pull that stops at Oct 11, 2026. Search clicks: Google Search Console and Bing Webmaster Tools daily totals summed by complete month, through Oct 10, 2026. Commits: the GitHub commits API for the site's repository, read Oct 13, 2026. None of this separates the season from anything changed on the site.

Every miss passed a check

The misses were real, and each one passed a check that was green at the time.

I shipped invented history

On April 14, 2026 I found that every season record on the original Fire history page was wrong, and that a coach who never coached the team was named on another page. Both were fixed that day. A made-up attendance figure went the same way in May 2026. Fabrication is the one error a sports site can't survive, and these came from drafting faster than I verified.

Automation that reported success and did nothing

The daily rebuild had been a no-op from the day it shipped: a missing secret sent it down a skip branch that exited clean every morning, so "today" froze. I found it on August 2, 2026. On August 29, 2026 I found the cached league data judged its own age by file time, which every checkout resets, so one hub had served a table from April 5 for months.

Every gate green, site still wrong

A Cascade score posted on July 11, 2026 was wrong on the live site until August 8. The old check compared the site to its own ledger, and the ledger held the same wrong score. Arithmetic caught it: the season totals were off against the league's published standings. The Fire were eliminated on Aug 25, 2026 and nothing on the site said so until September 6, 2026; the hub still led with preseason copy. And the hand-written recaps stopped in May 2026 while the automation kept running, because recaps needed a person every game.

What changed

I changed what the checks compare against. Season totals are asserted against the league's own standings instead of my ledger. A season has a phase with a dated end, so "eliminated" retires itself after the last game instead of waiting for me. A gate that hunts for pre-debut copy reads the player's own games-played count before it decides a phrase is stale. And automation has to prove it did something, not just exit clean. The Fire's hub now closes year one at 17-27, written the day the miss was found, and the checks keep it that way.

Dates are from the site's own commit history, read Oct 13, 2026; the Fire's record and elimination date from its live hub.

The evidence

Ask Bella

Ask Bella Hayden's corgi. Answers from this site, every fact sourced.

BELLA

WOOF. I'm Bella, Hayden's corgi. He's my human. Ask me about him; every answer cites its source.

How it works: answers written ahead and checked against this site's pages, plus a search of the site that quotes it word for word. Every claim has a numbered source you can tap. Nothing is generated while you wait, nothing is made up, and nothing you type leaves your browser. Every answer, in plain HTML

Top

This page was last updated .