[object Object]

← back to Ventura Claw Leads

Cross-link neighborhood pages to vertical+city combo pages

dbc5da9cd3fd9ad2ea8f57cad07e55bcad205ff3 · 2026-05-07 12:28:11 -0700 · Steve Abrams

/neighborhood/<slug> now renders 8 vertical chips + an inline 'Jump to
a category' paragraph, each linking to the matching /find?vertical=X&
city=Y combo page with crawlable anchor text. 5 neighborhoods × 16
combo links = 80 new internal links pointing into the 37 combo pages
seeded into sitemap.xml last tick — converts them from sitemap-only
orphans into part of the primary navigation graph.

Also fixed: lede was using businesses.length (capped at LIMIT 200) for
the count. Now uses the unfiltered totalCount from a separate aggregate
query. Sherman Oaks for example now reports 482 in its lede instead of
the capped 200.

Files touched

Diff

commit dbc5da9cd3fd9ad2ea8f57cad07e55bcad205ff3
Author: Steve Abrams <steve@designerwallcoverings.com>
Date:   Thu May 7 12:28:11 2026 -0700

    Cross-link neighborhood pages to vertical+city combo pages
    
    /neighborhood/<slug> now renders 8 vertical chips + an inline 'Jump to
    a category' paragraph, each linking to the matching /find?vertical=X&
    city=Y combo page with crawlable anchor text. 5 neighborhoods × 16
    combo links = 80 new internal links pointing into the 37 combo pages
    seeded into sitemap.xml last tick — converts them from sitemap-only
    orphans into part of the primary navigation graph.
    
    Also fixed: lede was using businesses.length (capped at LIMIT 200) for
    the count. Now uses the unfiltered totalCount from a separate aggregate
    query. Sherman Oaks for example now reports 482 in its lede instead of
    the capped 200.
---
 routes/public.js              | 23 ++++++++++++++++++++---
 views/public/neighborhood.ejs | 29 ++++++++++++++++++++++++++---
 2 files changed, 46 insertions(+), 6 deletions(-)

diff --git a/routes/public.js b/routes/public.js
index de8569e..ebb02f2 100644
--- a/routes/public.js
+++ b/routes/public.js
@@ -236,12 +236,29 @@ router.get('/neighborhood/:slug', async (req, res, next) => {
        LIMIT 200
     `, [slug]);
 
+    // Per-vertical counts for this neighborhood — drives the inline
+    // 'Beauty in Sherman Oaks (155)' cross-links that point to the new
+    // /find?vertical=X&city=Y combo pages. Strong internal-linking signal
+    // for Google: the combo pages are part of the site's primary structure,
+    // not just sitemap orphans.
+    const verticalRows = await db.many(`
+      SELECT vertical, COUNT(*)::int AS n
+        FROM businesses
+       WHERE status = 'active'
+         AND (LOWER(REPLACE(neighborhood, ' ', '-')) = $1
+              OR LOWER(REPLACE(city, ' ', '-')) = $1)
+       GROUP BY vertical
+    `, [slug]);
+    const verticalCountMap = Object.fromEntries(verticalRows.map(r => [r.vertical, r.n]));
+    const totalCount = verticalRows.reduce((sum, r) => sum + r.n, 0);
+
     res.render('public/neighborhood', {
       title: `${meta.label} businesses on Ventura Blvd · Ventura Claw`,
-      metaDescription: `${businesses.length} small businesses on Ventura Blvd in ${meta.label} — restaurants, salons, retail, fitness, pet, auto detail, cleaning, creative pros. Search and message a business directly via Ventura Claw.`,
+      metaDescription: `${totalCount} small businesses on Ventura Blvd in ${meta.label} — restaurants, salons, retail, fitness, pet, auto detail, cleaning, creative pros. Search and message a business directly via Ventura Claw.`,
       neighborhood: meta,
-      businesses,
-      verticals: VERTICALS
+      businesses, totalCount,
+      verticals: VERTICALS,
+      verticalCountMap
     });
   } catch (err) { next(err); }
 });
diff --git a/views/public/neighborhood.ejs b/views/public/neighborhood.ejs
index b257e55..97ce88b 100644
--- a/views/public/neighborhood.ejs
+++ b/views/public/neighborhood.ejs
@@ -27,16 +27,39 @@
 <section class="find-page">
   <p class="kicker">On Ventura Blvd</p>
   <h1 class="display-sm">Businesses in <%= neighborhood.label %></h1>
-  <p class="lede"><%= businesses.length %> business<%= businesses.length === 1 ? '' : 'es' %> in <%= neighborhood.label %>. Search by name, browse by category, or jump straight to a profile and send a message.</p>
+  <%
+    var _displayTotal = (typeof totalCount !== 'undefined' && totalCount) ? totalCount : businesses.length;
+  %>
+  <p class="lede"><%= _displayTotal %> business<%= _displayTotal === 1 ? '' : 'es' %> in <%= neighborhood.label %>. Search by name, browse by category, or jump straight to a profile and send a message.</p>
 
+  <%
+    // Per-vertical chip row + an inline 'browse by category' paragraph that
+    // gives Google crawlable anchor text linking each vertical+city combo
+    // page. Hide verticals with 0 matches so we don't ship soft-404 chips.
+    var _vMap = (typeof verticalCountMap !== 'undefined') ? verticalCountMap : {};
+    var _activeVerticals = verticals.filter(function(v){ return (_vMap[v.key] || 0) > 0; });
+  %>
   <div class="grid-controls" role="region" aria-label="Filters" style="margin-top:24px">
     <div style="display:flex;gap:6px;flex-wrap:wrap;align-items:center">
-      <% verticals.forEach(function(v){ %>
-        <a href="/find?vertical=<%= v.key %>&city=<%= encodeURIComponent(neighborhood.label) %>" class="btn btn-ghost btn-sm" style="font-size:12px"><%= v.icon %> <%= v.label %></a>
+      <% _activeVerticals.forEach(function(v){
+           var n = _vMap[v.key] || 0;
+      %>
+        <a href="/find?vertical=<%= v.key %>&city=<%= encodeURIComponent(neighborhood.label) %>" class="btn btn-ghost btn-sm" style="font-size:12px">
+          <%= v.icon %> <%= v.label %> <span class="muted" style="font-size:11px;font-weight:400">·&nbsp;<%= n %></span>
+        </a>
       <% }); %>
     </div>
   </div>
 
+  <% if (_activeVerticals.length > 1) { %>
+    <p class="muted" style="margin:14px 0 0;font-size:13px;line-height:1.7">
+      Jump to a category in <%= neighborhood.label %>:
+      <% _activeVerticals.forEach(function(v, i){
+           var n = _vMap[v.key] || 0;
+      %><% if (i > 0) { %>, <% } %><a href="/find?vertical=<%= v.key %>&city=<%= encodeURIComponent(neighborhood.label) %>" style="font-weight:600"><%= v.label.toLowerCase() %> in <%= neighborhood.label %></a> (<%= n %>)<% }); %>.
+    </p>
+  <% } %>
+
   <% if (businesses.length === 0) { %>
     <div style="padding:40px 0;text-align:center">
       <h3>No businesses listed in <%= neighborhood.label %> yet.</h3>

← d421ce8 Add 37 vertical+city combo pages to sitemap; unclaimed banne  ·  back to Ventura Claw Leads  ·  Home gets Organization+WebSite+FAQPage JSON-LD; neighborhood fb3a3e4 →