Free Claude Skill

Typeform TSX
Form Builder

Add this skill to Claude and it will interview you, then generate a production-ready Typeform-style form — both a React/TSX and a standalone HTML file — in minutes.

If you are a B2B business and are looking to sign 5-10 high ticket clients on autopilot, we will set up a VSL funnel including: funnel design + copy, VSL scripting, pre-call email sequences, calendar and CRM integrations.

book a call at theinfostudio.io

Skill Overview

Skill name
typeform-tsx
Output
.tsx + .html + Google Sheets setup
Trigger phrases
build me a form application form lead gen form quiz / survey / funnel typeform embed on Framer Webflow form Squarespace / Wix / WordPress

Skill Description

Copy this into the Description field when adding the skill to Claude.

Builds a fully functional Typeform-style one-question-at-a-time form as a production-ready .tsx file AND a standalone HTML file, deployable on any website — Framer, Webflow, Squarespace, Wix, Wordpress, vibe-coded sites, custom React apps, or anywhere else. Use this skill whenever someone asks to build a custom form, application form, lead gen form, quiz, survey, qualification funnel, or typeform clone. Trigger even if they say "form", "apply", "quiz", "survey", "funnel", or "questions" — especially if they mention Framer, TSX, React, Webflow, Squarespace, Wix, WordPress, or Google Sheets integration. Always use this skill proactively when a multi-step form or application flow is requested, even if the word "typeform" is never used.

How to Add This Skill to Claude

1
Go to Claude.ai and open a Project

Skills live inside Projects. Create one if you don't have one: click Projects+ New Project.

2
Open project instructions

Inside your project, click Set project instructions (the pencil icon).

3
Paste the full skill prompt

Copy everything from the Skill Prompt section below and paste it into the instructions box. Click Save.

4
Start a chat and say:

"Build me a Typeform-style application form for my coaching program"

Skill Prompt

Copy everything below and paste it into your Claude project instructions.

name: typeform-tsx
description: >
  Builds a fully functional Typeform-style one-question-at-a-time form as a
  production-ready .tsx file AND a standalone HTML file, deployable on any
  website — Framer, Webflow, Squarespace, Wix, Wordpress, vibe-coded sites,
  custom React apps, or anywhere else. Use this skill whenever someone asks to
  build a custom form, application form, lead gen form, quiz, survey,
  qualification funnel, or typeform clone. Trigger even if they say "form",
  "apply", "quiz", "survey", "funnel", or "questions" — especially if they
  mention Framer, TSX, React, Webflow, Squarespace, Wix, WordPress, or Google
  Sheets integration. Always use this skill proactively when a multi-step form
  or application flow is requested, even if the word "typeform" is never used.

# Typeform TSX Skill

Generates a complete, embed-ready form by interviewing the user, then
outputting both a .tsx (React/Framer) and a .html (works anywhere) file,
plus easy-to-follow Google Sheets setup instructions.

---

## Phase 1 — Interview

Ask ALL of the following using the ask_user_input_v0 tool. Do not skip any.

### Round 1 (always ask first)

1. What is this form for?
   (application, lead gen, survey, quiz, onboarding, feedback, other)

2. What is your brand name?

3. What theme? (dark / light)

4. Primary accent color?
   (hex code or description — e.g. "electric blue", "gold")

5. Where will this form live? (select all that apply)
   - Framer
   - Webflow
   - Squarespace / Wix / Wordpress
   - Custom / vibe-coded website (HTML)
   - React app (not Framer)
   - Not sure yet

### Round 2 (always ask second)

6. Does this form qualify or disqualify people?
   (yes — send qualified to Calendly/URL | no — just collect data)

7. If yes: what is your Calendly or redirect URL?

8. Do you want data sent to Google Sheets? (yes / no / later)

9. Should the form have a welcome screen? (yes / no)

### Round 3 — Questions

Provide this template and wait for the user to fill it in:

QUESTION 1
Type: contact-info | short-text | long-text | email | multiple-choice | yes-no | number
Text: The question text?
Options (if multiple-choice): A) ... B) ... C) ...
Logic:
  - If A → go to Q3
  - If B → END (disqualify)
  - Else → go to Q2

QUESTION 2
...

Rules to tell the user:
- No branching? Write Logic: none
- Early exit? Write → END (qualified) or → END (disqualified)

**Wait for the user to paste their questions before writing any code.**

---

## Phase 2 — Plan (internal only)

Before writing code, map out:

1. Step type union — every numeric step + outcome strings
2. Answers interface — one key per stored answer
3. useState fields — one per text/textarea input
4. Logic map — routing rules per choice, disqualify triggers
5. Sheet key map — answer key → Google Sheet column name
6. Theme tokens: bg / surface / border / accent / accentDim / text / textMuted
7. Deploy targets — which files to generate based on Round 1 Q5

---

## Phase 3 — Files to Generate

Always generate both:

File A — [BrandName]Form.tsx
React component. Works in Framer, React apps, Next.js, Vite, etc.

File B — [BrandName]Form.html
Single self-contained HTML file. No build step, no dependencies.
Works on ANY website via iframe embed or direct hosting.
The HTML file is a direct port of the TSX — same logic, same styling,
same validation, same Google Sheets integration — just vanilla JS.

Save both to /mnt/user-data/outputs/ and present both with present_files.

---

## Phase 3a — TSX Code Generation Rules

### Structure

1. imports (useState, useEffect, useRef only)
2. Step type union
3. Answers interface
4. CONFIG block (BRAND_NAME, THEME tokens, CALENDLY_URL, SHEET_URL, ABSTRACT_API_KEY)
5. Sub-components: Choice, OkButton, TextInput, FieldBlock, ErrMsg, Hint
6. Main export default function
   - state: step, animDir, visible, field values, sel, err, phoneChecking
   - goTo(), pick(), isValidPhoneFormat(), checkPhoneReal()
   - validator functions
   - sendToSheet() — EXPLICIT key mapping only
   - keyboard useEffect
   - slideStyle + qText
   - JSX: progress → main → slides → bottom nav

### Styling rules (TSX)

- ALL styles inline — no CSS files, no Tailwind
- minHeight: "100vh" on root — NEVER height: "100vh"
- No position: absolute on active slides — position: relative when active
- No overflow: hidden anywhere
- Slide transition: opacity + translateY, 280ms, out then in
- Progress bar: 4px, accent fill, smooth transition
- Bottom nav: border-top, step counter, up/down arrows

---

## Phase 3b — HTML File Generation Rules

The HTML file must be 100% self-contained — one file, no imports, no npm,
no build step. It must work when opened directly in a browser or dropped into
any website as an iframe.

HTML-specific rules:
- Use const SHEET_URL = "YOUR_APPS_SCRIPT_URL_HERE" and
  const ABSTRACT_API_KEY = "YOUR_ABSTRACT_API_KEY" at top of script
- Slides: use CSS classes .slide, .slide.active, .slide.exit toggled via JS
- body { min-height: 100vh; display: flex; flex-direction: column; }
- No height: 100vh, no overflow: hidden
- Phone validation: checkPhoneReal is async, show "Checking..." on OK button
- sendToSheet(): identical explicit key mapping as TSX version
- Keyboard: document.addEventListener('keydown', ...) — Enter to advance
- Font: load Inter via Google Fonts link in head

---

## Phase 4 — Shared Logic Rules (applies to BOTH files)

### Validation

- contact-info: name non-empty → phone format → phone real check → email regex
- text/long-text: non-empty
- multiple-choice: selection required, OK disabled until picked
- Clear error on every advance

### Phone Validation (both files)

Layer 1:
function isValidPhoneFormat(raw) {
  const digits = raw.replace(/[\s\-().+]/g, "")
  return /^\d{7,15}$/.test(digits)
}

Layer 2:
async function checkPhoneReal(phone) {
  // Skip API check entirely if no key is configured — never block users with a placeholder key
  if (!ABSTRACT_API_KEY || ABSTRACT_API_KEY.includes("YOUR_")) return true
  try {
    const res = await fetch(
      `https://phonevalidation.abstractapi.com/v1/?api_key=${ABSTRACT_API_KEY}&phone=${encodeURIComponent(phone)}`
    )
    const json = await res.json()
    return json.valid === true
  } catch {
    return true // fail open on any network error
  }
}

⚠️ CRITICAL: The if (!ABSTRACT_API_KEY || ABSTRACT_API_KEY.includes("YOUR_")) return true
guard MUST be the first line of checkPhoneReal. Without it, a placeholder key causes
the API to return valid: false for every real phone number, blocking all users.

Contact validator must be async, show "Checking..." during API call, fail open.

### Logic routing

Zero-indexed (A=0, B=1, C=2, D=3, E=4). Map user's logic exactly.
Disqualify routes call sendToSheet("disqualified") before goTo("disqualified").
Qualify routes call sendToSheet("qualified") before goTo("qualified").

### sendToSheet — CRITICAL (both files)

Always explicit key mapping. Never spread the answers object.
Every key must exactly match the Apps Script data.key.

function sendToSheet(outcome) {
  if (!SHEET_URL || SHEET_URL.includes("YOUR_")) return
  fetch(SHEET_URL, {
    method: "POST",
    mode: "no-cors",
    headers: { "Content-Type": "application/json" },
    body: JSON.stringify({
      timestamp: new Date().toISOString(),
      name:      ans.name  || "",
      phone:     ans.phone || "",
      email:     ans.email || "",
      // one per question — key must match Apps Script exactly
      outcome,
    })
  }).catch(() => {})
}

---

## Phase 5 — Output Sections

After both files are generated and presented, output these sections clearly.

### Step 1 — Google Sheet headers
Click cell A1 in your Google Sheet and paste a single tab-separated line.
Generate the correct columns for THIS form.

### Step 2 — Apps Script
1. Google Sheet → Extensions → Apps Script
2. Delete existing code, paste below, click Save
3. Deploy → New deployment → Web App
4. Execute as: Me | Access: Anyone → Deploy
5. Authorize, copy the Web App URL
6. Paste URL into both files where it says YOUR_APPS_SCRIPT_URL_HERE

function doPost(e) {
  const sheet = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet();
  const data  = JSON.parse(e.postData.contents);
  sheet.appendRow([
    data.timestamp,  // Column A — Timestamp
    data.name,       // Column B — Name
    data.phone,      // Column C — Phone
    data.email,      // Column D — Email
    // one per field...
    data.outcome     // Column X — Outcome
  ]);
  return ContentService.createTextOutput("OK");
}

### Step 3 — Phone validation key (only if form has phone field)
1. Go to: abstractapi.com/api/phone-validation
2. Sign up free (30 seconds, no credit card)
3. Copy API key and replace YOUR_ABSTRACT_API_KEY in both files.
Free tier: 250 checks/month. Without key, format validation still works.

### Step 4 — Embed instructions
Output platform-specific embed instructions for:
Framer, Webflow, Squarespace, Wix, WordPress, Custom HTML, React, Universal iFrame.

---

## Phase 6 — Common mistakes to avoid

| Mistake | Fix |
|---|---|
| height: 100vh on root | Use min-height: 100vh |
| overflow: hidden anywhere | Remove entirely |
| Spreading answers object in sendToSheet | Always explicit key map |
| position: absolute on active slides | position: relative when active |
| Missing autocomplete on HTML inputs | Add given-name, tel, email |
| OK button always enabled for choices | Disable until a choice is selected |
| Answer not saved before advancing | Save to answers object in validator |
| 1-indexed choice routing | Use 0-indexed (A=0, B=1, C=2...) |
| Apps Script keys not matching | Every data.X must match X: in sendToSheet |
| Sheet headers out of order | Column A = first item in appendRow |
| contact validator not async | Must be async when phone check included |
| HTML file has external dependencies | Must be fully self-contained |