PROJ-SERVICEB
Loaded
Project detail
λlambda Heating & Air

Problem

Local service sites often need many near-duplicate service/location pages without becoming a pile of hand-maintained HTML.

Context / users

This is a generalized local-service demo adapted from real client work. The useful part is the system: structured location and service data, generated pages, and narrow backend form handling.

My role

I owned the information architecture, content modeling, page generation, component structure, Express routes, form validation, reCAPTCHA integration, email handling, and demo adaptation.

Solution

I kept it static-first. Core pages are plain HTML enhanced by ES-module components. Location pages are generated from structured data. Express only handles the parts that need a server.

  • Generated location/service landing pages written from structured data instead of manually copied HTML
  • Reusable vanilla-JS component layer for navigation, hero, reviews, contact, careers, service pages, and location pages
  • Express-backed contact and quote endpoints with required-field checks, email validation, and reCAPTCHA verification
  • Nodemailer notifications and confirmation emails so form submissions behave like a real business workflow
  • Careers section with structured job data, job-detail routes, and a general-application path
  • SEO-oriented page metadata, schema markup, sitemap generation, and canonical handling
  • Static-friendly deployment model that keeps the frontend simple while preserving backend-powered lead capture

Architecture

Presentation, content modeling, generation, and backend form handling are kept separate. `public/components` holds reusable view modules, `public/data` holds source data, `scripts/` handles generation utilities, and `server.js` serves static files and exposes the form endpoints.

Engineering Details

  • Used a static-first architecture to keep most pages cheap to host and fast to serve, while reserving Express for the server concerns that actually require it
  • Modeled location and service content as structured data so the long-tail SEO footprint could be generated instead of hand-maintained
  • Organized the frontend into discrete ES-module components rather than one monolithic script, which makes the site easier to re-skin and extend
  • Added client-side validation in the contact flow and mirrored core validation on the server for a sensible defense-in-depth pattern
  • Handled careers detail pages with client-side route updates and a server catch-all so deep links can still resolve to the correct HTML shell
  • Built demo-mode touches such as booking fallbacks, health/test-email endpoints, and mock testimonial data to make the project usable as a portfolio artifact instead of a dead mockup

Outcome

  • Turned a repetitive local-SEO page problem into a reusable generation pattern
  • Produced a portfolio-safe demo that shows how a real agency/client implementation can be abstracted into a reusable technical asset
  • Created a small full-stack marketing site where the frontend stays lightweight but the lead flows still feel operational
  • Established a credible base for future reuse across other service-business builds, especially where static content and lead capture matter more than complex app state

Tradeoffs / Limits

  • The repo is stronger as an architecture demo than as a production-ready product. It has no database, no user accounts, and no fully integrated booking platform
  • The demo is only partially generalized today. Some legacy Heartland-specific branding, metadata, canonicals, and narrative copy still remain in the checked-in code
  • The careers UI is ahead of the backend: file inputs are present, but the checked-in job-application flow does not implement a real resume upload pipeline
  • The page-generation idea is real, but the checked-in generator script still needs module-format cleanup before the build story feels polished from a fresh clone
  • There is no visible automated test suite or CI workflow in the current repo

Why It Matters

It shows how I turn a repetitive SEO problem into a reusable technical pattern.

Like what you see?

Feel free to reach out if you have questions about this project or want to chat about working together.

> λlambda Heating & AirVanilla JavaScript