← Small Business Suite

The Salon Co.

A 14-page luxury salon website with a full-stack booking engine — 4-step reservation flow, Stripe deposit checkout, real-time stylist availability from Supabase, Resend transactional email, and automated cancellation with a 48-hour refund policy. Owned outright with no monthly platform fee.

Node.js · Express · Supabase · Stripe · Resend · Vercel

The Problem

Most salons are booked through platforms like Square Appointments, GlossGenius, or Vagaro that charge $25–100/month in perpetuity, impose their own branding on every customer-facing page, and in some cases take a cut of each transaction. The UX is generic by design — the same template used across thousands of salons — and the owner never fully controls the experience. The goal was a custom-branded presence built from scratch that feels genuinely luxury: a 4-step reservation flow with per-stylist availability, 25% deposit collection through Stripe, and automated email confirmation and cancellation — all owned outright with no subscription, no platform lock-in, and no commission per booking.

Try It

the-salon-co.vercel.app

Previewing at tablet width. Open the full site ↗ for the desktop experience. Also fully optimized for mobile.

You're on mobile — open the full site ↗ for the best experience. Any display issues are caused by the embed, not the site itself.

Meet Your Stylist

Each stylist has a profile card with their photo, specialty, and bio — so clients know who they're booking before they sit down. Builds trust and reduces no-shows from uncertain first-timers.

Stylist profile card with photo and bio

Stylist Selection

Step two of the booking flow only shows stylists who actually perform the selected service — so clients never see someone who can't help them. Smart filtering at the selection step, not an afterthought at checkout.

Stylist selection filtered by service

Date & Time Selection

Clients pick their appointment date and time from a live availability calendar — slots reflect the selected stylist's actual schedule.

Booking calendar — date and time selection

Mobile Experience

9:41
Technical Implementation

Booking Flow

Four steps: service selection (radio buttons mapped to valid stylists per service), stylist selection (cards dynamically enabled or disabled based on both service compatibility and per-stylist availability), date and time selection via a fully custom calendar, and a confirmation step where the client enters their details and pays a 25% deposit. The progress bar updates on each step transition with a smooth scroll back to the top of the booking section.

Stripe Checkout & Webhook

When the client submits their details, the front end POSTs to /create-checkout-session, which validates all inputs server-side, pulls the service price from Supabase, calculates a 25% deposit amount, and creates a Stripe Checkout session. When payment completes, Stripe fires a webhook to /webhook — the handler writes the booking to Supabase and sends a confirmation email through Resend. The success page fetches booking details from Supabase first, falling back to Stripe session metadata directly if the webhook hasn't fired yet — handling the race condition between a fast browser redirect and slower webhook delivery.

Cancellation & Refunds

Each booking is issued a UUID cancel token at insert time. The confirmation email carries that token in a link — no login, no account required, and the URL can't be guessed. When a client clicks it, the server calculates time remaining: cancellations at least 48 hours out trigger an automatic Stripe refund executed server-side through the Stripe API; inside 48 hours, cancellation requires calling the salon directly.

Real-Time Availability

The calendar makes two live API calls when a stylist and month are selected: /closed-dates returns owner-blocked dates stored in Supabase, and /booked-dates returns all confirmed bookings grouped by date so fully-booked days can be greyed out. When a specific day is selected, /booked-slots returns the taken time slots for that stylist on that date — the remaining slots render as selectable buttons. An AbortController cancels in-flight slot requests if the client changes their date selection before the previous fetch completes.

Scroll Behavior & UI

A scroll event listener transitions the header to its condensed sticky state once the page scrolls past 10px. The reviews carousel auto-rotates every 3 seconds with clickable progress bar dots that jump to any review directly. The gallery filter uses CSS class toggling to show and hide items by category — no external library. The FAQ accordion manages open/close state with display toggling, defaulting to the first item open on load.

Contact Form

The contact form POSTs to /contact, which sends a formatted email to the salon owner through Resend with a reply-to header pointing at the client's address — the owner can reply directly from their inbox without any intermediary dashboard.

SEO

Schema.org HairSalon JSON-LD structured data on the homepage with address, hours, and contact details. Verified passing in Google's Rich Results Test.

The Outcome

A 14-page luxury salon presence the owner controls outright — no subscription, no commissions, no platform lock-in. Each of the four core services (precision cut, color highlights, blowout, keratin treatment) has its own SEO-optimized page with pricing, description, and a direct booking link. Clients can browse services, see stylist availability in real time, book and pay a deposit through Stripe, and cancel if needed — all from the same site. Designed and built solo. Part of the Small Business Platform Suite.

Link Preview

The Salon Co. link preview image
the-salon-co.vercel.app

The Salon Co.

A four-chair hair studio. By appointment only. Cuts, color, and care — without the noise.

Need a website for your business? I take on select freelance web projects.

Let's talk →