All Startup Ideas

User Onboarding Flow Builder

No-code product tour and onboarding flow builder. AI generates flows from screenshots. Indie-priced under Appcues. Weekend MVP guide + prompts.

Activation is where most SaaS products die quietly. The average SaaS hits 5–10% signup-to-active conversion. Best-in-class products hit 30%+, and the difference is almost entirely onboarding. A great product tour shown at the right moment lifts day-7 retention 15–25 points. The founders who know this also know they cannot justify Appcues at $249/month or Pendo at "call us" pricing. So they do one of three things, all bad. They ship no onboarding at all and hope the product speaks for itself. They hack together a modal with Intro.js that breaks every time the app UI changes. Or they pay an agency $5K to build a single onboarding flow that gets stale by the next product release. None of these loops produce a learning system. None tell the founder which step users drop off at.

Built for Developers, Solo Founders.

Suggested stack: Next.js 14 (admin app), Vanilla JS widget (runtime), Supabase, GPT-4 Vision for flow generation, Cloudflare CDN for widget.js, Stripe Billing + usage events. Weekend scope: about 12 hours.

The Problem

Activation is where most SaaS products die quietly. The average SaaS hits 5–10% signup-to-active conversion. Best-in-class products hit 30%+, and the difference is almost entirely…

The Solution

A multi-tenant no-code builder where the admin paints tooltips, modals, checklists, and hotspots onto a live preview of their app, and the system emits an embeddable JS snippet.…

Market Research

Appcues raised $30M+ Series B (2021) with public ARR estimates in the $20M+ range. Pendo is a $2.6B-valued unicorn. Category validation is decisive.

Competitive Landscape

Appcues / Pendo — Category leaders. Appcues raised $30M+ and powers 1,700+ customers. Pendo is $2.6B unicorn with enterprise focus. Deep features, polished editors, opaque…

Business Model

Free ($0) — 1 flow, 1,000 tour views/mo, “Powered by” badge, 3 AI generations/mo

Recommended Tech Stack

Next.js 14 (admin app) — Admin dashboard: flow library, visual editor (drag-drop steps + element picker from screenshot), analytics. Server Actions for flow CRUD. Vercel hosting.

AI Prompts to Build This

Copy these build prompts into Claude, Cursor, or your AI coding tool. Create a free account to unlock the full research behind them.

  1. 1. Admin App + Editor

    Create a Next.js 14 App Router admin SaaS for building product tours. Supabase backend, Tailwind, TypeScript.
    
    Schema:
    - tenants(id, slug, owner_user_id, site_url, stripe_customer_id, plan ENUM[free,solo,team], monthly_views_used INT, created_at)
    - flows(id, tenant_id, name, status ENUM[draft,live,paused], trigger_type ENUM[url_match,event,manual], trigger_config JSONB, segment_rules JSONB)
    - steps(id, flow_id, position INT, step_type ENUM[tooltip,modal,hotspot,checklist], target_selector TEXT, title, body, buttons JSONB)
    - tour_events(id, tenant_id, flow_id, step_id, event ENUM[fired,advanced,completed,dismissed], visitor_id, occurred_at)
    
    Routes:
    - /dashboard (flow list, quick stats)
    - /flows/[id]/edit (visual editor + step list)
    - /flows/[id]/analytics (funnel: started → step 1 → step 2 → completed)
    - /install (snippet copy, docs)
    - /settings (billing, team)
    
    Visual editor:
    - Left panel: ordered step list, drag to reorder, add/remove.
    - Center panel: iframe of tenant.site_url (fallback: image of screenshot). On hover, show element outline; click to set target_selector via unique CSS path generator.
    - Right panel: step properties (type, title, body, buttons, transition).
    
    Preview mode: simulates the tour running on the site_url preview. Use postMessage from iframe to parent for event tracking.
  2. 2. Screenshot-to-Flow (GPT-4 Vision)

    Implement screenshot-to-flow AI generation. This is the category differentiator.
    
    User flow:
    1. On /flows/new, user uploads a screenshot of their app dashboard (drag-drop, PNG/JPG up to 4MB).
    2. Upload to Supabase Storage; get signed URL.
    3. Call OpenAI Chat Completions with gpt-4o, image_url pointing to the signed URL. System prompt:
    "You analyze SaaS dashboard screenshots and generate 5-step product tours for new users. For each step, identify a key UI element and write a friendly 1-2 sentence tooltip. Return JSON matching: {steps: [{position: 1-5, target_description: 'CSS selector or human description of the element', element_type: 'button|input|card|menu|chart|other', title: 'short', body: 'longer friendly microcopy', reason_for_step: 'why show this step'}]}. Prioritize the elements that enable the user's first success moment."
    4. Use response_format: {type: 'json_schema'}. Validate structure.
    5. Render the 5 generated steps in the visual editor. target_description is prefilled as a placeholder; user clicks on the element in the iframe preview to replace with a real selector.
    6. Show the reason_for_step as an inline comment on each step (coaching, not committed to the flow).
    
    Cost: ~$0.03 per generation. Cap Free tier at 3/month; no cap on Solo/Team. Cache the generation by image hash so re-uploads don't cost twice.
  3. 3. Embeddable JS Runtime

    Build the standalone widget runtime. This is what ships in customer apps.
    
    widget.js (vanilla, ~25KB minified, no framework):
    
    (function() {
     const tenantId = document.currentScript.getAttribute('data-tenant');
     const visitorId = getOrCreateVisitorId(); // localStorage
     const apiBase = 'https://api.product.com';
    
     // 1. Fetch live flows for this tenant (cached 60s at CDN)
     fetch(`${apiBase}/v1/flows?tenant=${tenantId}`).then(r => r.json()).then(({flows}) => {
     // 2. For each flow, check trigger conditions vs current URL / user segment
     flows.forEach(flow => evaluateAndRun(flow, visitorId));
     });
    
     function evaluateAndRun(flow, visitorId) {
     // Trigger check: url_match uses minimatch on window.location.pathname
     if (!matchesTrigger(flow)) return;
     // Segment check: simple key/value match against window.__product_identify__ or cookie
     if (!matchesSegment(flow, visitorId)) return;
     // Mount a Shadow DOM root so our styles don't leak
     const root = document.createElement('div');
     root.attachShadow({mode: 'open'});
     document.body.appendChild(root);
     runTour(flow, root.shadowRoot, visitorId);
     }
    
     function runTour(flow, root, visitorId) {
     let stepIndex = 0;
     renderStep(flow.steps[0]);
     // Send 'fired' event
     trackEvent('fired', flow.id, flow.steps[0].id, visitorId);
    
     function renderStep(step) {
     const target = document.querySelector(step.target_selector);
     if (!target) {
     // Retry with MutationObserver for 5 seconds, then skip
     return waitForElement(step.target_selector, 5000).then(el => renderStep({...step, _target: el})).catch(() => advance());
     }
     // Position tooltip/modal relative to target; attach Next/Prev/Skip buttons.
     //... render Shadow DOM content...
     }
     }
    
     function trackEvent(event, flowId, stepId, visitorId) {
     navigator.sendBeacon(`${apiBase}/v1/events`, JSON.stringify({tenantId, event, flowId, stepId, visitorId, ts: Date.now()}));
     }
    })();
    
    Customer embed:
    
    Identify API (optional):
    
    Test matrix: React SPA (Next.js dev), Vue SPA (Nuxt), vanilla static site, Shopify/Webflow. Runtime should handle all four without modification.