The SaaS launch checklist: everything to do before you go live
Auth flows, live-mode payments, transactional email, error tracking, analytics, SEO, legal pages, and performance — the complete checklist to work through the day before you ship your SaaS.
Shipping your SaaS is exciting — but the gap between “it works on my machine” and “it works for real users paying real money” is full of landmines. This checklist covers every category you need to verify before you flip the switch. Work through it top to bottom the day before you launch.
Auth
Broken authentication is the fastest way to lose a new user forever. Test every flow manually in a fresh incognito window:
Sign up — create a new account with a real email address you control. Confirm the welcome email arrives and the account is created in your database.
Sign in — log out and log back in. Confirm you land on the correct post-login page.
Sign out — click sign out and confirm the session is fully destroyed. Navigating back to a protected route should redirect to sign-in, not show stale data.
Password reset — request a reset link, receive it, and complete the flow. Confirm the new password works.
Protected routes — paste a dashboard URL into an incognito window with no session. You should be redirected to sign-in, not shown a blank page or a 500 error.
Payments
Your payment flow is what turns users into revenue. Test it in live mode with a real card before launch — Stripe's test mode has subtle differences that can mask issues.
Checkout in live mode — use a real card (you can refund it immediately after). Confirm the Stripe Checkout page loads, the card is charged, and you are redirected to the correct success page.
Webhook fires — after the real checkout, check your server logs or Stripe dashboard to confirm checkout.session.completed was received and processed. Check that the subscription row in your database was updated correctly.
Customer portal — confirm the billing portal link works and shows the correct plan and card details.
Cancellation — cancel the subscription through the portal. Confirm your app receives the customer.subscription.deleted event and updates the subscription status in your database.
Refund yourself — go to the Stripe dashboard and refund the test charge. No need to leave a real charge open.
Email
Transactional email is often the first direct communication a user has with your brand after signing up. A missed or spam-filtered welcome email is a terrible first impression.
Welcome email — trigger a welcome email (either by signing up or via a test API call) and check that it arrives in your inbox within 30 seconds.
Spam score — forward the email to mail-tester.com or run it through MXToolbox. Confirm your domain has SPF, DKIM, and DMARC records configured. Resend adds these automatically when you verify your domain, but verify they're there.
Receipt email— complete a checkout and confirm the payment receipt email fires from your webhook handler, not just from Stripe's default receipts.
Unsubscribe link — all marketing emails (not transactional) must have an unsubscribe link to comply with CAN-SPAM and GDPR.
Error tracking
You will not be watching your server logs in real time on launch day. Error tracking is how you find out when things break.
Sentry is connected — confirm your SENTRY_DSN is set in production environment variables, not just locally.
Trigger a test error — add a temporary route or button that throws a deliberate error, deploy it, hit it, and confirm the error appears in your Sentry dashboard within a minute. Remove the test code before launch.
Source maps — confirm Sentry shows readable stack traces, not minified variable names. If you see e.t is not a function instead of a real function name, source map upload is not configured.
Alert rules — set up a Sentry alert to email or Slack you when a new error occurs. The default is no alerts.
Analytics
Without analytics, you're flying blind. Verify your events are flowing before launch so you have a baseline from day one.
PostHog is receiving pageviews — visit your production site and check the PostHog Live Events panel. You should see pageview events appear within seconds.
Key events fire — complete a signup and a checkout in production (or staging). Confirm sign_up, checkout_started, and subscription_activated events appear in PostHog with the correct properties.
Identify is called— after sign-in, confirm PostHog associates the session with the user's ID, not an anonymous ID. This makes funnel analysis useful.
SEO
SEO issues are easy to introduce and annoying to debug after the fact. Check these before Google indexes your site.
Sitemap — visit /sitemap.xml and confirm it lists your key pages. If it returns a 404, add a app/sitemap.ts file that generates it.
robots.txt — visit /robots.txt. It should allow crawling of your public pages and disallow /dashboard and any private routes.
OG image — paste your URL into opengraph.xyz and confirm the preview image renders correctly. A missing or broken OG image kills click rates from social shares.
Canonical URLs — confirm your <link rel="canonical"> tags point to the correct production domain, not localhost or a staging URL.
Title and meta description — check your homepage and key pages in the browser tab and in a Google preview tool. Each page should have a unique, descriptive title under 60 characters.
Legal
Collecting money or personal data without a privacy policy is a legal liability. These pages must be live on launch day.
Privacy policy — published at /privacy or similar, linked from your footer and your sign-up page. It must describe what data you collect, how you use it, and how users can request deletion.
Terms of service — published and linked from the footer and checkout flow. Defines acceptable use and limits your liability.
Cookie consent— if you're tracking EU users with PostHog or any other analytics tool, you need a cookie consent banner that blocks tracking until consent is given.
Refund policy— even a simple “no refunds” policy prevents chargebacks and confusion. Stripe's terms require you to have one.
Performance
A slow site loses users before they ever reach your checkout. Run these checks in production, not locally — Next.js dev mode is not representative of real performance.
Lighthouse — open Chrome DevTools, go to the Lighthouse tab, and run an audit on your homepage. Aim for a Performance score above 85 and fix any obvious issues (render-blocking resources, unoptimized images, missing font-display).
Core Web Vitals — the three metrics Google uses for ranking: LCP (Largest Contentful Paint) under 2.5s, INP (Interaction to Next Paint) under 200ms, and CLS (Cumulative Layout Shift) under 0.1. Lighthouse reports all three.
Images — confirm all images use Next.js's <Image> component, which automatically serves WebP and adds lazy loading. Raw <img> tags skip all of that.
Font loading — if you use Google Fonts or a custom font, use next/font to load it. It eliminates layout shift and avoids a third-party network request.
Final pre-launch checks
All environment variables are set in Vercel (or your host) — not just locally.
No console.log statements left in production code that leak sensitive data.
HTTPS is enforced on your custom domain.
Your domain's MX records are correct if you're receiving email on it.
Your Stripe account is fully activated (not just in test mode).
Everything on this checklist — Clerk auth, Stripe webhooks, Resend emails, PostHog analytics, Sentry error tracking, Upstash rate limiting, and production-ready Next.js config — is pre-wired in GetLaunchpad, a Next.js 16 SaaS boilerplate. Skip the setup and ship your product instead.
Most Next.js API routes ship without authentication checks, input validation, or rate limiting. Here's how to add Clerk auth, Zod validation, Upstash rate limiting, consistent error shapes, and proper HTTP status codes to every route handler.
The complete guide to Stripe subscriptions in Next.js: creating products and prices, embedded vs redirect checkout, the checkout session → webhook → database flow, customer portal, and testing with the Stripe CLI.