Claude Code Boilerplate
FeaturesPricingBlogDocs
Get started →

Product

  • Features
  • Pricing
  • Skills

Compare

  • vs ShipFast
  • vs MakerKit
  • vs supastarter

Resources

  • Docs
  • Blog
  • Discord

Legal

  • License
  • Privacy Policy
  • Terms of Service
Claude Code Boilerplate

© 2026 Claude Code Boilerplate. All rights reserved.

← All posts

How to Make Your Next.js SaaS GDPR Compliant -- Cookie Consent, Data Export, and Deletion Without a $100/mo Tool

October 11, 2026
nextjssaasauthdrizzle-ormboilerplate

The GDPR Tax Most Founders Don't Expect

You ship your SaaS, a European user signs up, and six months later you get an email: "Please delete all my data."

If you haven't built anything for this, you're about to spend an afternoon manually combing your database. Or you're about to pay $79/month for a compliance tool you don't really understand.

GDPR has four requirements that affect every SaaS selling to EU customers:

  • Get consent before storing non-essential cookies
  • Let users export their data on request
  • Delete a user's data when they ask
  • Have a privacy policy that explains what you collect and why

Most of this is simpler to implement than the compliance industry wants you to think. Here is what you actually need to build, and how the Next.js SaaS Boilerplate makes each one faster.

Cookie Consent: What "Consent" Actually Means

The GDPR rule is not "show a banner." It is "don't set non-essential cookies before consent."

Essential cookies -- session auth, CSRF tokens, the user's current language -- are fine without consent. What needs consent: analytics pixels, third-party marketing scripts, anything that tracks users across sites.

If your SaaS uses Vercel Analytics (which the boilerplate already wires up), you're in good shape -- Vercel Analytics is privacy-friendly and does not set tracking cookies. You still need a consent mechanism if you add Google Analytics, Meta Pixel, or similar scripts.

The minimum viable approach:

  • Show a banner on first visit with Accept and Reject options
  • Store the choice in a consent cookie
  • Only load tracking scripts after Accept
  • Provide a way to change the choice later (a link in the footer is enough)

You do not need a $100/month tool for this. A React component that reads a consent cookie and conditionally renders a <Script> tag is the entire implementation. The component goes in components/layout/ and gets mounted in your root layout.

Data Export: Give Users Their Data

GDPR Article 20 gives users the right to receive their personal data in a portable format -- typically a JSON or CSV download.

The practical implementation in a Next.js SaaS:

  1. Add a "Download your data" button to the user settings page
  2. Create a GET /api/users/me/export route that requires auth
  3. Query every table that holds the user's data (profile, posts, payments, etc.)
  4. Return it as a downloadable JSON file
// app/api/users/me/export/route.ts
export async function GET(req: Request) {
  const user = await getUserFromRequest(req); // throws 401 if not authenticated
  const data = await userService.exportUserData(user.id);
  return new Response(JSON.stringify(data, null, 2), {
    headers: {
      'Content-Type': 'application/json',
      'Content-Disposition': 'attachment; filename="my-data.json"',
    },
  });
}

The exportUserData service method queries all relevant tables using Drizzle ORM and assembles the result. If you followed the module architecture, each feature module owns its own table -- your export service calls each module's repo to gather the user's records.

Data Deletion: The Right to Be Forgotten

When a user requests deletion, you have 30 days to comply. What deletion means in practice:

  • Delete the user row and all directly linked records (posts, comments, uploaded files)
  • Anonymize records you need to keep for legal reasons (replace name and email with [deleted] on payment records, keep the transaction amount for tax purposes)
  • Cancel the Stripe subscription before deleting the customer record

The flow that works:

  1. User submits a deletion request from the settings page
  2. You send a confirmation email with a one-click confirm link (prevents accidents)
  3. On confirmation, your service runs the deletion inside a database transaction

With Drizzle ORM and cascading deletes configured in your schema, the database handles most cleanup automatically. Set onDelete: 'cascade' on foreign keys pointing to the users table:

// In your module schema files:
authorId: uuid('author_id')
  .notNull()
  .references(() => userTable.id, { onDelete: 'cascade' }),

The one piece you handle manually is anonymizing financial records -- swap PII fields to [deleted] in the same transaction before removing the user row.

Privacy Policy: The One You Can't Skip

You need one. It does not have to be a 10,000-word legal document.

A credible privacy policy for a small SaaS covers:

  • What personal data you collect (email, name, usage data)
  • Why you collect it (account management, billing, analytics)
  • Who you share it with (Stripe, Resend, your hosting provider)
  • How long you keep data
  • How users can request export or deletion

A lawyer-reviewed template costs $50-200 as a one-time purchase. Termly and Iubenda generate them automatically from a questionnaire. Get one before you launch -- it takes an hour.

What You Skip by Starting With the Boilerplate

The auth layer (getUserFromRequest), the user settings page scaffold, and the module architecture with Drizzle ORM are already in place when you start from the Next.js SaaS Boilerplate.

The consent banner, export endpoint, and deletion flow are the three additions you build on top. Total build time for a working GDPR setup: half a day.

Ship your GDPR checklist before your first EU customer asks for it -- it is much easier to build proactively than to scramble under a deadline.