Widget AT Valid โ€” Demo e integrazioni

Validazione email in tempo reale per qualsiasi form. Provalo qui sotto, poi copia lo snippet per la tua piattaforma.

โ†“ Vai agli esempi di integrazione

รˆ richiesta una verifica di sicurezza prima di usare la demo

Validazione dettagliata

Risultato completo con punteggio, voto e indicatori

Email
Punteggio
Voto
Usa e getta
Provider gratuito

Validazione automatica (modalitร  widget)

widget.js con regole di ammissione, validazione HTML5, preventSubmit

// Widget events will appear here...

API programmatica

ATValid.validate(email, callback) โ€” valida senza collegamento al DOM

// Programmatic result will appear here...

Esempi di integrazione

Un tag script, un ATValid.init(). Sostituisci pk_live_โ€ฆ con la chiave pubblica disponibile su app.atvalid.com/apis (limitala ai tuoi domini).

HTML semplice โ€” avvio rapido

Qualsiasi sito: incolla prima di </body>. Ogni input[type="email"] viene validato all'uscita dal campo.

<!-- Add before </body> -->
<script src="https://www.atvalid.com/widget/v2/widget.js"></script>
<script>
  ATValid.init({
    publicKey: 'pk_live_your_public_key_here',
    preventSubmit: true            // block the submit while the email is invalid
  });
</script>
Il widget usa un MutationObserver, quindi i form inseriti in seguito (AJAX, SPA, page builder) vengono rilevati automaticamente. All'indirizzo non viene inviato nulla: la verifica avviene lato server.

Tutte le opzioni, le regole di ammissione e i messaggi

Sono mostrati i valori predefiniti. messages.sub (v2.1) fornisce un motivo specifico invece di un generico "non valido".

ATValid.init({
  publicKey: 'pk_live_your_public_key_here',
  selector: 'input[type="email"]',   // which inputs to bind
  validateOn: 'blur',                // 'blur' | 'input'
  verifyAfterDelay: 1000,            // ms after typing stops (validateOn: 'input')
  timeout: 10,                       // seconds
  showFeedback: true,                // message under the input
  preventSubmit: false,              // block submit when blocked/invalid
  formValidation: false,             // HTML5 setCustomValidity()
  blockOnRateLimit: false,
  statusAppendTo: null,              // CSS selector or element for the feedback
  ignoredForms: [],                  // form names/ids to skip
  ignoredInputs: [],                 // input names/ids to skip

  allow: {
    states: ['deliverable', 'risky', 'unknown'],  // 'undeliverable' is never accepted by default
    free: true,                      // Gmail, Outlook, Yahooโ€ฆ
    role: true,                      // info@, sales@, admin@โ€ฆ
    disposable: false                // temp-mail domains
  },

  messages: {
    checking: 'Verifying email...',
    valid: 'Valid email address',
    invalid: 'This email appears to be invalid',
    disposable: 'Disposable email addresses are not allowed',
    role: 'Role-based email addresses are not allowed',
    free: 'Free email addresses are not allowed',
    suggestion: 'Did you mean {suggestion}?',
    networkError: 'Could not verify email. Please check your connection.',
    rateLimited: 'Too many requests. Please wait a moment.',
    noCredits: 'Validation service temporarily unavailable',
    error: 'Could not verify email at this time',
    // v2.1 โ€” specific reasons (partial overrides are fine)
    sub: {
      not_found: 'This mailbox does not exist',
      mailbox_full: 'This mailbox is full and cannot receive email',
      null_mx: 'This domain does not accept email',
      no_mx: 'This domain has no mail server',
      blacklist: 'This email domain is blacklisted',
      parked: 'This domain is parked and does not receive email',
      no_reply: 'No-reply addresses cannot be used',
      greylist: 'The mail server asked us to try again later',
      toxic: 'This email address cannot be accepted',
      catch_all: 'We could not confirm this mailbox exists',
      smtp_unknown: 'The mail server did not respond',
      suspicious: 'This email address looks suspicious'
    }
  },

  onValidate: function (email, result) { console.log(email, result); },
  onError: function (email, error) { console.error(email, error.code, error.message); }
});

WordPress โ€” Contact Form 7, WPForms, Gravity Forms, Elementor, Formidable, Ninja Forms

Aggiungi a footer.php prima di </body>, oppure con il plugin "Insert Headers and Footers" / "WPCode" (footer di tutto il sito).

<script src="https://www.atvalid.com/widget/v2/widget.js"></script>
<script>
  ATValid.init({
    publicKey: 'pk_live_your_public_key_here',
    selector: [
      '.wpcf7-email',                          // Contact Form 7
      '.wpforms-field-email input',            // WPForms
      '.gfield input[type="email"]',           // Gravity Forms
      '.elementor-field-type-email input',     // Elementor Forms
      '.frm_form_field input[type="email"]',   // Formidable
      '.nf-form-cont input[type="email"]',     // Ninja Forms
      'input[type="email"]'                    // anything else
    ].join(', '),
    validateOn: 'blur',
    preventSubmit: true,
    allow: { disposable: false, role: false }
  });
</script>
Contact Form 7 ridisegna il form dopo un invio AJAX: il widget si ricollega automaticamente. Se un plugin mette in cache/minifica il JS, escludi widget.js dall'unione dei file.

RD Station โ€” landing page e pop-up

Landing page โ†’ Impostazioni โ†’ "Codice personalizzato (HTML/JS)" โ†’ prima di </body>. I form di RD si caricano dinamicamente; il widget li attende.

<script src="https://www.atvalid.com/widget/v2/widget.js"></script>
<script>
  ATValid.init({
    publicKey: 'pk_live_your_public_key_here',
    selector: 'input[type="email"], input[name="email"]',
    preventSubmit: true,
    formValidation: true,     // RD's own validation shows our message
    allow: { disposable: false }
  });
</script>
Per i form di RD Station incorporati nel tuo sito (embed via script), aggiungi lo stesso snippet alla pagina che ospita l'embed.

HubSpot โ€” form, landing page, pop-up

Impostazioni โ†’ Sito web โ†’ Pagine โ†’ Avanzate โ†’ "HTML del footer del sito" (o per singola pagina). I form di HubSpot vengono renderizzati dinamicamente e rilevati automaticamente.

<script src="https://www.atvalid.com/widget/v2/widget.js"></script>
<script>
  ATValid.init({
    publicKey: 'pk_live_your_public_key_here',
    selector: 'input[type="email"], .hs-input[name="email"]',
    preventSubmit: true,
    allow: { disposable: false }
  });

  // Optional: re-scan when HubSpot signals a form is ready
  window.addEventListener('message', function (e) {
    if (e.data && e.data.type === 'hsFormCallback' && e.data.eventName === 'onFormReady') {
      ATValid.refresh();
    }
  });
</script>

Mailchimp โ€” form di iscrizione incorporato

Incolla dopo il codice di embed di Mailchimp sul tuo sito (le landing page ospitate da Mailchimp non accettano JS personalizzato).

<!-- your Mailchimp embed form is above -->
<script src="https://www.atvalid.com/widget/v2/widget.js"></script>
<script>
  ATValid.init({
    publicKey: 'pk_live_your_public_key_here',
    selector: '#mc-embedded-subscribe-form input[type="email"], #mce-EMAIL',
    validateOn: 'input',        // validate while typing (debounced 1s)
    verifyAfterDelay: 1000,
    preventSubmit: true,
    allow: { disposable: false, role: false }
  });
</script>

Google Tag Manager โ€” tag HTML personalizzato

Tipo di tag "HTML personalizzato", attivatore "Tutte le pagine" (o solo le pagine con form). Funziona con qualsiasi CMS senza toccare il tema.

<script>
  (function () {
    var s = document.createElement('script');
    s.src = 'https://www.atvalid.com/widget/v2/widget.js';
    s.async = true;
    s.onload = function () {
      ATValid.init({
        publicKey: 'pk_live_your_public_key_here',
        preventSubmit: true,
        allow: { disposable: false },
        onValidate: function (email, result) {
          // push to the dataLayer for GA4 / conversion rules
          window.dataLayer = window.dataLayer || [];
          window.dataLayer.push({
            event: 'atvalid_email_verified',
            atv_accepted: result.accepted,
            atv_state: result.state,
            atv_sub_status: result.subStatus,
            atv_score: result.score
          });
        }
      });
    };
    document.head.appendChild(s);
  })();
</script>
Lo snippet non richiede "Supporta document.write". Il callback onValidate invia un evento al dataLayer per GA4 / regole di conversione.

Webflow, Wix, Shopify, Squarespace โ€” codice personalizzato per tutto il sito

Webflow: Project settings โ†’ Custom code โ†’ Footer. Wix: Impostazioni โ†’ Codice personalizzato โ†’ Fine del body. Shopify: theme.liquid prima di </body>. Squarespace: Impostazioni โ†’ Avanzate โ†’ Code injection โ†’ Footer.

<script src="https://www.atvalid.com/widget/v2/widget.js"></script>
<script>
  ATValid.init({
    publicKey: 'pk_live_your_public_key_here',
    // covers Webflow (.w-input), Wix, Shopify (customer/contact forms) and Squarespace
    selector: 'input[type="email"], input.w-input[type="email"], input[name="customer[email]"], input[name="contact[email]"]',
    preventSubmit: true,
    allow: { disposable: false }
  });
</script>
Il checkout di Shopify non consente JS personalizzato: usa il widget nei form del negozio (newsletter, contatti, account) e l'API REST lato server per il checkout.

React / Next.js

Carica una sola volta, collega al tuo input, distruggi allo smontaggio. In Next.js marca il componente con 'use client'.

import { useEffect } from 'react';

export function ContactForm() {
  useEffect(() => {
    const script = document.createElement('script');
    script.src = 'https://www.atvalid.com/widget/v2/widget.js';
    script.async = true;
    script.onload = () => {
      window.ATValid.init({
        publicKey: 'pk_live_your_public_key_here',
        selector: '#email-input',
        preventSubmit: true,
        formValidation: true,
        allow: { disposable: false },
        onValidate: (email, result) => console.log(email, result.accepted, result.subStatus)
      });
    };
    document.body.appendChild(script);
    return () => {
      window.ATValid && window.ATValid.destroy();
      document.body.removeChild(script);
    };
  }, []);

  return (
    <form>
      <input id="email-input" type="email" placeholder="Email" />
      <button type="submit">Submit</button>
    </form>
  );
}
Dopo una navigazione lato client che renderizza nuovi form, chiama ATValid.refresh() (oppure affidati al MutationObserver, attivo per impostazione predefinita).

Vue 3 / Nuxt

Stessa idea con onMounted / onBeforeUnmount. In Nuxt mantienilo dentro <ClientOnly> o in un componente client.

<script setup>
import { onMounted, onBeforeUnmount } from 'vue';

let script;
onMounted(() => {
  script = document.createElement('script');
  script.src = 'https://www.atvalid.com/widget/v2/widget.js';
  script.async = true;
  script.onload = () => window.ATValid.init({
    publicKey: 'pk_live_your_public_key_here',
    selector: '#email',
    preventSubmit: true,
    allow: { disposable: false }
  });
  document.body.appendChild(script);
});
onBeforeUnmount(() => {
  window.ATValid && window.ATValid.destroy();
  script && script.remove();
});
</script>

<template>
  <form><input id="email" type="email" /><button>Submit</button></form>
</template>

Callback, eventi DOM e oggetto risultato (v2.1)

Usa onValidate oppure ascolta atv:verified / atv:error su document.

document.addEventListener('atv:verified', function (e) {
  var r = e.detail.result;
  // r = {
  //   valid: true|false,            // API-level verdict
  //   accepted: true|false,         // passed your allow rules โ†’ decides the submit
  //   state: 'deliverable'|'risky'|'unknown'|'undeliverable',
  //   subStatus: 'ok'|'not_found'|'mailbox_full'|'disposable'|'null_mx'|'no_mx'|'typo'|
  //              'blacklist'|'parked'|'no_reply'|'greylist'|'catch_all'|'suspicious'|
  //              'role_based'|'toxic'|'smtp_unknown'|'risky'|'invalid',   (v2.1)
  //   toxicity: 0..5,               // reputation risk (โ‰ฅ3 is never accepted)  (v2.1)
  //   catchAllConfidence: 0..10|null, // evidence the mailbox exists on a catch-all domain (v2.1)
  //   score: 0..100, grade: 'A'..'F',
  //   disposable, free, role: booleans,
  //   suggestion: '[email protected]' | null,   // typo fix (clickable in the feedback)
  //   email: '[email protected]',
  //   raw: { ...full API response }
  // }
  if (!e.detail.accepted) console.log('blocked:', r.subStatus);
});

document.addEventListener('atv:error', function (e) {
  // e.detail.error: NETWORK_ERROR | TIMEOUT | RATE_LIMITED | NO_CREDITS |
  //                 DOMAIN_BLOCKED | AUTH_ERROR | API_ERROR | PARSE_ERROR | NO_KEY
  console.warn(e.detail.email, e.detail.error);
});
Attributo sull'inputValoriSignificato
data-atv-valid"true" | "false"Accettato dalle tue regole (ciรฒ che preventSubmit controlla)
data-atv-statedeliverable | risky | unknown | undeliverableStato derivato
data-atv-bound"1"Il widget รจ collegato a questo input

API programmatica โ€” senza collegamento al DOM

Valida su richiesta (ad es. prima di un invio XHR), riesegui la scansione, svuota la cache, smonta il widget.

// Validate a single address (publicKey optional if init() already ran)
ATValid.validate('[email protected]', 'pk_live_your_key', function (result) {
  console.log(result.accepted, result.state, result.subStatus, result.score, result.toxicity);
});

ATValid.refresh();     // re-scan the DOM for new email inputs (SPA navigation)
ATValid.clearCache();  // forget the 5-minute in-page cache
ATValid.destroy();     // remove listeners, observer, styles and feedback
Limiti per le chiavi pubbliche: 60 richieste/min per chiave e 30/min per IP del visitatore. I risultati restano in cache nella pagina per 5 minuti, quindi riscrivere lo stesso indirizzo non costa nulla.

Stile

Il widget inietta un CSS minimo; puoi sovrascrivere qualsiasi classe nel tuo foglio di stile.

.atv-input-valid    { border-color: #22c55e !important; box-shadow: 0 0 0 3px rgba(34,197,94,.1) !important; }
.atv-input-invalid  { border-color: #ef4444 !important; box-shadow: 0 0 0 3px rgba(239,68,68,.1) !important; }
.atv-input-checking { border-color: #9ca3af !important; }

.atv-feedback   { font-size: .8125rem; margin-top: .25rem; font-family: inherit; }
.atv-valid      { color: #22c55e; }
.atv-invalid    { color: #ef4444; }
.atv-checking   { color: #9ca3af; }
.atv-suggestion { color: #d97706; cursor: pointer; text-decoration: underline; }
.atv-suggestion:hover { color: #b45309; }