• Blog
  • Documentation
  • Courses
  • Changelog
  • AI Starters
  • UI Kit
  • FAQ
  • Supamode
    New
  • Pricing

Launch your next SaaS in record time with Makerkit, a React SaaS Boilerplate for Next.js and Supabase.

Makerkit is a product of Makerkit Pte Ltd (registered in the Republic of Singapore)Company Registration No: 202407149CFor support or inquiries, please contact us

About
  • FAQ
  • Contact
  • Verify your Discord
  • Consultation
  • Open Source
  • Become an Affiliate
Product
  • Documentation
  • Blog
  • Changelog
  • UI Blocks
  • Figma UI Kit
  • AI SaaS Starters
License
  • Activate License
  • Upgrade License
  • Invite Member
Legal
  • Terms of License

Using OTP Verification in Makerkit

Mar 1, 2025

Learn how to implement OTP verification in Makerkit to add extra security to your application.

changelog

In version 2.4.0, we've added support for OTP verification in Makerkit. This feature allows you to easily add two-factor authentication (2FA) to your application, providing an extra layer of security for sensitive operations.

While MFA was always possible to do thanks to Supabase Auth - we refer to OTP verification for different types of operations, such as:

  • deleting a user's account, a team, or transferring ownership of a team
  • super admin operations
  • any other operation that requires extra security

OTP Verification in Makerkit

The package @kit/otp provides a simple interface for managing OTP verification in your application.

We export three main parts from the package:

  1. <VerifyOtpForm />: A reusable form component for dispatching and verifying OTP codes
  2. createOtpApi(client): An API for verifying OTP codes

The VerifyOtpForm Component

The <VerifyOtpForm /> component is a reusable form component that handles the OTP verification process. It's designed to be used in conjunction with the createOtpApi function, which we'll cover next.

Here's an example of how to use the component:

tsx
import { VerifyOtpForm } from '@kit/otp';
import { useState } from 'react';
const MyForm = () => {
const [otp, setOtp] = useState('');
if (otp) {
// render an action button that dispatches the OTP code
return <FormActionConfirmation otp={otp} />;
}
return (
<VerifyOtpForm
purpose="delete-account"
onSubmit={setOtp}
email="user@example.com"
/>
);
};
function FormActionConfirmation({ otp }) {
return (
<button onClick={() => dispatchOtpAction(otp)}>
Confirm Action
</button>
);
}

The FormActionConfirmation component is an example of how you might use the OTP code to dispatch an action. In this case, we're confirming the deletion of a user's account:

Now, let's call the createOtpApi function to create an API for dispatching and verifying OTP codes:

tsx
'use server';
import { createOtpApi } from '@kit/otp';
import { getServerSupabaseClient } from '@kit/supabase/server-client';
import { enhanceAction } from '@kit/next/actions';
import { z } from 'zod';
export const dispatchOtpAction = enhanceAction(async ({ user, data }) => {
const supabase = getServerSupabaseClient();
const otpApi = createOtpApi(supabase);
// retrieve the OTP code from the request
const otpResult = await otpApi.verifyToken({
token: data.otp,
userId: user.id,
purpose: 'delete-personal-account',
});
// token, userID and purpose must match
// otherwise, the OTP code is invalid
if (!otpResult.valid) {
throw new Error('Invalid OTP');
}
// OTP is valid, proceed with the operation
}, {
auth: true,
schema: z.object({
otp: z.string().min(1),
}),
});

The above is a fairly simple example, but it demonstrates the basic idea.

  1. Dispatching an OTP code: The VerifyOtpForm component is used to render the OTP form, and will automatically handle sending an OTP code to the user's email address.
  2. Verifying an OTP Code: The createOtpApi function takes a Supabase client instance. We then call the verifyToken method on the API, passing in the OTP code and the user ID. The method returns a result object that indicates whether the OTP code is valid or not.

A few things to note:

  1. The purpose parameter is used to identify the type of operation being performed. This ensures that the OTP code is only valid for the intended purpose.
  2. The userId parameter is used to associate the OTP code with a specific user. This ensures that the OTP code is only valid for the user who requested it.

If these parameters don't match, the OTP code is considered invalid, so it's important to ensure that they are correctly set.

Examples of OTP Verification: deleting a user's account

Deleting a user's account is a sensitive operation that requires extra security - therefore we made the decision to implement OTP verification for it.

The below video demonstrates how to delete a user's account using OTP verification:

Loading video...

Conclusion

OTP verification is a simple yet effective way to add extra security to your application. By implementing OTP verification for sensitive operations, you can ensure that your users' data is protected and their accounts are secure.

For more information about the OTP API, please refer to the OTP API documentation.

Some other posts you might like...
Aug 29, 2025Introducing Custom Dashboards in Supamode: Build Dynamic Analytics InterfacesCreate powerful Supabase dashboard interfaces with Supamode's custom analytics platform. Build personalized Supabase analytics views with drag-and-drop widgets and real-time data visualization.
Aug 21, 2025Makerkit 2.13.0: Components Showcase, Next.js 15.5 & Advanced Data TablesNext.js 15.5 upgrade, Component Showcase, enhanced Table component directly from Supamode to the SaaS Kit
Jul 10, 2025Introducing Supamode, the enterprise-grade Super Admin for SupabaseIntroducing Supamode, a self-hosted enterprise-grade Super Admin for Supabase, turning your database into a powerful, flexible, and secure CMS.
Jun 13, 2025Makerkit 2.11.0: Building Better Authentication ExperiencesDeep dive into the new authentication features: Identity Linking, OTP Sign-In, Smart User Hints, and Legacy Plans support. Learn how these features solve real user problems and reduce support overhead.
Apr 29, 2025Multi-Platform Deployment: Docker, Cloudflare & Self-Hosting Now Available in MakerkitDeploy your Makerkit SaaS projects anywhere with our new first-class support for Docker, Cloudflare, and self-hosting on VPS. Generate configuration files with a single command and follow our comprehensive guides to get up and running quickly.
Mar 10, 2025Introducing the React Router 7 SaaS Starter KitAnnouncing the release of our React Router 7 + Supabase SaaS Boilerplate! The SaaS template for shipping your SaaS with React Router 7.