CheckDisposable Emailcheckdisposable.email
← All guidesNuxt 3 guide · TypeScript

Block disposable email signups in Nuxt 3

Use a server route under `server/api/`. Nuxt 3 runs on Nitro — `useRuntimeConfig` exposes server-only env vars to the handler.

The code

// server/api/signup.post.ts
export default defineEventHandler(async (event) => {
  const body = await readBody<{ email: string; password: string }>(event);
  const config = useRuntimeConfig();

  let isDisposable = false;
  try {
    const r = await $fetch<{ is_disposable: boolean }>(
      `https://api.checkdisposable.email/v1/check?email=${encodeURIComponent(body.email)}`,
      { headers: { Authorization: `Bearer ${config.cdeKey}` } }
    );
    isDisposable = r.is_disposable === true;
  } catch {
    // fail open
  }

  if (isDisposable) {
    throw createError({
      statusCode: 400,
      statusMessage: 'Please use a real email address.',
    });
  }

  // ...create user, return session
  return { ok: true };
});

// nuxt.config.ts
export default defineNuxtConfig({
  runtimeConfig: {
    cdeKey: '', // populated from NUXT_CDE_KEY
  },
});

Notes

runtimeConfig naming
Set the env var as `NUXT_CDE_KEY` and Nuxt automatically maps it to `cdeKey` in runtimeConfig. Server-only fields are only accessible in `server/` — never leaked to the client bundle.
Compatible with Sidebase Nuxt Auth
If you use @sidebase/nuxt-auth with a CredentialsProvider, drop the check into the provider's `authorize` callback. Same logic, just wrapped by the auth module.
createError style
Throwing with `createError` gives a clean JSON error response the Nuxt fetcher can surface in your <script setup> block.

Get a free API key

500 checks/month, no credit card. No credit card. 30 seconds.

Sign up free →