How I Stopped Rewriting Next.js and Stripe for Every SaaS

2026-11-05来源 dev.to WebDevEnglish

I used to fall into the same trap every time I got a new SaaS idea. I’d call it the "weekend project," but it never stayed a weekend project. I’d spend Friday night setting up the Next.js App Router. Saturday was dedicated to wrestling with NextAuth.js configurations and trying to get OAuth providers to play nicely. Sunday? That was all Stripe. Setting up the checkout sessions, configuring the webhooks, and testing the edge cases.

By the time I actually started writing the core business logic for my app, I was already burnt out. I was spending 80% of my time building the same boilerplate over and over again.

So I decided to build something.

The Hidden Tax of SaaS Boilerplate

The hidden tax of SaaS development isn't just the time it takes to write the boilerplate; it's the mental load of maintaining it. When you copy-paste authentication and billing logic from an old project, you inherit all its old bugs.

Stripe webhooks are notoriously tricky. If you don't handle idempotency correctly, or if you miss a specific event signature, you can end up double-provisioning subscriptions or failing to upgrade users. Similarly, messing up session handling in NextAuth can lead to security vulnerabilities.

Ignoring these details means building on a fragile foundation. When you finally get traction and real users hit your app, that's exactly when your hacked-together webhook handler is going to fail. You end up spending your weekends fixing billing bugs instead of shipping features.

Architecting a Reliable Stack

I wanted to create a production-ready SaaS boilerplate that I could actually rely on. I made a few strict architectural decisions: it had to be TypeScript-first for full type safety, use the Next.js 14+ App Router, and handle Stripe billing reliably out of the box.

But I also wanted to solve a specific performance issue I kept running into: edge-side processing. I often needed to fetch external data, like analyzing a webpage for SEO, and doing this from a standard serverless function was too slow and expensive for global users.

This is where Cloudflare Workers came in. I integrated them into the stack to handle edge-side API routes. Here is an example of how the edge SEO analysis works in the boilerplate:

// Cloudflare Worker for edge SEO analysis export default { async fetch(request, env) { const url = new URL(request.url); if (url.pathname !== '/api/analyze') { return new Response('Not found', { status: 404 }); } const targetUrl = url.searchParams.get('url'); if (!targetUrl) { return new Response(JSON.stringify({ error: 'Missing url' }), { status: 400, headers: { 'Content-Type': 'application/json' }, }); } // Fetch target page at the edge (low latency worldwide) const response = await fetch(targetUrl, { cf: { cacheTtl: 300, cacheEverything: true }, }); const html = await response.text(); // Run SEO checks (regex-based, no DOM needed) const title = html.match(/<title[^>]*>([^<]*)<\/title>/i)?.[1] || ''; const desc = html.match(/<meta[^>]*name=["']description["'][^>]*content=["']([^"']*)["']/i)?.[1] || ''; const h1Count = (html.match(/<h1[ >]/gi) || []).length; return new Response(JSON.stringify({ title, desc, h1Count }), { headers: { 'Content-Type': 'application/json' }, }); }, }; 

By running this on Cloudflare Workers, the fetch happens at the edge, significantly reducing latency. Notice that I'm using regex to parse the HTML instead of a heavy DOM parser like jsdom. This keeps the Worker execution time and memory footprint incredibly low, which is crucial when you're dealing with edge compute limits.

On the backend, the Stripe integration uses the App Router to handle checkout sessions securely. It passes the client_reference_id to map the Stripe customer back to the internal database user once the webhook fires, ensuring that user provisioning happens smoothly without manual intervention.

Practical Results and Lessons Learned

Building this boilerplate significantly changed how I approach new projects. The one-click deployment to Vercel for the frontend and Cloudflare Pages for the edge functions means I can go from git clone to a live, authenticated, billable SaaS in about ten minutes.

What worked really well was the type safety across the entire stack. Because it's TypeScript-first, refactoring the database schema or updating a Stripe price ID immediately flags any broken references in the UI components.

What surprised me the most was how much I ended up using the built-in SEO tools myself. I originally built the edge analyzer just as a proof of concept for the Workers integration, but it became a genuinely useful utility for checking my own landing pages before I even launched them.

If I were to do it again, I would probably spend less time initially trying to support every single OAuth provider under the sun. I started with five, but realistically, most projects only need Google and GitHub. Simplifying the initial auth scope would have saved me a few days of edge-case testing.

Try the Edge SEO Tool

If you're curious about how the edge SEO analysis performs, or if you just need a quick way to check a landing page's basic SEO metrics without spinning up a whole project, I extracted that specific Worker into a free tool.

You can try the free SEO Checker at https://saaslaunch.dev/free-tools/seo-checker. It runs entirely on the edge and gives you instant feedback on your title, description, and heading structure.

Full disclosure: I'm the developer of SaaSLaunch. I built this because I needed it myself.

原文:https://www.a8q9.cn/en/article/how-i-stopped-rewriting-next-js-and-stripe-for-every-saas-e3a0b3.html

相关文章