DEV Community

hb lai
hb lai

Posted on

What Search Console taught me six weeks after shipping a quiz site (and the blank question 69)

Six weeks ago I shipped a Rice Purity Test site and wrote up the build here. This is the follow-up nobody asks for: what Search Console taught me after launch, and the two content fixes I made because of it.

The "explained" page problem

The page with the most impressions on the whole site was the plain list of 100 questions. Impressions kept climbing. Clicks stayed at zero. When I dumped the queries it was showing for, they weren't "rice purity test questions." They were things like:

  • seen or been seen by another person in a sensual context meaning
  • kissed horizontally rice purity
  • what is question 69 on the rice purity test
  • what is the question mark in the rice purity test

People weren't looking for the list. They were looking up one line they didn't understand, and they were quoting the original wording, which is phrased like a 1980s campus handout. My page had a modern rewrite, so it half-matched and never earned the click.

The fix was boring and took an afternoon: a second section with all 100 items in the classic wording, each with a one or two sentence note in plain English, and an id="q69" style anchor on every row so a search result can deep-link to a single item.

{CLASSIC_ITEMS.map((it, i) => {
  const n = i + 1;
  return (
    <li id={`q${n}`} key={n}>
      <span className="qn">{n}</span>
      <span>
        <span className="qt">{it.q}</span>
        <span className="qnote">{it.note}</span>
      </span>
    </li>
  );
})}
Enter fullscreen mode Exit fullscreen mode

A build-time guard keeps the data honest:

if (CLASSIC_ITEMS.length !== 100) {
  throw new Error(`CLASSIC_ITEMS must have 100 items, has ${CLASSIC_ITEMS.length}`);
}
Enter fullscreen mode Exit fullscreen mode

I'd rather the build fail than ship a 99-item "complete list." (I have done that before. Off by one on a list whose whole identity is the number 100.)

What the question mark actually is

The "question mark" queries confused me until I read the canonical list line by line. Item 69 on the classic Rice test is literally a lone ? with no text. It's a joke about the number, and paper-test takers get it in about two seconds. Search engines can't tell it's a joke, so nobody's page answered the question, which is why the query kept showing up with no good result. It's now an FAQ entry with FAQPage schema and the anchor #q69. The live version is at ricepuritytest.art/questions.

Small lesson: when a query looks nonsensical, go read the source document before assuming the searcher is confused. The searcher was right; the page was missing.

The "unblocked" query

The other cluster I'd been ignoring was rice purity test unblocked, showing up on both Google and Bing. It's a school-network intent: someone on filtered Wi-Fi who wants the test without an app install or an ad wall. I was wary of it because "unblocked" pages have a spammy reputation from the games world.

What I shipped is the honest version: a page that renders the actual test component right under the heading, states plainly that there's no login and nothing to download, and says in so many words that if a network filter blocks the domain, we don't offer workarounds. No proxy tricks, no mirror domains. It's at ricepuritytest.art/unblocked, and it reuses the same client-side quiz component the homepage uses, so it costs nothing to maintain.

export default function UnblockedPage() {
  const dict = getDict("en");
  return (
    <>
      <Intro />
      <div id="test">
        <RicePurityTest dict={dict} locale="en" />
      </div>
      <Faq />
    </>
  );
}
Enter fullscreen mode Exit fullscreen mode

One more: stop letting queries invent pages

A pile of queries like "different rice purity tests," "things like the rice purity test," and "rice purity test variations" were landing on random pages. Instead of building a page per phrase, I made one roundup of the actual versions that exist (the classic, the modern rewrite, the AO3 fanfic edition, the long Usenet-era ones, the Innocence Test) at ricepuritytest.art/variants. One page, several intents, and it doubles as an internal-link hub.

Two things I got wrong

I trusted a build that had silently gone x86. After a machine change, @opennextjs/cloudflare started failing on a missing native binding. The x64 build of @ast-grep/napi was sitting in node_modules from the Rosetta days while Node was now arm64. One pnpm add -D @ast-grep/napi-darwin-arm64 fixed it, but I lost twenty minutes assuming the bug was mine.

I burned my Search Console indexing quota by clicking too fast. After a "request indexing" succeeds, a toast covers the URL bar. If you type the next URL while it's up, the input silently fails and you re-submit the same page. Do that twice and the daily quota is gone. Close the toast first.

Where the numbers are now

Google is still deciding what it thinks of a two-month-old domain, and I won't pretend the graph is pretty. Bing, which doesn't sandbox new sites, has the homepage on page one for the head term and the glossary pages at positions one and two for their phrases, mostly thanks to submitting through IndexNow on every deploy. If you're launching a fresh domain, wire IndexNow on day one. It's a thirty-line shell script and it's the only thing on this list that had an obvious, immediate effect.

Top comments (0)