Not Another Sunday is a 137,000-listing directory of specialty coffee shops, pubs and restaurants built on Next.js 15, Supabase and Vercel. It ranks venues by a custom 0-100 quality score, not review counts. It generates hundreds of programmatic pages from one template. And it deliberately holds thin listings out of Google's index.

Key takeaways

  • Not Another Sunday ranks 137,000+ venues with a custom 0-100 quality score (the NRI) instead of raw review counts.
  • A single Next.js template drives hundreds of programmatic landing pages from structured venue and coffee data.
  • Cutting the sitemap from 132K to 55K quality URLs raised indexability to 84% by concentrating crawl budget on pages worth ranking.
  • A crawler-built catalog of 10,500+ coffees adds a "what to drink" layer with roaster links and origin data.
  • The project runs entirely in-house at Social Animal on Next.js 15, Supabase and Vercel, with no client involved.

Updated 15 August 2026: sources added, experience claims checked against our project record, summary added.

Not Another Sunday is built and run entirely in-house at Social Animal. No client, no committee. The full build, the scoring system, the programmatic SEO engine and the indexation strategy that keeps 137K listings crawlable, is documented in our Not Another Sunday case study.

Why review-count ranking is broken

Search for the best coffee in almost any major city. Google will show you the same chain cafe next to a train station. It has 4,200 reviews because every commuter and tourist walks past it. The rating's fine, 4.1 stars, but the espresso tastes like burned rubber. Three blocks away, a roaster pulls shots from single-origin beans sourced directly from a farm in Huila. It has 180 reviews, all glowing, from people who made a deliberate trip to get there. Google buries it on page two.

This pattern shows up in city after city. It's not a quirk. It's structural. Review volume is just a proxy for foot traffic. Generic directories inherit that bias wholesale: they pull star ratings straight from Google, sort by count, and call it a recommendation. They also go stale fast, padding lists with bakeries, breweries and restaurants that happen to serve coffee as an afterthought. We wanted a directory that could tell a genuine specialty roaster from a tourist trap. That meant building the scoring system from scratch, and defending every decision in it.

The NRI score and the filtering decisions

The data foundation is 137K listings harvested and enriched from Google Places and DataForSEO. But raw data isn't a directory. The first filtering pass uses Google's business category to classify each venue: specialty coffee shop, restaurant that also serves coffee, bakery, brewery. Restaurants, bakeries and tourist-oriented venues get filtered OUT of the specialty rankings entirely.

Category alone isn't enough, though. A place can be categorized as a "coffee shop" and still serve Lavazza from a superautomatic. So we added a language-model review pass that reads a venue's reviews for specialty signals: mentions of single origin, pour-over, roasting in-house, specific farms or processes. It weighs those against generic food-first language. The combination of structured category data and unstructured review analysis gives us a classification we trust enough to stake the product on.

Then comes the NRI score itself, a 0-100 composite that blends four factors. A Bayesian-adjusted rating pulls the raw star average toward a global mean, so a 5.0 from 3 reviews does not beat a 4.7 from 500. Review volume runs on a log curve, since volume matters but with diminishing returns. Going from 50 to 200 reviews moves the needle; going from 2,000 to 4,000 barely does. Specialty weighting draws on the classification confidence from the pipeline above, giving genuine specialty venues a boost. And a local-versus-tourist credibility factor applies heuristics around review patterns to separate devoted-regular signals from tourist-passing-through signals.

The result: a quiet neighborhood roaster with 200 devoted regulars can outrank a 4,000-review tourist magnet. This one decision shapes every leaderboard on the site. It's the reason the product exists, and it's the thing we defend most carefully as the dataset grows. Venue owners whose rankings drop, and partners who'd rather weight recency differently, will always push back on a scoring system like this. Our answer stays the same: the score exists to be right, not to be popular.

Programmatic SEO from a single renderer

What do you do with 137K scored and classified venues? Build the pages people actually search for. We built an editorial page engine that generates ranked lists: "best coffee in {city}", "{origin} roasters in {city}", neighborhood pages, landmark pages, drink-specific and amenity-specific pages. Hundreds are live, and every one is rendered from a single Next.js template. The data drives the content, ranked venues, NRI scores, editorial descriptions, structured data, internal links. But the template handles layout, schema markup and routing. This pattern, one template driving structured, database-backed content into consistent pages, is standard practice for programmatic SEO at scale. We've applied it here with tighter editorial gates.

Those gates matter, and we won't apologize for how strict they are. Every generated description has to clear a minimum word count, pass a banned-vocabulary check for filler and generic praise, and survive an AI-detection scoring pass. Venues that deserve deeper coverage get first-person in-person reviews, 1,500+ words, researched and fact-checked. The goal is that no page on the site feels like it was spit out by a content mill, even though the underlying system is fully automated.

The engineering runs on Next.js App Router with static generation and per-page revalidation across all 137K routes. Supabase handles the Postgres database and storage layer. Vercel hosts the front end. Tailwind CSS v4 keeps styling consistent. The architecture is tuned to stay fast and cheap at this scale, the same stack we'd recommend for any large-scale directory build.

The coffees layer

A coffee directory that only lists shops felt incomplete to us from the start. We wanted to catalog the coffees themselves. So we built crawlers that scrape roaster shopfronts across Shopify, WooCommerce and other e-commerce platforms. They pull product data for individual coffees: origin country, region, farm, process method, tasting notes, price.

10,500+ individual coffees are now cataloged, each on its own page, each linked back to the roaster that sells it, with roasters from 60+ countries represented. This layer turns Not Another Sunday from a "where to go" directory into a "what to drink" reference. It also creates thousands of additional long-tail pages with genuine informational value. Someone searching for a specific Ethiopian natural process coffee should land on a page that actually tells them something useful. That's the product working the way we designed it to.

The indexation call that made it work

This was the hardest and most counterintuitive decision we made. With 137K listings in the database, the easy approach is to put them all in the sitemap and let Google sort it out. We tried that first. The sitemap ballooned to 132K URLs, and Google's response was predictable: it crawled slowly, indexed erratically, and treated most pages as low-value.

So we did the opposite. We pulled thin listings out of the index. Any venue that hadn't earned real content, a meaningful description, enough data to differentiate it, photos, got a noindex tag and was removed from the sitemap. The sitemap shrank from 132K to 55K quality URLs. The results were immediate: 84% of submitted listings are now indexable, up from a sitemap bloated with thin pages that Google largely ignored. Crawl budget concentrated on pages that actually deserve to rank. The remaining thin pages still exist on the site for internal linking and user navigation, but they don't compete for crawl attention.

Holding pages back from the index is a call many directory builders get wrong. The instinct is understandable: more pages promise more chances to rank, more surface area. That instinct is usually wrong. Google doesn't reward volume, it rewards signal density. A 55K-page site where every page earns its place beats a 132K-page site where half the pages are stubs. We wrote about this in the Florida Massage Elite case study too. Not Another Sunday is where we've proven it at the largest scale.

Place-ID-matched photo seeding keeps listings visual, and every image is re-encoded to WebP to keep page weight down. The classification pipeline, Google category plus coordinate-matched place IDs plus the language-model QA pass, runs continuously to keep rankings clean as new venues enter the dataset.

The growth loop

A directory is only as valuable as its freshness. Here's how the loop works for Not Another Sunday: venue owners can claim their profile for free and earn a trust badge that signals verified status to visitors. A two-channel outreach system, cold email plus a warmer editorial invite, brings roasters in. Per-recipient dedup and suppression run end to end, so nobody gets contacted twice. Claimed profiles give owners a reason to keep their data current, which keeps the directory fresh, which keeps pages ranking, which brings more owners in. It's a flywheel, not a campaign. That distinction matters, because campaigns end.

What I would do differently

We underestimated how much editorial work the coffees layer would need. Crawled product data from roaster sites is messy: inconsistent field names, tasting notes that are sometimes marketing copy and sometimes genuine cupping descriptors. Cleaning that data at scale is an ongoing cost we should've budgeted for from day one. We knew it would be imperfect. We didn't know how imperfect, or how much that would add up at 10,000-plus SKUs.

We also waited too long to make the indexation cut. The first three months of the project had a bloated sitemap that trained Google to see the domain as low-quality. Recovering from that took patience, more than we'd expected, and more than we'd want a client to absorb.

But the NRI score, the decision to rank by quality instead of volume, is the call we'd make again every time. It's the reason the product has integrity, and integrity is the only moat a directory can have.

FAQ

How does the NRI score work and why not just use raw ratings?

The NRI blends a Bayesian-adjusted star rating, review volume on a logarithmic curve, a specialty classification weight, and a local-versus-tourist credibility factor into a 0-100 score. Raw ratings reward volume and punish small venues. The NRI corrects for that so genuinely great roasters surface above tourist traps.

How does a directory with 137K listings stay fast on Next.js?

Static generation with per-page revalidation means pages are pre-built and served from Vercel's edge, then refreshed on a schedule. Supabase handles data queries efficiently, images are re-encoded to WebP, and only pages that need updates get rebuilt. That keeps the site fast without redeploying all 137K routes at once.

Why did you deliberately deindex thin pages?

Google treated a 132K-URL sitemap mostly as noise. Cutting it to 55K quality URLs concentrated crawl budget on pages with real content and differentiation. The thin listings still exist for internal linking, but keeping them out of the index raised indexability to 84% and improved ranking signals across the board.

How was the coffee catalog built?

Crawlers scrape roaster shopfronts on Shopify, WooCommerce and other platforms, pulling origin, process, tasting notes and pricing for each product. The data is cleaned and normalized, then each of the 10,500+ coffees gets its own page linked back to the roaster. Ongoing re-crawls keep the catalog current.

Do you build directories like this for other companies?

Yes. The architecture behind Not Another Sunday, programmatic SEO, quality scoring, scalable Next.js rendering, is the same stack we use through our directory development practice. Not Another Sunday is where we test every pattern before we recommend it.