Why I built it
Iconic Web Studios is my web design & development agency. We build websites & apps for small businesses & solo founders. I built Launch to fix one of the slowest parts of that work: collecting content. Text arrives in long email threads, photos come in through texts & file-sharing links, details get lost & nobody can easily tell what’s still missing. Questions & answers end up scattered across email, phone calls & texts, separate from the project itself.
Launch puts all of that in one place:
- Each project has a single home for its content, files & conversation.
- Clients can see exactly what’s done & what’s left. They can save their work & come back whenever they like.
- Iconic gets complete, organized content in a predictable structure, so building can start without a round of follow-up questions.
- It feels premium & simple for clients, not like a CMS or a complicated SaaS dashboard.
It isn’t a website builder. Clients don’t design or publish anything in Launch. They supply the raw material & Iconic builds the site from it.
The client side
Launch was built for one of Iconic’s products, the Launch Page: a well-defined, one-page website for clients who don’t need a larger or more complex site. It’s separate from our regular website tiers, which are fully custom. Every Launch Page has the same core sections & clients can add up to five more from a set list.
Iconic creates a private account for each client. After signing in, clients see their projects, each with a progress bar & a status: Not Started, In Progress, Submitted or Complete. Each project also has its own message thread, so clients can ask questions & talk with the Iconic team without leaving Launch.
In Project Setup, they enter their business details once. Those details pre-fill matching fields later, so their phone number automatically shows up in the Hero & Contact sections. Then they choose the sections for their one-page site. Header, Hero, Contact & Footer are always included, plus up to five of these: About, Services, Gallery, Testimonials, FAQ, Hours & Location, Call to Action or a Custom Section. If a client removes a section that already has content, Launch asks first, so no work disappears without warning.
Adding content
Clients use Launch to send Iconic everything we need to build their Launch Page & to talk with our team along the way. In Content & Files, a sidebar lists every section with its status. Each section gets a form designed for its content:
- Testimonials & FAQs are added one entry at a time. FAQs can also be grouped into topics.
- Hours & Location has a weekly hours editor with 30-minute steps & optional breaks.
- Every section has drag-and-drop uploads for images, videos & files, plus a “Notes for Iconic” field.
- Work saves automatically, with a visible “Saving…” / “Saved” indicator.
- Clients mark each section finished. Finished sections lock & have to be unlocked to edit again.
When everything is done, the client submits the project. It locks on their side & Iconic is notified.
The admin side
For the Iconic team, Launch plays a complementary role to the client side. We use it to receive each client’s material for their Launch Page & to communicate with them.
Admins create client accounts & projects, see every project’s status & unread message count, review submitted content, download files, add internal notes & mark projects complete.
Admins also manage users: their contact details, whether they’re OK with texts & their notification preferences. They can also deactivate accounts. Internal notes about a client are visible to admins only.
Messaging
Each project has one message thread between the client & Iconic, with unread indicators. New messages appear instantly.
There’s no separate inbox. Messages live inside each project, next to its content & files, so every conversation stays tied to the work it’s about. On the admin side, the unread badge counts projects, not messages. If the badge shows 3, three projects need attention. That tells an admin what they need to look at next. Completed projects still count toward it, so nothing gets missed just because a project is finished.
I wanted messaging to feel like part of Launch, not like Slack or Messenger, so it uses the same cards, type & colors as the rest of the app. It’s also not meant to be a full chat app, so I left a lot out of the first version on purpose: attachments, rich text, editing, deleting, reactions, typing indicators, online status & read receipts. Each one could have been added, but leaving them out kept messaging focused & reliable. Messages are permanent, so the thread is a trustworthy record of what was agreed. If someone makes a mistake, they correct it with a new message.
Email notifications are batched. Unread messages are grouped into one email roughly every 15 minutes instead of one per message & nothing more goes out for that thread until the recipient reads it. Clients can also turn notifications off.
Under the hood
Front end
- React 19 & TypeScript
- Vite
- React Router 7
- TanStack Query for data fetching & caching
- Tailwind CSS 4
- Radix UI primitives for dialogs & menus
Back end · Supabase
- Auth: invite-only email & password sign-in, password reset
- PostgreSQL with Row Level Security on every table
- Storage: private bucket, expiring signed links, 50MB per-file limit
- Realtime for instant messages & live unread badges
- Edge Functions (Deno) for admin tools & notifications
- pg_cron & pg_net to schedule batched emails
Email goes out through Resend. The app is deployed as a static single-page app at launch.iconicweb.dev.
Engineering choices
- Security in the database. Access rules live in Postgres Row Level Security, so even a bug in the interface couldn’t show one client another client’s data. Admin-only notes live in their own table, so they can never leak through a client’s access to their own profile.
- Built in phases. I built & validated the full front end against mock data behind a small service layer, then switched it to Supabase without rewriting the interface.
- Tracking unread messages. Instead of a “read” row for every message & every user, Launch keeps one bookmark per user per project: the last message they’ve seen. Unread counts stay simple & fast as conversations grow.
- Batched notifications. Batching & per-user preferences keep clients from being flooded with email.
- Specced for growth. I designed the data model with section-specific conversations & text message notifications in mind. It already stores clients’ cell numbers & whether they’re OK with texts, so both features can be added without restructuring anything.
Design
I wanted Launch to feel warm & personal, not like a CMS or a complicated SaaS dashboard. Instead of the cool blues & grays most business software uses, I went with soft, warm neutrals & deep, earthy accents. The result feels calm & inviting. The contrast between light backgrounds & dark accents keeps text & buttons easy to read. Clients & admins see slightly different background tones, so it’s always clear which side of the app you’re on.
The type follows the same idea. Headings use a bold, modern typeface with some personality, so each screen has a clear starting point. Body text is set in a clean, friendly sans-serif that stays readable through long forms. Small details use a monospaced font, which sets them apart from the content clients are entering & makes them easy to scan.
I built accessibility in from the start. Unread & error states never rely on color alone, everything works by keyboard with labeled controls & text meets a 4.5:1 contrast ratio on every background.
It has light & dark modes. It’s also fully responsive, including mobile versions of every section form.
I designed the screens in Claude Design, then built & refined them in code.