Key Takeaways
- In Next.js App Router, email verification belongs in a Server Action or Route Handler so the API key stays server-side and never reaches the browser bundle.
- Never prefix the key with NEXT_PUBLIC_, which exposes it to client-side JavaScript. Read it from process.env inside server code only.
- Use the HTTP-based verification API, not SMTP from a serverless function, which can exceed the default timeout on cold starts.
- Validate server-side before the address is written to your database, and debounce client-side real-time checks at around 400 milliseconds.
Next.js is one of the most common stacks for modern signup flows, and the App Router has changed how server-side work is structured. As of 2026 the App Router is the stable, recommended pattern and the Pages Router is in maintenance mode. This guide builds email verification in Next.js with TypeScript the right way: a typed Server Action and Route Handler that call the v2 API server-side, keep your key secret, and gate the database write on the result. For the full reference, including other JavaScript runtimes, see the email verification integrations hub and the verify email with Node.js guide.
The most important rule comes first, because it is the one most often broken.
The v2 Endpoint and Typed Response
Confirm the endpoint with curl, then model the response as a TypeScript interface so the rest of your code is type-safe.
The status field is the primary signal: passed means the mailbox exists and accepts mail, failed means it does not, and unknown or transient covers greylisting and temporary errors. The booleans flag risk categories you may want to reject independently.
The Server-Side Verifier
Put the verification call in a server-only utility so it can be shared by both a Route Handler and a Server Action. The key is read from process.env and never leaves the server.
The server-only import is a guardrail: if anyone accidentally imports this file into a Client Component, the build fails instead of silently shipping your key to the browser. The cache: no-store option keeps Next.js from caching a verification result that should always be fresh.
The Route Handler
The App Router uses named HTTP method exports in app/api/.../route.ts. This handler validates the address and returns a clean verdict the client can act on, without ever exposing the key.
The Server Action for Signup
For a form submission, a Server Action gates the database write directly, with no separate API route needed. The 'use server' directive marks the function as server-only.
On the client, call the Route Handler on a 400 millisecond debounce as the user types so you show an inline checkmark or typo warning without a request on every keystroke. Sub-second verification means this adds no perceptible delay. Keep the final, authoritative check in the Server Action so the database write is always gated server-side, even if a bot bypasses the client.
New developers can grab 100 free email verification credits to test the flow, and the email verification API documentation covers the full response schema and rate limits.
Frequently Asked Questions
Should I use a Server Action or a Route Handler for email verification?
Use a Server Action for form submissions that write to your database, since it gates the write directly with no separate endpoint. Use a Route Handler when you need an HTTP endpoint for client-side real-time checks as the user types. Many apps use both: a debounced Route Handler call for UX and a Server Action for the authoritative final check.
Why should the API key never use the NEXT_PUBLIC_ prefix?
Any environment variable prefixed with NEXT_PUBLIC_ is inlined into the client-side JavaScript bundle, so the key becomes visible to anyone who inspects the page. Read the key from process.env inside server code only, and add a server-only import to your verifier module so an accidental client import fails the build.
Can I verify emails with SMTP from a Next.js serverless function?
It is not recommended. Raw SMTP connections can exceed the default serverless function timeout, especially on cold starts when the TCP connection is established from scratch. The HTTP-based verification API completes in a single HTTPS request, well within any serverless timeout, which makes it the reliable choice on platforms like Vercel.
How do I add real-time validation without hurting UX?
Debounce the client-side call to your Route Handler at about 400 milliseconds so it fires on a typing pause rather than every keystroke. With sub-second verification, the result returns before the user finishes, letting you show a green check or a typo suggestion inline with no perceptible delay.