← back to Ventura Claw Leads
Add per-vertical sample rails to home page (food/beauty/retail/creative)
05ae6c75d1f12618789dff5aa2aa6f1cbc9ebc7e · 2026-05-07 11:22:52 -0700 · Steve Abrams
Home was showing only category-chip counts plus the existing 'Featured'
rail (claim+tier-gated, only 9 cards). With 1,819 corridor-seeded
listings, the home page should preview the directory's depth, not just
gate-keep behind a search box.
Top 4 verticals by count get a 6-card preview rail with 'See all N →'
link. Cards prioritize photographed/claimed/premier rows then random,
so the rail rotates per request and rewards owners who fill out their
page. Today's home: 28 unique business links vs. 9 before — a 3x lift
in click targets without changing any other section.
JSON-LD LocalBusiness + BreadcrumbList already exists on
/business/<slug>; no structured-data work needed this tick.
Files touched
M routes/public.jsM views/public/home.ejs
Diff
commit 05ae6c75d1f12618789dff5aa2aa6f1cbc9ebc7e
Author: Steve Abrams <steve@designerwallcoverings.com>
Date: Thu May 7 11:22:52 2026 -0700
Add per-vertical sample rails to home page (food/beauty/retail/creative)
Home was showing only category-chip counts plus the existing 'Featured'
rail (claim+tier-gated, only 9 cards). With 1,819 corridor-seeded
listings, the home page should preview the directory's depth, not just
gate-keep behind a search box.
Top 4 verticals by count get a 6-card preview rail with 'See all N →'
link. Cards prioritize photographed/claimed/premier rows then random,
so the rail rotates per request and rewards owners who fill out their
page. Today's home: 28 unique business links vs. 9 before — a 3x lift
in click targets without changing any other section.
JSON-LD LocalBusiness + BreadcrumbList already exists on
/business/<slug>; no structured-data work needed this tick.
---
routes/public.js | 29 ++++++++++++++++++++++++++++-
views/public/home.ejs | 38 ++++++++++++++++++++++++++++++++++++++
2 files changed, 66 insertions(+), 1 deletion(-)
diff --git a/routes/public.js b/routes/public.js
index c6a82a7..9da3dc9 100644
--- a/routes/public.js
+++ b/routes/public.js
@@ -49,10 +49,37 @@ router.get('/', async (req, res, next) => {
`);
const verticalCountMap = Object.fromEntries(verticalCounts.map(r => [r.vertical, r.n]));
+ // Per-vertical sample rails. Pick the 4 verticals with the most active
+ // listings (currently food/beauty/retail/creative ≈ 1,690 of 1,819).
+ // For each, pull 6 sample businesses prioritizing those with photos
+ // and claimed status — they look nicer in the rail and reward owners
+ // who've put work into their page. Random within each priority bucket
+ // so the rail rotates per request.
+ const TOP_RAIL_VERTICALS = Object.entries(verticalCountMap)
+ .sort((a, b) => b[1] - a[1])
+ .slice(0, 4)
+ .map(([k]) => k);
+ const verticalSamples = {};
+ for (const vk of TOP_RAIL_VERTICALS) {
+ const rows = await db.many(`
+ SELECT id, slug, business_name, vertical, headline, neighborhood, city, state,
+ tier, claim_status, verified, photo_path
+ FROM businesses
+ WHERE status = 'active' AND vertical = $1
+ ORDER BY (photo_path IS NOT NULL) DESC,
+ (claim_status IN ('self','claimed')) DESC,
+ tier = 'premier' DESC, tier = 'standard' DESC,
+ RANDOM()
+ LIMIT 6
+ `, [vk]);
+ if (rows.length) verticalSamples[vk] = rows;
+ }
+
res.render('public/home', {
title: 'Ventura Claw — directory of Ventura Blvd small businesses',
metaDescription: `Find local restaurants, salons, retail, fitness, pet, auto detail, cleaning, and creative businesses on Ventura Blvd. ${stats.total} listings across Sherman Oaks, Studio City, Encino, Tarzana, and Woodland Hills — owners claim and update their own page.`,
- stats, featured, recentlyJoined, verticals: VERTICALS, verticalCountMap
+ stats, featured, recentlyJoined, verticals: VERTICALS, verticalCountMap,
+ verticalSamples
});
} catch (err) { next(err); }
});
diff --git a/views/public/home.ejs b/views/public/home.ejs
index a830514..8f4d92a 100644
--- a/views/public/home.ejs
+++ b/views/public/home.ejs
@@ -62,6 +62,44 @@
</div>
</section>
+<% if (typeof verticalSamples !== 'undefined' && verticalSamples) {
+ // Render rails in the same order verticalCountMap dictates (largest first).
+ // Each rail = 6-card preview + a "see all N <vertical>" link to the filter.
+ verticals.forEach(function(vv){
+ var rows = verticalSamples[vv.key];
+ if (!rows || rows.length < 3) return;
+ var totalForV = verticalCountMap[vv.key] || rows.length;
+%>
+ <section class="find-page" style="padding-top:24px">
+ <div style="display:flex;align-items:baseline;justify-content:space-between;flex-wrap:wrap;gap:12px;margin:0 0 16px">
+ <h2 style="margin:0"><span aria-hidden="true"><%= vv.icon %></span> <%= vv.label %> on Ventura Blvd</h2>
+ <a href="/find?vertical=<%= vv.key %>" class="muted" style="font-size:13px;font-weight:600;text-decoration:underline">
+ See all <%= totalForV %> →
+ </a>
+ </div>
+ <div class="business-grid" style="grid-template-columns:repeat(auto-fill,minmax(220px,1fr));gap:14px">
+ <% rows.forEach(function(b){ %>
+ <a class="business-card" href="/business/<%= b.slug %>" style="padding:14px 16px">
+ <% if (b.photo_path) { %>
+ <div class="biz-card-hero biz-card-hero-photo" style="aspect-ratio:16/9;margin:-14px -16px 12px">
+ <img src="<%= b.photo_path %>" alt="<%= b.business_name %>" loading="lazy" decoding="async">
+ </div>
+ <% } else { %>
+ <div class="biz-card-hero vertical-hero-<%= b.vertical %>" aria-hidden="true" style="aspect-ratio:16/9;margin:-14px -16px 12px">
+ <%- include('../partials/vertical-glyph', { verticalKey: b.vertical }) %>
+ </div>
+ <% } %>
+ <p class="biz-name" style="font-size:15px;margin:2px 0"><%= b.business_name %></p>
+ <p class="biz-loc" style="font-size:11px;margin:0"><%= [b.neighborhood, b.city].filter(Boolean).join(' · ') %></p>
+ <% if (b.claim_status === 'self' || b.claim_status === 'claimed') { %>
+ <p class="muted" style="font-size:10px;margin:4px 0 0;letter-spacing:0.05em;text-transform:uppercase">✓ Claimed</p>
+ <% } %>
+ </a>
+ <% }); %>
+ </div>
+ </section>
+<% }); } %>
+
<section class="faq">
<h2>Common questions</h2>
<details class="faq-item">
← 5cc49d8 Sitemap covers paginated pages; head supports rel=prev/next
·
back to Ventura Claw Leads
·
Add 37 vertical+city combo pages to sitemap; unclaimed banne d421ce8 →