← 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
M routes/public.jsM views/public/neighborhood.ejs
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">· <%= 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 →