External storefronts
Give an LLM the Barbershop storefront skill to adapt the built-in experience or create a separate client.
To create a custom Barbershop storefront, copy the skill and give it to your LLM. The skill will explain how features/storefront and the customer-facing app routes implement Barbershop's current experience.
After that source orientation, it will ask what you dislike, what should stay, what workflows and users matter, and what the replacement should look and feel like. It then traces the exact routes, feature slices, GraphQL calls, schema, access rules, sessions, and provider boundaries in the supplied Barbershop codebase before proposing work.
Skill file: /skills/openfront-barbershop-custom-storefront/SKILL.md
Storefront routes
Routes live under app/(storefront). Each route file is thin and re-exports a screen from features/storefront/screens. Data loaders are in features/storefront/lib/data.
| Route | Screen | Customer journey |
|---|---|---|
/ | HomePage | Shop name, tagline, hours, and links into services, barbers, booking, and the walk-in line |
/services | ServicesPage | Service menu by category (getPublicServiceCatalog) |
/services/[id] | ServiceDetailPage | One service: duration, price, deposit, barbers who offer it |
/barbers | BarbersPage | Barbers who take online bookings (getPublicBarbers) |
/barbers/[id] | BarberDetailPage | Bio, weekly hours (getPublicBarberWeek), services; link to /book?barber= |
/book | BookingPageServer, BookingPage | Pick a service, barber, and time (checkBarberAvailability), enter details, book as a guest (createOnlineBooking) or signed in (createAccountBooking); pay a deposit when Stripe is set up |
/appointment | AppointmentStatusPage | Visit status (getPublicAppointment), cancel or reschedule with a fee preview (managePublicAppointment), sign a waiver (signPublicWaiver), pay or confirm a deposit |
/queue | QueuePage | Now-serving board, join the walk-in line (createPublicQueueEntry), see your ticket (getPublicQueueEntry). Shows a closed state when no one is working |
/shop, /shop/[id] | ShopPage, ShopProductPage | Retail products (getPublicProducts). Sold at the counter |
/memberships | MembershipsPage | Membership plans and packages (getPublicMembershipOffers). Bought in the shop |
/account | AccountPage | Sign in or create a customer account; visits (accountBookings), package and membership balances (accountBalances), data export (exportMyAccountData) |
/account/reset | AccountResetPage | Password reset (needs SMTP) |
/[...missing] | NotFoundPage | Storefront 404 |
Shop name, hours, colors, and logo come from getPublicStorefrontSettings. Booking rules for the public come from getPublicBookingEligibility. Whether deposits can be paid online comes from getPublicPaymentOptions.
Journey rules
- The storefront shows one shop: the single active shop with
isPublicset. - Guest bookings use a request key and proof so a retried request returns the same booking (
recoverGuestBooking,recoverAccountBooking). - Access tokens for a booking or queue ticket are stored in HttpOnly cookies (
sf_appt_<id>, kept 180 days, andsf_queue_<id>, kept 2 days). Status links carry only the record id. A separate client must keep these tokens server-side. - A service that requires a deposit is booked online when Stripe is set up for the shop. Otherwise the booking page asks the customer to book by phone.
- Stripe deposits are confirmed by reading the Checkout Session back from Stripe when the customer returns to
/appointment. - Storefront sign-up creates a login with name, email, phone, and password. It grants no role or shop access.
- Services, retail, packages, and memberships are paid at the counter.