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
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
️ 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
Editapps/web/.env (or let yarn setup fill it):
Step 3: Switch Modes Quickly
Step 4: Run the Development Server
http://localhost:5173 to see your marketing page!
Customization
Switching Between Modes
Use the helper command (it updatesapps/web/.env for you):
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):
- Place your screenshot in
/apps/web/public/app-screenshot.png - Or update
VITE_APP_SCREENSHOT_URLto use a URL
Customizing Launch Mode
Edit/apps/web/src/components/LaunchMode.tsx:
Change feature highlights (lines 92-108):
- 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: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:
- Install Supabase CLI (if not already installed):
- Login to Supabase:
- Link your project:
- Initialize Supabase in your project (if not already done):
- Create the edge function:
supabase/functions/waitlist/index.ts. Replace its contents with this code:
- Deploy the edge function:
- Set environment secrets in Supabase Dashboard:
- Go to Project Settings → Edge Functions → Secrets
- 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)
apps/web/.env:
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
Deploy to Vercel (Recommended)
- Push your code to GitHub
- Go to vercel.com
- Import your repository
- Set Root Directory to
apps/web - Add environment variables from your
.envfile - Deploy!
vercel.json configuration file for easy deployment.
Deploy to Netlify
- Go to netlify.com
- Import your repository
- Set Base directory to
apps/web - Set Build command to
yarn build - Set Publish directory to
apps/web/dist - Add environment variables
- Deploy!
Other Platforms
The marketing page is a standard Vite app, so it works with:- Cloudflare Pages
- GitHub Pages
- AWS Amplify
- Any static host
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
.env:
/apps/web/public/og-image.jpg.
vs. Main Landing Page Repo
You might be wondering: “What’s the difference betweenapps/web and the landing_page repo?”
| Feature | apps/web | landing_page |
|---|---|---|
| Purpose | Your app’s marketing page | Shipnative’s own marketing |
| Included | Yes, in the monorepo | Separate repository |
| Customization | You own it - edit freely | Don’t edit (it’s for Shipnative) |
| Use case | Pre-launch waitlist or launch page | Shipnative product marketing |
| Deploy | Your domain | shipnative.com |
apps/web for YOUR app. Ignore landing_page (unless you’re contributing to Shipnative itself).
Tips & Best Practices
Pre-Launch Strategy
- Start in waitlist mode while building
- Share the link on Twitter, Product Hunt, Reddit
- Collect 100-1000+ emails before launch
- Send launch announcement when app goes live
Launch Day
- Switch to launch mode (
VITE_MODE=launch) - Add your App Store / Play Store URLs
- Redeploy
- Email your waitlist!
A/B Testing
Want to test different copy? Create multiple deployments:waitlist-v1.yourapp.comwaitlist-v2.yourapp.com
Custom Domain
- Buy a domain (Namecheap, Google Domains, etc.)
- Point it to your Vercel/Netlify deployment
- Configure in your hosting dashboard
- Update
VITE_APP_URLto match
Troubleshooting
Environment variables not working
Environment variables not working
- Make sure your
.envfile is inapps/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
App screenshot not showing
App screenshot not showing
- Verify the image exists in
/apps/web/public/ - Check that
VITE_APP_SCREENSHOT_URLmatches your filename - Try using an absolute URL instead of a relative path
- Clear browser cache
Waitlist form not submitting
Waitlist form not submitting
- Check browser console for errors
- Verify
VITE_WAITLIST_API_ENDPOINTis correctly set - Test your API endpoint with Postman/Insomnia first
- Check CORS settings on your API
Styling looks broken
Styling looks broken
- Run
yarn installinapps/web/ - Verify
tailwind.config.cjsexists - Check that
src/index.cssis imported insrc/main.tsx - Try
yarn buildto 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

