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 →