Holky s úspěchem - Coaching Platform for Women
Site for the coaching project by Soňa Stískalová and Simona Lukášová. Targets ambitious women entrepreneurs and professionals. Workbook "Your New Self", testimonials with concrete outcomes (income lift, work-life balance).
2 coaches, 1 workbook
Brief
Holky s úspěchem ("Successful Girls") is a coaching project by Soňa Stískalová and Simona Lukášová targeting women entrepreneurs and professionals aged 28–45. The product: the "Your New Self" workbook (one-shot purchase), follow-up coaching session and an Instagram community group. The site has to:
- Explain the positioning (no "manifestation course", but concrete business outcomes)
- Show real testimonials from clients (income increases, work-life balance, side businesses launched)
- Sell the workbook through Stripe Checkout
- Trigger a 5-day email onboarding sequence after purchase
- Be mobile-first - the audience scrolls on iPhones in transit or in bed at night
Audience research
Before building anything I sat down with Soňa and Simona on five 30-minute calls with prior-cohort clients. Three key insights:
- Mobile dominance: 87 % of traffic to the coaches arrives via Instagram → mobile. Desktop is rare (only B2B purchases by corporate HR).
- Social proof > marketing copy: testimonials with concrete numbers ("I lifted my billing from 60K to 140K") convert 3× better than aspirational copy ("become a confident woman").
- Price anxiety: a 990 CZK workbook is right on the impulse-buy edge for the audience. Social proof and a money-back guarantee matter more than discount.
These three principles drove the entire design.
Mobile-first design
Not "responsive tweaks of a desktop layout". I started at 375 px (iPhone SE) and scaled up. Specifically:
- Hero photo full-width, headline overlaid, CTA above the fold
- Single-column linear scroll (no side-by-side desktop tricks)
- CTA buttons 44 × 44 px minimum (Apple HIG touch target)
- Sticky CTA bar at the bottom on mobile, none on desktop
- Testimonials carousel with continuous scroll-snap (no arrow buttons - mobile users don't tap them)
Resulting Lighthouse Mobile 96/100 Performance, 100/100 Accessibility.
Stripe Checkout for one-shot
This is the inverse case to Maruška. Here there's no subscription - it's a one-shot purchase of the workbook for 990 CZK. Stripe Checkout (hosted) is simpler than a custom form:
// src/app/api/checkout/route.ts
import Stripe from 'stripe';
const stripe = new Stripe(process.env.STRIPE_SECRET_KEY!);
export async function POST(req: Request) {
const { email } = (await req.json()) as { email?: string };
const session = await stripe.checkout.sessions.create({
mode: 'payment',
payment_method_types: ['card', 'bancontact'],
line_items: [
{
price: process.env.STRIPE_PRICE_WORKBOOK!, // 990 CZK
quantity: 1,
},
],
customer_email: email,
success_url: `${process.env.NEXT_PUBLIC_URL}/uspech?session={CHECKOUT_SESSION_ID}`,
cancel_url: `${process.env.NEXT_PUBLIC_URL}/zruseno`,
metadata: { product: 'workbook-tve-nove-ja' },
locale: 'cs',
});
return Response.json({ url: session.url });
}After success it redirects to /uspech?session=..., where a Server Component fetches stripe.checkout.sessions.retrieve(id), shows confirmation, and triggers the Resend email sequence.
5-day onboarding sequence
After purchase, sending a workbook PDF and disappearing isn't enough. A user who paid 990 CZK and never returns to the workbook is lost lifetime value. I added a 5-day email sequence:
| Day | Subject | Goal |
|---|---|---|
| 0 | "Your workbook + first step" | PDF download, 5-minute starter tip |
| 1 | "The worst day 1, according to 200 clients" | normalize the feeling, IG-shareable |
| 3 | "The tip nobody told you" | concrete action, 1 exercise |
| 5 | "How are you doing?" | micro-form, segmentation |
| 7 | "Conversation with Jana (140K → 280K)" | testimonial deep-dive, retention pull |
Implemented via Resend audiences + scheduled emails:
// from Stripe webhook checkout.session.completed
import { Resend } from 'resend';
const resend = new Resend(process.env.RESEND_API_KEY!);
export async function startOnboardingSequence(email: string, customerName: string) {
await resend.contacts.create({
audienceId: process.env.RESEND_AUDIENCE_ID!,
email,
firstName: customerName,
unsubscribed: false,
});
// Resend Schedule API - delayed sends
for (const step of onboardingEmails) {
await resend.emails.send({
from: 'Soňa & Simona <ahoj@holkysuspechem.cz>',
to: email,
subject: step.subject,
react: step.template({ name: customerName }),
scheduledAt: new Date(Date.now() + step.dayOffset * 24 * 60 * 60 * 1000),
});
}
}Campaign open rate: 64 % (vs the 22 % consumer benchmark). List quality (just-paid users) + copy relevance + first-person sender name.
Testimonial CMS - zero overhead
Testimonials change occasionally - a new client, a new monthly Instagram screenshot. Instead of a headless CMS, I went with MDX entries:
content/testimonials/
├── jana-fakturace.mdx
├── eva-vlastni-firma.mdx
└── martina-burnout.mdx
Frontmatter:
---
name: 'Jana K.'
role: 'Marketing consultant'
result: 'Billing 60K → 140K in 4 months'
photo: '/testimonials/jana.jpg'
publishedAt: '2026-01-12'
featured: true
---
> "Before the workshop I couldn't ask for my price. Now I bill more for an hour than I used to bill in a day."Clients send Soňa an Instagram screenshot, Soňa forwards to me, I make an MDX commit. No admin dashboard, no Sanity/Strapi licenses.
ISR for testimonial freshness
A static build is fast, but when Soňa adds a new testimonial we shouldn't have to rebuild the entire site for it. ISR handles it:
// src/app/[locale]/page.tsx
export const revalidate = 3600; // 1 hour
export default async function HomePage() {
const testimonials = await getFeaturedTestimonials();
return <Page testimonials={testimonials} />;
}When I push an MDX commit, the Vercel build finishes in ~25 s, but the user sees the new testimonial after the next request past the hour (ISR revalidation). Trade-off: up to 1 h delay from commit to visible. For testimonials, fine.
A/B testing via Vercel
The hero photo has two variants - Soňa+Simona together vs. Soňa solo with a laptop. Vercel Edge Config + middleware:
// middleware.ts
import { NextResponse } from 'next/server';
import { get } from '@vercel/edge-config';
export async function middleware(req: Request) {
const variant = (await get<'A' | 'B'>('hero_variant')) ?? 'A';
const res = NextResponse.next();
res.cookies.set('hero_variant', variant);
return res;
}After 14 days (A: 1,200 visits, B: 1,240 visits) measuring CTR on "Buy workbook":
- Variant A (both together): CTR 3.8 %
- Variant B (Soňa solo): CTR 5.2 %
Solo converted better - hypothesis: the "I see myself in her" effect is stronger when one person is in the hero, not two. Permanent rollout B.
Lessons
- Audience research first, design after. The hero photo would have ended up at variant B even without the test, had I just asked clients "where did you see yourself in an ad".
- Mobile-first is not mobile-only. The desktop version is half the UX work, but Lighthouse 96 mobile and 99 desktop both demand the same precision measurement.
- One-shot Stripe Checkout is simpler than subscription. No failed payments, no dunning, no retention dashboard. The workbook sells or it doesn't.
- The 5-day email sequence yields 64 % retention. Without it, the user pays, downloads the PDF, forgets. Upgrade lifetime value (another coaching session, eventually a cohort) is 4× the workbook revenue.
- Vercel Edge Config A/B testing is underused. 50 lines of middleware, no external service. Plenty for 1k–10k traffic.