The Brief
A local fence installation company needed a professional web presence — something that looked credible, communicated their services clearly, and made it easy for potential customers to reach out. The site needed to work well on mobile (most local service searches happen on phones), handle multiple fence product categories, and not require a CMS or database to maintain.
What It Does
Fence For Hire is a multi-page marketing and lead-capture SPA. Visitors can browse the company's background, explore six distinct fence product categories with individual detail pages, view a catalog, read testimonials, learn about financing options, and submit a contact inquiry. The navigation is fully responsive across mobile, tablet, and desktop breakpoints, including a dropdown submenu for the Fence Options section.
Key Features
Tech Stack
Client — React SPA with wouter routing
The frontend is a Vite-built React SPA using `wouter` for client-side routing (not React Router). wouter was chosen for its minimal footprint — the full router is a few hundred bytes and has no peer dependencies. The route tree covers Home, About, FenceOptions, Catalog, Testimonials, Financing, Contact, and the six individual fence type sub-pages, all loaded as a single bundle with no SSR overhead.
Component Architecture
Every section of the site is a discrete component with a clear responsibility:
Brand Identity Constraints
All design decisions were constrained by the company's established brand: Navy `#1e3a7a` as the primary color and Gold `#fbbf24` as the accent. shadcn/ui made this straightforward — every component is unstyled at the source level, so applying the brand palette was a matter of configuring the CSS variables rather than fighting a predefined theme.
Backend Structure
The repo includes a lightweight Express server and a `shared/schema.ts` file with Drizzle and Zod table definitions for future persistence. The current deployed version uses in-memory storage (a `MemStorage` class backed by a JavaScript `Map`) because the contact lead requirements were scoped to a first phase — the architecture is ready to swap to a real database without touching the client or shared schema.
What I Learned
Building within a client's brand constraints is a different muscle than building for yourself. Every color choice, spacing decision, and copy tone had to serve the company's existing identity rather than my own preferences. The three-breakpoint responsive header — particularly the Fence Options dropdown behavior across all three layouts — was the most time-consuming piece technically, and getting it right on mobile without JavaScript hacks required thinking carefully about CSS specificity and Radix's dropdown primitive behavior.