Skip to main content
Shipnative includes a marketing landing page built with Vite + React + Tailwind CSS. Use it to collect emails before launch (waitlist mode) or showcase your app after it’s live (launch mode).
For vibecoders: yarn setup configures this for you. Just run yarn web to see your marketing page at localhost:5173.
Which landing page is this?
  • apps/web/ - Your app’s marketing page (this guide)
  • landing_page/ - Shipnative’s own marketing site (not yours)

Two Modes

The marketing page has two modes you can switch between:

Waitlist Mode (Pre-Launch)

Perfect for collecting early user emails before your app launches. Features:
  • Email capture form with validation
  • Success confirmation message
  • App screenshot showcase
  • Feature bento grid with 6 tiles:
    • AI-first architecture
    • Mock mode
    • Premium design system
    • Monetization
    • Analytics & reliability
    • Optimized dev loop
  • AI tools integration section (Cursor, Claude, Copilot, etc.)
  • Fully responsive design
  • SEO optimized
When to use: Building in public, collecting beta testers, pre-launch hype

Launch Mode (Post-Launch)

Perfect for when your app is live on the App Store and Google Play. Features:
  • App Store and Google Play badge links
  • Hero section with app name and tagline
  • Feature highlights (3 key benefits)
  • Clean, minimal design focused on downloads
  • SEO optimized
When to use: App is live and you want to drive downloads

️ Quick Setup

yarn setup now also asks for the marketing page mode. It writes apps/web/.env for you, so you can skip to Step 3 if you just ran it.Important: The Resend API key is now stored securely in Supabase Edge Function secrets, not in the frontend .env file. See the “Adding a Waitlist API” section below for setup instructions.

Step 1: Copy Environment Variables (if you skipped yarn setup)

Step 2: Configure Your Settings

Edit apps/web/.env (or let yarn setup fill it):

Step 3: Switch Modes Quickly

Step 4: Run the Development Server

Visit http://localhost:5173 to see your marketing page!

Customization

Switching Between Modes

Use the helper command (it updates apps/web/.env for you):
Prefer to edit manually? Change VITE_MODE in apps/web/.env. No code changes needed - the app automatically renders the correct mode!

Customizing Waitlist Mode

Edit /apps/web/src/components/WaitlistMode.tsx: Change feature tiles (lines 92-164):
Change AI tools (lines 33-90):
Add your app screenshot:
  1. Place your screenshot in /apps/web/public/app-screenshot.png
  2. Or update VITE_APP_SCREENSHOT_URL to use a URL

Customizing Launch Mode

Edit /apps/web/src/components/LaunchMode.tsx: Change feature highlights (lines 92-108):
Customize colors and styling: The landing page uses Tailwind CSS. Edit component files to change:
  • Colors: bg-blue-600, text-gray-900, etc.
  • Spacing: p-4, m-8, gap-6, etc.
  • Layout: Grid, flex, responsive breakpoints

Adding a Waitlist API with Supabase Edge Function

The waitlist form is already configured to use a Supabase Edge Function endpoint. This keeps your Resend API key secure on the server side. Step 1: Create the Waitlist Table The waitlist table is included in the default Supabase schema. You have three options: Option A: Use Migrations (Recommended) The initial migration already includes the waitlist table:
Option B: Run the full schema If you prefer not to use migrations, run the entire supabase/schema.sql file in your Supabase SQL Editor. It includes the waitlist table along with all other default tables. Option C: Run just the waitlist table SQL If you’ve already set up your database and just need the waitlist table, run this SQL in your Supabase SQL Editor:
Step 2: Deploy the Edge Function
  1. Install Supabase CLI (if not already installed):
  1. Login to Supabase:
  1. Link your project:
  1. Initialize Supabase in your project (if not already done):
  1. Create the edge function:
This creates supabase/functions/waitlist/index.ts. Replace its contents with this code:
  1. Deploy the edge function:
  1. Set environment secrets in Supabase Dashboard:
    • Go to Project SettingsEdge FunctionsSecrets
    • Add RESEND_API_KEY (your Resend API key)
    • Add RESEND_FROM_EMAIL (optional, e.g., noreply@yourdomain.com)
    • Add RESEND_WAITLIST_SUBJECT (optional, custom subject line)
    • Add RESEND_WAITLIST_HTML (optional, custom HTML email template)
Step 3: Configure the Frontend Set the edge function endpoint in apps/web/.env:
Replace your-project-ref with your actual Supabase project reference (found in your Supabase dashboard URL). That’s it! The waitlist form will now:
  • Save emails to your Supabase database
  • Send confirmation emails via Resend (if configured)
  • Keep your Resend API key secure on the server

Deployment

  1. Push your code to GitHub
  2. Go to vercel.com
  3. Import your repository
  4. Set Root Directory to apps/web
  5. Add environment variables from your .env file
  6. Deploy!
The landing page includes a vercel.json configuration file for easy deployment.

Deploy to Netlify

  1. Go to netlify.com
  2. Import your repository
  3. Set Base directory to apps/web
  4. Set Build command to yarn build
  5. Set Publish directory to apps/web/dist
  6. Add environment variables
  7. Deploy!

Other Platforms

The marketing page is a standard Vite app, so it works with:
  • Cloudflare Pages
  • GitHub Pages
  • AWS Amplify
  • Any static host
Build command: yarn build (from apps/web/) Output directory: dist/

SEO Configuration

The landing page includes SEO components that set:
  • Meta title and description
  • Open Graph tags (for social sharing)
  • Twitter cards
  • Canonical URL
Configure these in your .env:
Pro Tip: Create an Open Graph image (1200x630px) for better social sharing. Place it in /apps/web/public/og-image.jpg.

vs. Main Landing Page Repo

You might be wondering: “What’s the difference between apps/web and the landing_page repo?” TL;DR: Use apps/web for YOUR app. Ignore landing_page (unless you’re contributing to Shipnative itself).

Tips & Best Practices

Pre-Launch Strategy

  1. Start in waitlist mode while building
  2. Share the link on Twitter, Product Hunt, Reddit
  3. Collect 100-1000+ emails before launch
  4. Send launch announcement when app goes live

Launch Day

  1. Switch to launch mode (VITE_MODE=launch)
  2. Add your App Store / Play Store URLs
  3. Redeploy
  4. Email your waitlist!

A/B Testing

Want to test different copy? Create multiple deployments:
  • waitlist-v1.yourapp.com
  • waitlist-v2.yourapp.com
Deploy the same code with different env vars and see which converts better.

Custom Domain

  1. Buy a domain (Namecheap, Google Domains, etc.)
  2. Point it to your Vercel/Netlify deployment
  3. Configure in your hosting dashboard
  4. Update VITE_APP_URL to match

Troubleshooting

  • Make sure your .env file is in apps/web/, not the monorepo root
  • Restart the dev server after changing .env
  • Vite requires VITE_ prefix for all public env vars
  • Check for typos in variable names
  • Verify the image exists in /apps/web/public/
  • Check that VITE_APP_SCREENSHOT_URL matches your filename
  • Try using an absolute URL instead of a relative path
  • Clear browser cache
  • Check browser console for errors
  • Verify VITE_WAITLIST_API_ENDPOINT is correctly set
  • Test your API endpoint with Postman/Insomnia first
  • Check CORS settings on your API
  • Run yarn install in apps/web/
  • Verify tailwind.config.cjs exists
  • Check that src/index.css is imported in src/main.tsx
  • Try yarn build to see if it’s a dev-only issue

Next Steps

Deploy Your Page

Get your landing page live on Vercel in 5 minutes

Build Your App

Start building your actual mobile app with vibecoding

Analytics Setup

Track waitlist signups and page views with PostHog

Custom Domain

Point your domain to your landing page