Next.js Supabase V3 (#463)

Version 3 of the kit:
- Radix UI replaced with Base UI (using the Shadcn UI patterns)
- next-intl replaces react-i18next
- enhanceAction deprecated; usage moved to next-safe-action
- main layout now wrapped with [locale] path segment
- Teams only mode
- Layout updates
- Zod v4
- Next.js 16.2
- Typescript 6
- All other dependencies updated
- Removed deprecated Edge CSRF
- Dynamic Github Action runner
This commit is contained in:
Giancarlo Buomprisco
2026-03-24 13:40:38 +08:00
committed by GitHub
parent 4912e402a3
commit 7ebff31475
840 changed files with 71395 additions and 20095 deletions

View File

@@ -0,0 +1,185 @@
---
status: "published"
title: 'Add a Waitlist to the Next.js Supabase SaaS Starter kit'
label: 'Waitlist'
order: 1
description: 'Add a waitlist to your Next.js Supabase SaaS Starter kit to collect emails from interested users.'
---
In this guide, you will learn how to add a waitlist to your Next.js Supabase SaaS Starter kit to collect emails from interested users. This feature is useful for building an audience before launching your product.
This plugin allows you to create a waitlist for your app. Users can sign up for the waitlist and receive an email when the app is ready.
### How it works
1. You disable sign up in your app from Supabase. This prevents any user from using the public API to sign up.
2. We create a new table in Supabase called `waitlist`. Users will sign up for the waitlist and their email will be stored in this table.
3. When you want to enable a sign up for a user, mark users as `approved` in the `waitlist` table.
4. The database trigger will create a new user in the `auth.users` table and send an email to the user with a link to set their password.
5. The user can now sign in to the app and update their password.
6. User gets removed from the waitlist as soon as the email is sent.
### Installation
#### Get the plugin using the CLI
Please run the following command in your terminal:
```bash
npx @makerkit/cli@latest plugins add waitlist
```
After completed, the CLI will install the plugin at `packages/plugins/waitlist`.
The codemod will automatically:
- Add the `@kit/waitlist` dependency and install packages
- Replace the sign-up form with the waitlist form
- Add the waitlist translations to your `auth.json` locale file
- Create the Supabase migration file for the waitlist table
#### Run the migrations
After installation, run the migration and regenerate types:
```bash
pnpm run supabase:web:reset
pnpm run supabase:web:typegen
```
#### Adding the Database Webhook to listen for new signups
Let's extend the DB handler at `apps/web/app/api/db/webhook/route.ts`. This handler will listen for new signups and send an email to the user:
```tsx
import { getDatabaseWebhookHandlerService } from '@kit/database-webhooks';
import { getServerMonitoringService } from '@kit/monitoring/server';
import { enhanceRouteHandler } from '@kit/next/routes';
import appConfig from '~/config/app.config';
import pathsConfig from '~/config/paths.config';
/**
* @name POST
* @description POST handler for the webhook route that handles the webhook event
*/
export const POST = enhanceRouteHandler(
async ({ request }) => {
const service = getDatabaseWebhookHandlerService();
try {
const signature = request.headers.get('X-Supabase-Event-Signature');
if (!signature) {
return new Response('Missing signature', { status: 400 });
}
const body = await request.clone().json();
// handle the webhook event
await service.handleWebhook({
body,
signature,
async handleEvent(payload) {
if (payload.table === 'waitlist' && payload.record.approved) {
const { handleApprovedUserChange } = await import(
'@kit/waitlist/server'
);
const inviteToken = payload.record.invite_token;
const redirectToUrl = new URL(
pathsConfig.auth.passwordUpdate,
appConfig.url,
);
if (inviteToken) {
const next = encodeURI(
pathsConfig.app.joinTeam + '?invite_token=' + inviteToken,
);
redirectToUrl.searchParams.append('callback', next);
}
const redirectTo = redirectToUrl.toString();
await handleApprovedUserChange({
email: payload.record.email,
redirectTo,
});
}
},
});
// return a successful response
return new Response(null, { status: 200 });
} catch (error) {
const service = await getServerMonitoringService();
await service.ready();
await service.captureException(error as Error);
// return an error response
return new Response(null, { status: 500 });
}
},
{
auth: false,
},
);
```
#### Adding the Trigger to the Database
We need to add a trigger to the `waitlist` table to listen for updates and send a webhook to the app when a user is approved.
During development, you can simply add the webhook to your seed file `apps/web/supabase/seed.sql`:
```sql
create trigger "waitlist_approved_update" after update
on "public"."waitlist"
for each row
when (new.approved = true)
execute function "supabase_functions"."http_request"(
'http://host.docker.internal:3000/api/db/webhook',
'POST',
'{"Content-Type":"application/json", "X-Supabase-Event-Signature":"WEBHOOKSECRET"}',
'{}',
'5000'
);
```
The above creates a trigger that listens for updates to the `waitlist` table and sends a POST request to the webhook route.
**Note**: You need to add this trigger to your production database as well. You will replace your `WEBHOOKSECRET` with the secret you set in your `.env` file and the `host.docker.internal:3000` with your production URL.
Just like you did for the other existing triggers.
#### Approving users
Simply update the `approved` column in the `waitlist` table to `true` to approve a user. You can do so from the Supabase dashboard or by running a query.
Alternatively, run an update based on the created_at timestamp:
```sql
update public.waitlist
set approved = true
where created_at < '2024-07-01';
```
#### Email Templates and URL Configuration
Please make sure to [edit the email template](https://makerkit.dev/docs/next-supabase-turbo/authentication-emails) in your Supabase account.
The default email in Supabase does not support PKCE and therefore does not work. By updating it - we replace the existing strategy with the token-based strategy - which the `confirm` route in Makerkit can support.
Additionally, [please add the following URL to your Supabase Redirect URLS allow list](https://supabase.com/docs/guides/auth/redirect-urls):
```
<your-url>/password-reset
```
This will allow Supabase to redirect users to your app to set their password after they click the email link.
If you don't do this - the email links will not work.
#### Disable oAuth
If you are using any oAuth providers, please disable them in the [Makerkit Auth configuration](../configuration/authentication-configuration#third-party-providers). Since sign-ups are disabled, users will hit errors.