Skip to content
← Back to work

Marketing Site · Caffeinated Petals

Caffeinated Petals — Oklahoma City florist intake & subscription site

A React Router 7 + Vite SSR site for a bespoke OKC florist: separate intake flows for weddings, sympathy, and recurring subscriptions, all routed to the florist via Resend with no CRM in the middle.

React Router 7ViteResendContentful schemaE-commerce intake
Caffeinated Petals — marketing site screenshot

The problem

Caffeinated Petals is an Oklahoma City florist specializing in bespoke arrangements for weddings, funerals, and events, plus a recurring "Petals on Repeat" subscription for homes and businesses. The challenge is structural: a wedding inquiry, a sympathy order, and a weekly subscription are three different sales conversations. The previous site funnelled everything to one generic contact form — and lost the wedding inquiry signal in a stream of one-off questions.

What we built

A purpose-built marketing and intake site at caffeinatedpetals.comwith separate flows for event quote requests, individual service pages (weddings, funerals, events, everyday), and a dedicated subscription path with three real tiers (weekly, bi-weekly, monthly). Quote requests capture event date and ceremony type up front, so the florist walks into the call already knowing what kind of conversation it is.

What the site has to do

  • Route wedding inquiries, sympathy orders, and subscription signups into three distinct intake flows.
  • Communicate "local farm sourcing" as a real value, not a marketing line.
  • Carry a gallery of real arrangements — the most important social proof in floral.
  • Stay editable as the service menu evolves.

Technical highlights

React Router 7 (server) instead of Next.js

Caffeinated Petals runs on React Router 7 with server-side rendering on Vite, not Next.js. The loader/action pattern fits a form-heavy service business cleanly: every form is a real HTTP action, every page is a real loader, and there is no client-side framework abstraction in between. Same hosting story (Vercel), lighter runtime, more explicit data flow.

Quote and subscription forms post directly to Resend

Both the wedding-quote flow and the subscription signup post to a React Router action that sends a formatted email to the florist via Resend, with date-fns formatting event dates into a human-readable subject line. No CRM in the middle, no third-party form platform. The first response a customer gets is from the florist, not from a SaaS tool.

Contentful-shaped data, served as static JSON

The subscription page is rendered from JSON shaped to match a Contentful schema, with the option to flip back to live Contentful reads when the editorial cadence justifies it. This is the pragmatic middle: same component contracts as a headless CMS build, none of the per-month CMS cost while content barely changes. When the volume changes, the wiring already exists.

Stack

  • React Router 7 (SSR mode) + React 19 + TypeScript
  • Vite for build + Tailwind CSS 4 (@tailwindcss/vite)
  • Resend for quote-form and subscription-signup email
  • Embla Carousel for the arrangement gallery
  • Framer Motion for entrance animations on pricing tiers
  • Radix UI primitives + shadcn-style component patterns
  • Vercel for hosting

Outcome

Caffeinated Petals is live at caffeinatedpetals.comtaking real wedding inquiries, sympathy orders, and recurring subscription signups across three separate intake flows, with email landing in the florist's inbox formatted and ready to action.

Why it matters to clients

Local-service businesses get pushed toward template platforms that compress every customer type into one funnel. Caffeinated Petals is the proof that a small operator can have a real, hand-built site that respects the actual shape of their business — three distinct sales conversations, three distinct flows — without a monthly retainer and without a platform that owns their forms.