Héberger gratuitement votre site avec un formulaire de contact
Ou comment créer une SPA avec Nuxt 3 et la déployer en utilisant les fonctionnalités serverless de Netlify
Il arrive souvent de devoir créer un site statique, mais avec un formulaire de contact. Cela peut être le cas pour un site vitrine, pour un CV en ligne, ou même seulement pour une page de site en cours de construction… Un site statique peut être hébergé à peu près n'importe où, mais ajouter un simple formulaire de contact y ajoute une contrainte supplémentaire : il faut valider le formulaire, récupérer les données saisies, et peut-être même envoyer un e-mail.
Heureusement, il est aujourd'hui très simple d'inclure cette fonctionnalité, sans avoir à la développer et sans payer le coût de l'hébergement d'un backend. Je vais vous présenter ici comment réaliser un projet sur Netlify, de la création au déploiement automatisé.
Pour cet exemple, le projet sera développé avec Nuxt 3, framework basé sur Vue.js 3. Mais pas d'inquiétude, vous pourrez sauter cette section si votre site statique est développé autrement.
A noter : la gratuité de ce service dépend de votre utilisation. Au-delà de 100 envois (hors spams) par mois, il vous sera facturé automatiquement, d'où notre utilisation comme formulaire de contact.
Création du projet et CI/CD
Pour commencer, créez votre projet sur votre gestionnaire Git préféré (Netlify accepte actuellement GitHub, GitLab et Bitbucket). Ici par exemple sur GitLab.
Une fois cela réalisé, et après avoir créé un compte sur Netlify, allez dans la partie « Sites », puis « Add new site » et « Import an existing project ».
Ensuite, choisissez votre provider Git, ainsi que votre branche de déploiement. Comme nous n'avons fait aucun paramétrage dans GitLab, notre branche sera main. Il est toujours possible de la changer en cours de route.
Vous pouvez spécifier le dossier racine, la commande de build, le dossier de publication, et d'autres choses selon votre besoin. Laissons tout par défaut.
… Et voilà, votre site est prêt à être mis en ligne ! A chaque commit sur la branche sélectionnée, la nouvelle version sera déployée. Vous n'avez rien eu à faire, votre CI est déjà en place.
Vous êtes maintenant prêt à développer votre site !
Génération statique avec Nuxt 3
Si vous n'utilisez pas Nuxt, vous pouvez passer au chapitre suivant. Sinon, voici la méthode pour créer un site statique… Avec des données dynamiques.
Création du projet
Créons notre projet avec Nuxt 3 (cf. Quick Start) : npx nuxi init demo-app
Vous devriez avoir une arborescence similaire à celle-ci :
Personnellement, je déplace ensuite le contenu du dossier demo-app
dans le répertoire du dessus.
A noter : Nuxt 3 est à ce jour encore en développement (release candidate 5), et j'ai fait mes tests sur la rc 3. J'ai rencontré quelques soucis avec d'anciennes versions, qui m'empêchaient de générer le projet correctement, mais cela a fonctionné à partir de la version 3.0.0-rc.3-27550969.a4a3cff
. Si vous rencontrez des erreurs lors du build, vous pouvez donc modifier la version comme suit dans le fichier package.json
:
"devDependencies": {
"nuxt": "npm:nuxt3@3.0.0-rc.3-27550969.a4a3cff"
}
Nous pouvons maintenant installer les dépendances avec npm install
, puis lancer le projet avec npm run dev
. Il devrait être accessible après quelques instants sur http://localhost:3000.
Génération statique
Pour générer un site statique avec Nuxt, il faut lancer la commande generate
. Cependant, il faut auparavant configurer le projet pour autoriser la génération statique en modifiant le fichier nuxt.config.ts
.
A présent, exécutez la commande npm run generate
. Vous devriez voir apparaître les dossiers .output
et dist
(que vous pouvez ajouter au .gitignore
).
Sur Netlify, allez dans les paramètres de build de votre projet et spécifiez la commande de build (npm run generate
) le dossier d'output (dist
).
Vous pouvez commit / push, et regarder Netlify déployer votre site tout neuf !
Formulaire Netlify
Maintenant que votre site est créé, il est temps d'y ajouter quelques fonctionnalités… En commençant par un formulaire.
Netlify permet de créer gratuitement un formulaire complètement fonctionnel et sécurisé. La documentation complète se trouve sur cette page, mais voici les étapes à retenir :
- Créer un formulaire HTML classique
- Ajouter au formulaire quelques balises spécifiques à Netlify
- Sécuriser le formulaire
- Configurer l'envoi de mail dans Netlify
Création du formulaire
Commençons par créer un formulaire simple en remplaçant le contenu du fichier app.vue
. Pour l'exemple, nous ne garderons qu'un input "email", mais vous pouvez créer un formulaire complet avec autant de champs que vous voulez.
Ensuite, ajoutons le tag netlify
qui permet de dire à Netlify que nous voulons qu'il traite ce formulaire automatiquement.
<form name="myForm" method="post" netlify >
En principe, c'est tout ce dont on a besoin pour que le formulaire fonctionne sur Netlify. Cependant, si comme moi vous utilisez Nuxt, vous aurez un problème : le formulaire n'est pas détecté par Netlify, car le contenu de notre page est créé via JavaScript : il suffit de générer notre projet pour se rendre compte que le fichier dist/index.html
ne contient pas notre formulaire.
Formulaire avec Nuxt
Pour palier à ce problème, une méthode simple consiste à créer un fichier html brut décrivant notre formulaire. Cette solution décrite ici est peu élégante, car il faudra mettre à jour le formulaire dans les deux fichiers en même temps. Elle reste cependant la plus simple à mettre en oeuvre.
Dans le dossier public
, on crée un formulaire hidden avec les champs utilisés
<form name="myForm" netlify hidden>
<input name="email" type="email" />
</form>
Pour que Netlify reçoive les données, le formulaire de notre fichier app.vue
doit maintenant contenir un champ input form-name
hidden contenant comme valeur le nom de notre formulaire. Plus besoin de name
ni netlify
sur la balise <form>
, car Netlify analysera le fichier .html
créé précédemment.
Et voilà ! Lors du prochain commit du code, le formulaire sera en ligne et prêt à être utilisé.
Sécurisation du formulaire
Il est vivement recommandé de sécuriser un minimum le formulaire contre les spams. Netlify utilise déjà le service Akismet pour cela, mais permet d'ajouter une sécurité supplémentaire, ce qui est toujours bienvenue pour cette problématique importante. Deux solutions sont proposées :
- Ajouter un reCaptcha Google
- Ajouter un champ honeypot afin de leurrer les bots
Le champ honeypot pose quelques contraintes supplémentaires mais a l'avantage de ne pas imposer l'utilisation de cookies et d'être moins invasif pour les utilisateurs. Il est aussi un peu moins efficace pour filtrer les bots, mais peut être suffisant en combinaison avec Akismet. Cependant, gardez à l'esprit qu'il est nécessaire de respecter certaines règles afin de garder un honeypot utile.
Configurer l'envoi de mails
Maintenant que notre formulaire est en ligne, nous pouvons configurer certains paramètres dans Netlify pour qu'un mail soit envoyé automatiquement.
Rendre le site dynamique avec Nuxt
Notre page statique fonctionne, mais il est aussi possible d'avoir un site multi-pages dont les données sont dynamiques.
SPA et Routing Nuxt
Il est relativement commun d'avoir plusieurs pages sur un site web… Cependant, étant donné que nous n'avons pas de backend pour gérer les routes, il est nécessaire d'indiquer à Netlify que nous voulons nous comporter comme une Single Page Application avec un routing côté front.
Première étape : modifier notre exemple pour ajouter une seconde page, "About us". Il suffit de créer un dossier pages
et de créer deux fichiers, index.vue
, qui correspond à la page d'accueil (et qui contiendra maintenant notre formulaire), et about.vue
, qui sera notre nouvelle page. Le fait de créer un fichier .vue
dans un dossier pages
active le routing Nuxt au prochain build.
Le fichier app.vue
va également changer, pour que l'application Nuxt affiche le contenu de chaque page via la balise <NuxtPage />
. En mode développement (npm run dev
), pensez à relancer votre serveur.
Seconde étape : Si nous déployons le site tel quel, l'url http://localhost:3000/about sera accessible en local, mais l'équivalent déployé sur Netlify ne le sera pas. Il faut spécifier à Netlify que toutes les url doivent mener à la racine, via un fichier _redirects
.
# The following redirect is intended for use with most SPAs that handle routing internally.
/* /index.html 200
Cela permet de rediriger tous les chemins vers index.html
. Il faut aussi que ce fichier soit copié dans le répertoire de destination du build. Ici par exemple à l'aide du package copyfile
avec la modification du package.json
.
J'ai utilisé ici le script postbuild
qui est automatiquement appelé à la fin d'une commande npm run build
. J'ai donc supprimé la commande generate
pour utiliser la commande build
à la place, et il m'a fallu mettre à jour la commande de build dans Netlify avant de faire le commit.
Notre SPA fonctionne maintenant lorsqu'elle est déployée sur Netlify. Vous pouvez aller sur la page /contact
et rafraîchir sans problème.
Appels APIs
Notre site est statique, mais il est tout à fait possible de le rendre dynamique en faisant appel à des APIs externes.
Pour que cela fonctionne, il faut qu'elles acceptent les requêtes CORS. Si vous développez vos propres APIs, je vous conseille plutôt de configurer celles-ci pour accepter exclusivement les appels depuis l'URL de votre frontend, pour des raisons de sécurité.
Formulaires dynamiques
Nous avons vu précédemment comment créer un formulaire fixe dans Vue.js, et comment le faire reconnaître par Netlify. Nous avons ainsi dû définir chaque champ à envoyer manuellement.
Il existe cependant une technique pour créer des formulaires dynamiques dans vue. Cela nécessite de coder soi-même l'envoi du formulaire à Netlify. Ce sujet nécessiterait un article à lui tout seul, je vous conseille donc de jeter un coup d'œil au lien précédent.
Important : comme précédemment, n'oubliez pas le champ caché form-name
nécessaire pour que Netlify comprenne de quel formulaire il s'agit.
axios.post(
"/",
this.encode({
"form-name": "myForm",
...this.form
}),
axiosConfig
);
Bonus : fonctions serverless
Nous avons créé un site qui appelle des APIs externes. Il est aussi possible de créer des fonctions serverless dans Netlify ! Ces fonctions sont des morceaux de codes (JavaScript, TypeScript ou Go) qui seront appelés à la volée sans avoir à maintenir votre propre serveur.
Netlify limite la durée des fonctions à 10 secondes. Il est possible de faire des traitements plus longs (jusqu'à 15 minutes) avec les fonctions asynchrones (background functions). Il y a aussi une limite du nombre de requêtes et de la durée de traitement.
Toutes les fonctions doivent correspondre à des fichiers déposés dans le dossier netlify/functions
. Une fonction hello
peut être sauvée de plusieurs manières :
netlify/functions/hello.js
netlify/functions/hello/hello.js
netlify/functions/hello/index.js
Le résultat sera dans tous les cas une API exposée sur /.netlify/functions/hello
. Pour créer une fonction asynchrone, il suffit de rajouter le suffixe -background
.
Nous allons par exemple créer une fonction synchrone qui nous renverra le résultat N de la suite de Fibonacci.
Votre fichier .js
devra exporter une méthode handler
, qui prend en paramètres event
et context
qui contiennent les données de la requête entrante (voir ici pour les détails).
Notre fonction renvoie un code OK 200, et le résultat en body. Le body doit être une string valide, donc nous avons transformé notre objet de retour en JSON, qui devra être décodé côté client. Pour les fonctions asynchrones, on ne renvoie rien.
Ajoutons maintenant une nouvelle page Vue qui fera appel à notre API.
Pour simplifier au maximum mon exemple, je n'ai pas vraiment sécuriser le JSON.parse : en local, la page restera blanche (erreur dans la console).
Lors de notre prochain déploiement, notre API sera appelée côté client. Vous avez créé votre propre fonction serverless !
Vous pouvez retrouver d'autres exemples de fonctions serverless sur cette page.
Pour aller plus loin…
Il reste bien sûr beaucoup de choses intéressantes à voir avec Netlify ! Je vous invite à fouiller dans la documentation et dans les paramètres de votre projet.
Exemples :
- Vous pouvez paramétrer la page de retour du formulaire, mais pensez à modifier l'
action
dans les deux formulaires si vous utilisez Nuxt. - L'upload de fichier est aussi possible, avec une limite assez basse.
- Dans les paramètres "Build & deploy" de votre site, il existe une section "Asset optimization". Il existe aussi une partie "Deploy Previews" pour faire tester vos branches de développement.
Good Luck & Have Fun!