zsty.us

Before / After · Case Study

JP Taylor Group — seven brands, one codebase, branch-per-brand data

  • Local Pro Services

The JP Taylor Group operates seven distinct brands — the JPTG umbrella, JPTI, Taylor Metal, Roseville RV, Load & Go Dumpsters, eMotorack, and Sierra Stoves — each with its own domain and audience. Instead of seven WordPress sites drifting apart, the platform serves all seven from a single Next.js 16 repo: proxy.ts hostname routing maps each domain to its brand, Neon database branches isolate each brand's data, and the shared services — SES email, self-hosted VAPID web push, a Slack router for ops/leads/reviews, Vercel AI Gateway for LLM calls — are built once and inherited by every brand.

The eighth site costs a config entry, not a rebuild — that's the whole argument for multi-tenant.
🔒jp-taylor-group.vercel.app
jackiej.events — modern site

Receipts — measured

Numbers that moved.

0
Brands served from one repo
was 0
0
Neon branches isolating brand data
was 0
7
Codebases to maintain
was 7
1
Third-party push vendors
was 1
  • 7 brands · 1 codebase · hostname-routed via proxy.ts
  • Neon branch-per-brand data isolation
  • Self-hosted VAPID web push — no third-party push vendor
  • Slack channel router: ops, leads, and reviews fan out per brand

The story

Problem · Insight · Build · Outcome.

  1. 01 · Problem

    Seven brands, and the web presence multiplied cost instead of reach.

    Every brand needed a site, email, lead capture, and someone to notice when a form came in. As separate builds, that's seven of everything — and the apex WordPress site was fragile enough that it was returning 503s by capture day.

  2. 02 · Insight

    The brands differ in paint, not plumbing.

    A dumpster-rental lead and a wood-stove lead need the same machinery: a fast page, a form, a database row, a Slack ping, maybe a push. Multi-tenant architecture builds that machinery once and lets each brand keep a fully distinct face.

  3. 03 · Build

    One repo, proxy routing, branch-per-brand data, shared rails.

    Next.js 16 with proxy.ts hostname routing; Neon branch per brand with shared Drizzle schema; SES email, self-hosted VAPID push, R2 media, Upstash, a Slack ops/leads/reviews router, and Vercel AI Gateway for the LLM surface — every brand inherits all of it.

  4. 04 · Pending

    The apex 503 is the loudest argument for cutover.

    At capture time jptaylorgroup.com returned 503 on every variant while the new platform answered instantly on the Vercel host. DNS cutover of the seven brand domains is the remaining step — flagged to the operator.

Architecture

One chain replaced by another. Receipts above.

Old stack
  • Per-brand WordPress
  • Seven sites, seven drifts
  • No shared services
New stack
  • One Next.js 16 repo
  • proxy.ts hostname routing
  • Neon branch-per-brand
  • Shared SES + VAPID push
  • Slack router + AI Gateway

What changed

Grouped by what kind of system shipped.

Each claim ships with concrete evidence — env vars, table names, cadence chips. No marketing fluff.

Design

Hostname routing makes a brand a config entry

proxy.ts maps each inbound domain to its brand: theme, nav, catalog, copy. Taylor Metal and Roseville RV share zero audience but share every line of infrastructure. Standing up brand number eight is a routing entry, a Neon branch, and a theme — not a project.

Before
Each brand meant another site to build, host, patch, and forget.
After
Seven brands ride one deploy; improvements land portfolio-wide instantly.
Retention

Branch-per-brand data isolation on Neon

Each brand's data lives on its own Neon branch — leads for the dumpster brand can never leak into the stove brand's queries, retention/deletion policies can differ per brand, and a migration can be rehearsed on one branch before touching the rest.

  • 7 Neon branches, one per brand
  • Drizzle schema shared; data planes isolated
Real-time push

Owned comms rails: SES + self-hosted VAPID push + a Slack router

Transactional email is shared SES; web push is self-hosted VAPID (no OneSignal-class vendor holding the subscriber list); and a Slack router fans ops events, inbound leads, and review alerts into per-brand channels so the right person sees the right brand's signal.

  • Self-hosted VAPID keypair — subscriber list is first-party data
  • Slack router: ops / leads / reviews per brand channel
  • Vercel AI Gateway fronts the LLM calls

While the owner sleeps.

Autonomous surfaces

The agent backbone keeps the brand earning after hours. The owner approves; the system runs.

  • Routes every lead to the right brand's Slack channel

    on each event

    Inbound leads, ops events, and review alerts fan out through the Slack router to per-brand channels the moment they land — seven brands, zero shared-inbox triage.

  • Pushes to subscribers without a push vendor

    on each send

    Self-hosted VAPID web push notifies brand subscribers directly — the subscriber list stays first-party, and no third-party vendor sits between a brand and its audience.

← All rebuilds

JP Taylor Group — seven brands, one codebase, branch-per-brand data — zsty.us