Landing page (Vercel)
Quick answer
- 01What is it?
- Scaffolds a production-ready static landing page with working email capture form, analytics, and responsive design. The value is a focused slice of conversion optimization judgment, useful when several similar skills cover the same ground.
- 02Inputs
- Context for conversion optimization: your goals, audience, constraints, and any source material the skill asks for.
- 03Output
- A ready-to-use result for conversion optimization: the analysis, copy, or recommendations the agent produces.
Add this skill
Install as a package
Installs this one skill package for your coding agent, including any supporting files that skill ships with — not every skill in the repository. Read the tutorial.
$ npx skills add shipshitdev/skills --skill landing-page-vercelSkill instructions
The instruction file for this skill. The skill also includes other files you need to install to use it.
Landing Page (Vercel)
Create a static landing page with:
Contract
Inputs:
- Product name, tagline, audience, offer, and CTA
- Destination directory
- Form provider and analytics preference
Outputs:
- Static landing page files
- Form/analytics setup notes
- Deployment instructions
Creates/Modifies:
- Local landing page files and Vercel config
- Does not deploy production unless explicitly requested
External Side Effects:
- None during scaffolding
- May deploy to Vercel only after explicit deploy request
Confirmation Required:
- Before using external form/analytics identifiers
- Before running Vercel deploy commands
- Before overwriting an existing landing page directory
Delegates To:
-
project-init-orchestrator/npx @shipshitdev/v0for full Shipshit.dev product repos -
frontend-designfor custom visual design -
deployment-composerordeployfor deployment -
Structure: Semantic HTML5 + Modern CSS + Vanilla JS
-
Form: Working email capture (Formspree or custom endpoint)
-
Analytics: Plausible/Fathom ready
-
Design: Responsive, accessible, performant
-
Deploy: One-click Vercel deployment
What Makes This Different
This skill generates working landing pages, not empty templates:
- Real email capture form that actually submits
- Analytics integration ready to activate
- Responsive design tested on mobile
- Accessibility basics (WCAG 2.1 AA)
- Content from your PRD brief
Workflow
Phase 1: PRD Brief Intake
Ask the user for product details, then extract and confirm: product name, tagline, hero headline/subheadline/CTA, 3-5 features with descriptions, CTA type (Waitlist/Sign Up/Demo Request/Contact), and social proof preference (Testimonials/Logos/Stats/None). See references/full-guide.md (§ PRD Brief Intake Template) for the confirmation message format.
Phase 2: Content Generation
Generate complete landing page content across these sections:
- Hero - Headline, subheadline, CTA button, optional hero image
- Features - 3-5 feature cards with icons
- How It Works - 3-step process (optional)
- Social Proof - Testimonials or logos (optional)
- FAQ - 4-6 common questions (optional)
- CTA - Final call to action with form
- Footer - Links, copyright, social icons
Phase 3: Form Integration
Choose an email capture option:
- Formspree (Recommended - Free tier) - no backend needed, instant setup, email notifications
- Custom Endpoint - your own API, full control, requires backend
- Waitlist Service - Waitlist.email, Loops.so, ConvertKit
Phase 4: Quality Verification
Verify before handoff:
- HTML validates (W3C)
- Responsive on mobile
- Form submits successfully
- Analytics placeholders present
- Lighthouse score 90+
Usage
# Create landing page with PRD
python3 scripts/scaffold.py \
--out ./my-landing-page \
--name "ProductName" \
--tagline "Your compelling value proposition" \
--features "Feature1,Feature2,Feature3"
# Interactive mode
python3 scripts/scaffold.py --out ./my-landing-page --interactive
Generates index.html, styles.css, script.js, data.json, vercel.json, and an assets/ directory. See references/full-guide.md (§ Generated Structure) for the full file tree.
Key Patterns
Form submission handles loading/success/error states via fetch against the form's action URL; content lives in data.json (hero, features, faq) so copy edits never touch markup. See references/full-guide.md (§ Form Handling (JavaScript), § Data Structure (data.json)) for the full implementations.
Form Integration Guide
Formspree (Recommended): create a free account at formspree.io (https://formspree.io), create a form, and replace YOUR_FORM_ID in the HTML with the generated form ID.
Custom Endpoint: post { email } as JSON to a self-hosted API and handle the response. See references/full-guide.md (§ Option 2: Custom Endpoint) for the full snippet.
Analytics Setup
Add one script tag to the page head: Plausible (data-domain + plausible.io/js/script.js) for privacy-friendly analytics, or Fathom (cdn.usefathom.com/script.js + data-site). See references/full-guide.md (§ Analytics Setup) for both tags.
Deployment
cd my-landing-page
bunx vercel # Deploy (no global install needed)
bunx vercel --prod # Production deploy
vercel.json maps all static assets through @vercel/static, routes everything to index.html, and sets baseline security headers (X-Content-Type-Options, X-Frame-Options, X-XSS-Protection). See references/full-guide.md (§ Vercel Configuration (vercel.json)) for the full config.
CSS Variables
Theme tokens (--color-primary, --color-bg, --font-sans, --spacing-*, --max-width) drive the whole stylesheet — see references/full-guide.md (§ CSS Variables) for the full :root block.
Accessibility Checklist
- Semantic HTML structure
- Proper heading hierarchy (h1 → h2 → h3)
- Alt text for images
- Focus states for interactive elements
- Color contrast ratio 4.5:1 minimum
- Form labels and error messages
- Skip link for keyboard navigation
- Responsive text sizing (no fixed px for body text)
Performance Checklist
- No external CSS frameworks
- Minimal JavaScript
- Optimized images (WebP with fallback)
- System fonts (no web font loading)
- Lazy loading for below-fold images
- Preconnect for external resources
References
scripts/scaffold.py- Generation script (templates are inline)references/full-guide.md- Full PRD template, generated file tree, form/analytics/deploy config dumps, and CSS variable set
Supporting file: plugin.json
{ "name": "landing-page-vercel", "version": "1.0.1", "description": "Scaffold a production-ready static landing page with working email capture form, analytics, and resp", "author": { "name": "Ship Shit Dev", "email": "hello@shipshit.dev (mailto:hello@shipshit.dev)", "url": "https://shipshit.dev" }, "license": "MIT", "skills": "." }
Supporting file: references/full-guide.md
Landing Page (Vercel) — Full Guide
Full templates, config dumps, and integration snippets for the landing-page-vercel skill. See SKILL.md for the Contract, workflow phases, and quality checklists.
PRD Brief Intake Template
I'll help you create a landing page. Based on your description:
**Product:** [Name]
**Tagline:** [One-line value proposition]
**Hero Section:**
- Headline: [Main headline]
- Subheadline: [Supporting text]
- CTA: [Button text]
**Features:** (3-5)
1. [Feature 1]: [Description]
2. [Feature 2]: [Description]
3. [Feature 3]: [Description]
**CTA Type:** [Waitlist / Sign Up / Demo Request / Contact]
**Social Proof:** [Testimonials / Logos / Stats / None]
Is this correct? Any adjustments?
Generated Structure
my-landing-page/
├── index.html # Main landing page
├── styles.css # All styles (no framework)
├── script.js # Form handling + interactions
├── data.json # Content data (easy to edit)
├── vercel.json # Vercel configuration
├── assets/
│ ├── favicon.ico
│ └── og-image.png # Social sharing image
└── README.md # Deployment instructions
Form Handling (JavaScript)
document.addEventListener('DOMContentLoaded', () => {
const form = document.getElementById('signup-form');
const button = form.querySelector('button[type="submit"]');
const messageEl = document.getElementById('form-message');
form.addEventListener('submit', async (e) => {
e.preventDefault();
const originalText = button.textContent;
try {
button.textContent = 'Submitting...';
button.disabled = true;
const response = await fetch(form.action, {
method: 'POST',
body: new FormData(form),
headers: { 'Accept': 'application/json' }
});
if (response.ok) {
// Hide form and show success message
form.style.display = 'none';
messageEl.textContent = 'Thanks! We will be in touch.';
messageEl.classList.add('success');
} else {
throw new Error('Form submission failed');
}
} catch (error) {
button.textContent = originalText;
button.disabled = false;
messageEl.textContent = 'Something went wrong. Please try again.';
messageEl.classList.add('error');
}
});
});
Data Structure (data.json)
{
"name": "ProductName",
"tagline": "Your compelling value proposition",
"hero": {
"headline": "Build something amazing",
"subheadline": "The easiest way to create, launch, and grow your product.",
"cta": "Join the Waitlist"
},
"features": [
{
"icon": "zap",
"title": "Lightning Fast",
"description": "Built for speed from the ground up."
},
{
"icon": "shield",
"title": "Secure by Default",
"description": "Enterprise-grade security included."
},
{
"icon": "sparkles",
"title": "AI-Powered",
"description": "Smart features that learn from you."
}
],
"faq": [
{
"question": "When will you launch?",
"answer": "We're aiming for Q1 2026. Join the waitlist to be first to know."
}
]
}
Form Integration Guide
Option 1: Formspree (Recommended)
- Go to formspree.io (https://formspree.io)
- Create a free account
- Create a new form
- Copy your form ID
- Replace
YOUR_FORM_IDin the HTML
Option 2: Custom Endpoint
// In script.js, update the form action
const API_URL = 'https://your-api.com/api/waitlist';
form.addEventListener('submit', async (e) => {
e.preventDefault();
const email = form.querySelector('input[name="email"]').value;
const response = await fetch(API_URL, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ email })
});
// Handle response...
});
Analytics Setup
Plausible (Privacy-friendly)
<script defer data-domain="yourdomain.com" src="https://plausible.io/js/script.js"></script>
Fathom
<script src="https://cdn.usefathom.com/script.js" data-site="YOUR_SITE_ID" defer></script>
Deployment
Vercel (One-click)
cd my-landing-page
bunx vercel # Deploy (no global install needed)
bunx vercel --prod # Production deploy
Vercel Configuration (vercel.json)
{
"version": 2,
"builds": [
{ "src": "*.html", "use": "@vercel/static" },
{ "src": "*.css", "use": "@vercel/static" },
{ "src": "*.js", "use": "@vercel/static" },
{ "src": "assets/**", "use": "@vercel/static" }
],
"routes": [
{ "src": "/(.*)", "dest": "/index.html" }
],
"headers": [
{
"source": "/(.*)",
"headers": [
{ "key": "X-Content-Type-Options", "value": "nosniff" },
{ "key": "X-Frame-Options", "value": "DENY" },
{ "key": "X-XSS-Protection", "value": "1; mode=block" }
]
}
]
}
CSS Variables
:root {
--color-primary: #3b82f6;
--color-primary-dark: #2563eb;
--color-bg: #0f172a;
--color-bg-secondary: #1e293b;
--color-text: #f8fafc;
--color-text-muted: #94a3b8;
--font-sans: system-ui, -apple-system, sans-serif;
--max-width: 1200px;
--spacing-sm: 0.5rem;
--spacing-md: 1rem;
--spacing-lg: 2rem;
--spacing-xl: 4rem;
}
Common questions
How do I install Landing page (Vercel) in Cursor, Claude Code, or Codex?
Run npx skills add shipshitdev/skills --skill landing-page-vercel in the project where you want it, then ask your agent for the skill by name. The --skill flag installs only Landing page (Vercel), not every skill in the repository.
Where does Landing page (Vercel) come from and what license is it under?
Landing page (Vercel) comes from the shipshitdev/skills repository on GitHub. That repository has 35 GitHub stars. No license was detected on the source repository, so check with the author before redistributing it.
Prefer plain text? Read the Landing page (Vercel) guide as markdown.