La sortie statique reste possible
Une route Nitro empêche nuxt generate de suffire. Gardez le formulaire externe pour toujours pouvoir déployer le site en fichiers.
intégrations · framework
Nuxt inclut un serveur : un fichier server/api/ donne une route Nitro simple. Mais nuxt generate pré-génère sur CDN sans runtime Nitro : server/api/contact.post.ts est compilé sans être déployé là où il peut s’exécuter.
Ce piège touche ceux qui choisissent Nuxt pour le statique. Avec mailcontact, la page fonctionne pareil sous nuxt build avec Node, nuxt generate sur CDN et le prochain préréglage de l’hébergeur.
configuration recommandée
Ajoutez ce HTML à votre site, ou utilisez le générateur de formulaires. Remplacez le lien du formulaire par le vôtre. Le script hébergé injecte le contrôle caché, gère l’envoi et la vérification automatique, et conserve le brouillon en cas d’erreur. Vous contrôlez le HTML et le CSS. Les formulaires Free affichent un lien visible « Traité par mailcontact.app » ; Pro et Plus ne l’affichent pas. Les messages de retour suivent la langue du navigateur ; définissez data-mailcontact-language="fr" sur le formulaire pour imposer le français.
<form action="https://mailcontact.app/api/forms/your-form-id" method="POST" data-mailcontact-form lang="fr" data-mailcontact-language="fr">
<input type="hidden" name="_language" value="fr" />
<fieldset>
<legend>Contactez-nous</legend>
<label>
Nom (facultatif)
<input name="name" type="text" autocomplete="name" maxlength="200" />
</label>
<label>
Email
<input name="email" type="email" autocomplete="email" maxlength="320" required />
</label>
<label>
Message
<textarea name="message" rows="5" maxlength="5000" required></textarea>
</label>
<noscript>
<div aria-hidden="true" style="position:absolute;left:-10000px;width:1px;height:1px;overflow:hidden;">
<label>Site web
<input name="company_website" type="text" tabindex="-1" autocomplete="off" />
</label>
</div>
</noscript>
<button type="submit">Envoyer le message</button>
</fieldset>
<p data-contact-status role="status" aria-live="polite" aria-atomic="true"></p>
</form>
<script defer src="https://mailcontact.app/forms/v1.js" crossorigin="anonymous" referrerpolicy="no-referrer"></script>Pour un composant doté de son propre gestionnaire d’envoi, chargez le même script et utilisez MailContact.prepare(form) et MailContact.send() au lieu du marqueur automatique. Voir la référence des interfaces personnalisées pour le chargement, les messages de retour et l’attribution Free.
l’extrait
Cet exemple appelle directement l’API. Gardez le champ requis company_website champ présent et vide. Les envois natifs ouvrent du JSON en cas de succès ou une page de vérification si nécessaire. Les scripts personnalisés sans vérification envoient les messages suspects dans les spams pour examen ; les spams manifestes y sont aussi retenus sans notification ni consommation du quota. Un succès confirme la réception, y compris pour examen, ou l’abandon silencieux d’un contrôle rempli. Voir protection antispam pour le comportement complet.
<script setup>
// No server/api/contact.post.ts. Nothing here needs Nitro at runtime,
// so `nuxt generate` keeps this page fully working.
const sent = ref(false);
async function submit(event) {
await $fetch("https://mailcontact.app/api/forms/your-form-id", {
method: "POST",
body: new FormData(event.target),
});
sent.value = true;
}
</script>
<template>
<p v-if="sent">Thanks. We'll be in touch.</p>
<form v-else @submit.prevent="submit">
<input name="name" placeholder="Your name" required />
<input name="email" type="email" placeholder="[email protected]" required />
<textarea name="message" placeholder="What's on your mind?" required />
<input name="company_website" type="text" tabindex="-1" autocomplete="off"
style="position:absolute;left:-10000px" aria-hidden="true" />
<button>Send</button>
</form>
</template>fonctionnement
Une boîte par projet. URL et adresse de projet actives avant d’ajouter la page.
Collez dans pages/contact.vue et remplacez l’identifiant. Aucun fichier server/, entrée runtimeConfig ou clé à garder hors du bundle client.
Ajoutez Discord, Slack, email ou webhook pour recevoir les messages dès leur arrivée.
pourquoi mailcontact
Une route Nitro empêche nuxt generate de suffire. Gardez le formulaire externe pour toujours pouvoir déployer le site en fichiers.
La solution maison exige clé API mail, secret, stockage et configuration par hébergeur. Ici, aucune clé à divulguer ni renouveler.
Les préréglages Nitro varient selon l’hébergeur. Une route peut se comporter différemment ; une URL externe reste identique partout sans toucher au préréglage.
FAQ
Oui, avec un serveur. server/api/contact.post.ts fonctionne avec nuxt build et un préréglage Node ou serverless, mais pas nuxt generate : un site pré-généré n’a pas de runtime Nitro pour recevoir le POST. Pour garder du statique, sortez le formulaire du serveur.
Oui. L’exemple utilise ref, $fetch et @submit.prevent, stables dans les deux versions. Vous pouvez remplacer $fetch par fetch : les données sont toujours FormData, sans dépendre de Nuxt.
Non. useFetch sert aux données nécessaires au rendu, avec déduplication et cache, ce qui ne convient pas à un POST unique déclenché par un clic. Appelez $fetch (ou fetch) dans le gestionnaire d’envoi.
Le contrôle company_website doit être présent et vide. Le remplir ignore silencieusement l’envoi, mais un robot avancé peut l’éviter. MailContact applique aussi limites serveur, contrôles de contenu et de campagnes. Le script hébergé gère la vérification si nécessaire ; les spams manifestes sont retenus sans notification ni quota.
voir aussi
Formulaires et vraie adresse email, ensemble, avec des notifications dans vos outils. Commencez gratuitement.
Créer mon formulaireAucune carte bancaire requise. Free comprend un projet et 50 messages de formulaire par mois.