Un guide complet pour créer des formulaires accessibles et robustes dans SvelteKit à l'aide de l'amélioration progressive, garantissant une expérience utilisateur transparente pour tous.
Formulaires SvelteKit : Maîtriser l'amélioration progressive
Les formulaires sont l'épine dorsale de l'interaction utilisateur sur le Web. Des simples formulaires de contact aux flux de travail d'application complexes, ils sont essentiels pour collecter des informations et permettre aux utilisateurs d'effectuer des actions. SvelteKit, avec son orientation sur la performance et l'expérience développeur, fournit des outils puissants pour créer des formulaires robustes et accessibles. Ce guide explore comment tirer parti de l'amélioration progressive pour créer des formulaires qui fonctionnent pour tout le monde, quelles que soient les capacités de leur navigateur ou les conditions du réseau.
Qu'est-ce que l'amélioration progressive ?
L'amélioration progressive est une stratégie de développement Web qui consiste à donner la priorité à la création d'une expérience de base fonctionnelle et accessible pour tous les utilisateurs, puis à ajouter progressivement des fonctionnalités avancées et des améliorations pour les utilisateurs disposant de navigateurs ou d'appareils plus performants. Il s'agit d'une approche axée sur la résilience qui garantit que votre site Web ou votre application reste utilisable même face à des limitations techniques.
Dans le contexte des formulaires, cela signifie :
- Fonctionnalité de base : Le formulaire doit être utilisable avec HTML et CSS de base, même sans JavaScript.
- Accessibilité : Les éléments de formulaire doivent être correctement étiquetés et accessibles aux technologies d'assistance.
- Expérience améliorée : JavaScript peut être utilisé pour ajouter des fonctionnalités telles que la validation en temps réel, les champs de formulaire dynamiques et les éléments d'interface utilisateur améliorés.
Pourquoi est-ce important ? Considérez les scénarios suivants :
- Utilisateurs avec JavaScript désactivé : Certains utilisateurs désactivent intentionnellement JavaScript pour des raisons de sécurité ou de confidentialité.
- Utilisateurs avec des navigateurs plus anciens : Les navigateurs plus anciens peuvent ne pas prendre en charge les dernières fonctionnalités JavaScript.
- Utilisateurs avec des connexions Internet lentes ou peu fiables : Les fichiers JavaScript peuvent prendre beaucoup de temps à charger, ou peuvent ne pas se charger du tout.
- Utilisateurs utilisant des technologies d'assistance : Les lecteurs d'écran s'appuient sur le code HTML sémantique pour offrir une expérience utilisable.
En adoptant l'amélioration progressive, vous vous assurez que vos formulaires sont utilisables par le public le plus large possible.
SvelteKit et les formulaires : une combinaison parfaite
L'architecture de SvelteKit le rend bien adapté à la création de formulaires améliorés de manière progressive. Il vous permet de définir des actions de formulaire qui peuvent être gérées à la fois sur le serveur et sur le client, ce qui vous donne la flexibilité de fournir une expérience transparente, que JavaScript soit activé ou non.
Rendu côté serveur (SSR)
Les capacités de rendu côté serveur de SvelteKit sont essentielles pour l'amélioration progressive. Lorsqu'un utilisateur soumet un formulaire sans JavaScript, les données du formulaire sont envoyées au serveur, où elles peuvent être traitées et validées. Le serveur peut ensuite rendre une nouvelle page avec les résultats de la soumission du formulaire, offrant ainsi une expérience de base mais fonctionnelle.
Hydratation côté client
Lorsque JavaScript est activé, la fonctionnalité d'hydratation côté client de SvelteKit prend le relais. Le code HTML rendu côté serveur est « hydraté » avec JavaScript, ce qui vous permet d'ajouter des fonctionnalités interactives et d'améliorer l'expérience utilisateur. Cela comprend :
- Validation en temps réel : Fournissez une rétroaction instantanée aux utilisateurs lorsqu'ils remplissent le formulaire.
- Champs de formulaire dynamiques : Ajoutez ou supprimez des champs de formulaire en fonction de la saisie de l'utilisateur.
- Éléments d'interface utilisateur améliorés : Utilisez JavaScript pour améliorer l'apparence et la fonctionnalité des éléments de formulaire.
Création d'un formulaire amélioré de manière progressive dans SvelteKit
Passons en revue un exemple de création d'un simple formulaire de contact dans SvelteKit, en démontrant les principes de l'amélioration progressive.
1. Le formulaire HTML de base
Tout d'abord, créez un formulaire HTML de base dans une route SvelteKit (par exemple, `src/routes/contact/+page.svelte`) :
<form method="POST" action="?/submit">
<label for="name">Nom :</label>
<input type="text" id="name" name="name" required>
<label for="email">Courriel :</label>
<input type="email" id="email" name="email" required>
<label for="message">Message :</label>
<textarea id="message" name="message" required></textarea>
<button type="submit">Envoyer le message</button>
</form>
Points clés :
- `method="POST"` : Spécifie que les données du formulaire doivent être envoyées à l'aide de la méthode POST.
- `action="?/submit"` : Spécifie l'action à effectuer lorsque le formulaire est soumis. Dans SvelteKit, `?/submit` est une convention pour définir une action de formulaire dans la même route.
- attribut `required` : Garantit que les champs sont obligatoires avant la soumission (géré par le navigateur si JavaScript est désactivé).
- Étiquettes : Chaque entrée est correctement étiquetée pour l'accessibilité.
2. Définition de l'action de formulaire côté serveur
Ensuite, créez un fichier `+page.server.js` dans le même répertoire pour définir l'action de formulaire côté serveur :
import { fail } from '@sveltejs/kit';
/** @type {import('./$types').Actions} */
export const actions = {
submit: async ({ request }) => {
const data = await request.formData();
const name = data.get('name');
const email = data.get('email');
const message = data.get('message');
if (!name) {
return fail(400, { name: { missing: true } });
}
if (!email) {
return fail(400, { email: { missing: true } });
}
if (!message) {
return fail(400, { message: { missing: true } });
}
// Basic email validation
if (!/^\w+[\.-]?\w+)*@(\w+[\.-]?\w+)*(\.\w{2,4})+$/.test(email)) {
return fail(400, { email: { invalid: true } });
}
// Simulate sending the email
console.log('Name:', name);
console.log('Email:', email);
console.log('Message:', message);
return { success: true };
}
};
Points clés :
- objet `actions` : Cet objet contient les actions de formulaire pour la route.
- action `submit` : Cette fonction est appelée lorsque le formulaire est soumis.
- `request.formData()` : Récupère les données du formulaire à partir de la requête.
- Validation : Le code valide les données du formulaire sur le serveur. S'il y a des erreurs, il renvoie une réponse `fail` avec des messages d'erreur.
- fonction `fail` : Cette fonction est fournie par `@sveltejs/kit` et est utilisée pour renvoyer une réponse d'erreur avec un code d'état et des données d'erreur.
- Réponse de succès : Si les données du formulaire sont valides, le code simule l'envoi du courriel et renvoie une réponse `success`.
3. Affichage des erreurs de validation
Pour afficher les erreurs de validation dans le composant Svelte, vous pouvez utiliser la propriété `form` qui est automatiquement transmise au composant lorsqu'une action de formulaire renvoie une réponse `fail`. Ajoutez le code suivant à `src/routes/contact/+page.svelte` :
<script>
/** @type {import('./$types').PageData} */
export let data;
</script>
<form method="POST" action="?/submit">
<label for="name">Nom :</label>
<input type="text" id="name" name="name" required>
{#if data?.form?.name?.missing}
<p class="error">Le nom est obligatoire.</p>
{/if}
<label for="email">Courriel :</label>
<input type="email" id="email" name="email" required>
{#if data?.form?.email?.missing}
<p class="error">Le courriel est obligatoire.</p>
{/if}
{#if data?.form?.email?.invalid}
<p class="error">Le courriel n'est pas valide.</p>
{/if}
<label for="message">Message :</label>
<textarea id="message" name="message" required></textarea>
{#if data?.form?.message?.missing}
<p class="error">Le message est obligatoire.</p>
{/if}
<button type="submit">Envoyer le message</button>
{#if data?.success}
<p class="success">Message envoyé avec succès!</p>
{/if}
</form>
<style>
.error {
color: red;
}
.success {
color: green;
}
</style>
Points clés :
- `export let data` : Ceci déclare une propriété nommée `data` qui recevra les données transmises par le serveur.
- `data?.form` : Ceci accède en toute sécurité à la propriété `form` de l'objet `data`. L'opérateur `?` est utilisé pour le chaînage optionnel afin d'éviter les erreurs si `data` ou `form` ne sont pas définis.
- Rendu conditionnel : Les blocs `{#if}` rendent conditionnellement les messages d'erreur en fonction des données reçues du serveur.
- Message de succès : Un message de succès est affiché si la propriété `success` est définie sur `true`.
À ce stade, le formulaire est fonctionnel même sans JavaScript. Si vous désactivez JavaScript dans votre navigateur et soumettez le formulaire, vous devriez voir les erreurs de validation affichées correctement.
4. Ajout d'améliorations côté client
Maintenant, ajoutons des améliorations côté client pour améliorer l'expérience utilisateur. Nous pouvons ajouter une validation en temps réel et empêcher le formulaire de se soumettre s'il y a des erreurs. Cela nécessitera du code JavaScript dans le composant Svelte.
<script>
/** @type {import('./$types').PageData} */
export let data;
let nameError = null;
let emailError = null;
let messageError = null;
function validateForm() {
nameError = null;
emailError = null;
messageError = null;
let isValid = true;
if (!$name) {
nameError = 'Le nom est obligatoire.';
isValid = false;
}
if (!$email) {
emailError = 'Le courriel est obligatoire.';
isValid = false;
} else if (!/^\w+([\.-]?\w+)*@\w+([\.-]?\w+)*(\.\w{2,3})+$/.test($email)) {
emailError = 'Le courriel n'est pas valide.';
isValid = false;
}
if (!$message) {
messageError = 'Le message est obligatoire.';
isValid = false;
}
return isValid;
}
/** @type {import('svelte/store').Writable<string>} */
import { writable } from 'svelte/store';
const name = writable('');
const email = writable('');
const message = writable('');
async function handleSubmit(event) {
if (!validateForm()) {
event.preventDefault(); // Prevent the form from submitting
return;
}
// If the form is valid, let SvelteKit handle the submission
}
$: $name, $email, $message // Trigger re-render when name, email, or message changes
</script>
<form method="POST" action="?/submit" on:submit={handleSubmit}>
<label for="name">Nom :</label>
<input type="text" id="name" name="name" bind:value={$name} required>
{#if nameError || data?.form?.name?.missing}
<p class="error">{nameError || 'Le nom est obligatoire.'}</p>
{/if}
<label for="email">Courriel :</label>
<input type="email" id="email" name="email" bind:value={$email} required>
{#if emailError || data?.form?.email?.missing || data?.form?.email?.invalid}
<p class="error">{emailError || data?.form?.email?.missing ? 'Le courriel est obligatoire.' : 'Le courriel n'est pas valide.'}</p>
{/if}
<label for="message">Message :</label>
<textarea id="message" name="message" bind:value={$message} required></textarea>
{#if messageError || data?.form?.message?.missing}
<p class="error">{messageError || 'Le message est obligatoire.'}</p>
{/if}
<button type="submit">Envoyer le message</button>
{#if data?.success}
<p class="success">Message envoyé avec succès!</p>
{/if}
</form>
<style>
.error {
color: red;
}
.success {
color: green;
}
</style>
Points clés :
- Magasins Svelte : Utilisation de magasins inscriptibles (`name`, `email`, `message`) pour gérer les valeurs d'entrée du formulaire.
- `bind:value` : Cette directive lie la valeur des champs de saisie aux magasins Svelte correspondants. Toute modification dans le champ de saisie met automatiquement à jour la valeur du magasin, et vice versa.
- `on:submit={handleSubmit}` : Ce gestionnaire d'événements est appelé lorsque le formulaire est soumis.
- `validateForm()` : Cette fonction effectue la validation côté client et définit les messages d'erreur.
- `event.preventDefault()` : Ceci empêche le formulaire de se soumettre s'il y a des erreurs.
- Affichage des messages d'erreur : Les messages d'erreur sont affichés en fonction de la validation côté client et côté serveur. Ceci garantit que l'utilisateur voit les erreurs même si JavaScript est désactivé ou ne parvient pas à se charger.
5. Gestion gracieuse des erreurs JavaScript
Même avec la validation côté client, il est important de gérer gracieusement les erreurs JavaScript potentielles. Si JavaScript ne parvient pas à se charger ou à s'exécuter correctement, vous voulez toujours que le formulaire soit utilisable. Le formulaire fonctionne déjà sans JavaScript grâce à l'action côté serveur. Envisagez d'ajouter la consignation des erreurs à votre code côté client pour surveiller les erreurs JavaScript qui pourraient survenir en production. Des outils comme Sentry ou Bugsnag peuvent vous aider à suivre et à résoudre les erreurs JavaScript en temps réel.
Meilleures pratiques pour les formulaires SvelteKit avec amélioration progressive
- Commencez par HTML : Commencez toujours par créer un formulaire HTML fonctionnel avec un balisage sémantique approprié et des considérations d'accessibilité.
- Validation côté serveur : Validez toujours les données du formulaire sur le serveur, même si vous les validez également sur le client. Ceci est essentiel pour la sécurité et l'intégrité des données.
- Amélioration côté client : Utilisez JavaScript pour améliorer l'expérience utilisateur, mais assurez-vous que le formulaire reste utilisable sans celui-ci.
- Accessibilité : Portez une attention particulière à l'accessibilité. Utilisez des étiquettes appropriées, des attributs ARIA et une navigation au clavier pour vous assurer que vos formulaires sont utilisables par tous. Des outils comme Axe DevTools peuvent vous aider à identifier les problèmes d'accessibilité.
- Gestion des erreurs : Gérez les erreurs JavaScript avec élégance et fournissez des messages d'erreur informatifs à l'utilisateur.
- Performance : Optimisez votre code JavaScript pour vous assurer qu'il se charge et s'exécute rapidement. Utilisez la division du code et le chargement paresseux pour réduire le temps de chargement initial de votre application.
- Test : Testez minutieusement vos formulaires avec et sans JavaScript activé pour vous assurer qu'ils fonctionnent comme prévu dans tous les scénarios. Utilisez des outils de test automatisés pour détecter les régressions.
- Internationalisation (i18n) : Si votre application cible un public mondial, envisagez d'internationaliser vos formulaires. Utilisez une bibliothèque comme `svelte-i18n` pour gérer les traductions. Portez une attention particulière aux différents formats de date et de nombre dans différentes langues.
- Sécurité : Soyez conscient des vulnérabilités courantes en matière de sécurité Web, telles que les attaques de script intersite (XSS) et les falsifications de requête intersite (CSRF). Assainissez les entrées des utilisateurs et utilisez les en-têtes de sécurité appropriés pour protéger votre application.
- Expérience utilisateur (UX) : Concevez vos formulaires en pensant à l'utilisateur. Facilitez leur compréhension et leur utilisation. Fournissez des instructions claires et une rétroaction utile. Envisagez d'utiliser la divulgation progressive pour afficher uniquement les informations pertinentes pour l'utilisateur à un moment donné.
Techniques avancées
Utilisation de JavaScript pour améliorer la soumission de formulaires
Au lieu de vous fier au comportement de soumission de formulaire par défaut, vous pouvez utiliser JavaScript pour intercepter la soumission de formulaire et envoyer les données au serveur à l'aide de `fetch`. Cela vous permet de fournir une expérience utilisateur plus transparente, comme l'affichage d'un indicateur de chargement pendant que le formulaire est soumis et la mise à jour de la page sans rechargement complet de la page.
async function handleSubmit(event) {
event.preventDefault(); // Prevent default form submission
if (!validateForm()) {
return;
}
try {
const formData = new FormData(event.target);
const response = await fetch(event.target.action, {
method: 'POST',
body: formData,
headers: {
'X-Requested-With': 'XMLHttpRequest' // Indicate that this is an AJAX request
}
});
if (!response.ok) {
throw new Error(`HTTP error! Status: ${response.status}`);
}
const data = await response.json();
if (data.success) {
// Handle success
console.log('Form submitted successfully!');
} else {
// Handle errors
console.error('Form submission failed:', data);
}
} catch (error) {
console.error('There was an error submitting the form:', error);
}
}
Points clés :
- `event.preventDefault()` : Empêche le comportement de soumission de formulaire par défaut.
- `FormData` : Crée un objet `FormData` à partir des données du formulaire.
- `fetch` : Envoie les données du formulaire au serveur à l'aide de `fetch`.
- En-tête `X-Requested-With` : Cet en-tête est utilisé pour indiquer que la requête est une requête AJAX.
- Gestion des erreurs : Le code gère les erreurs potentielles pendant le processus de soumission du formulaire.
Champs de formulaire dynamiques
Vous pouvez utiliser JavaScript pour ajouter ou supprimer des champs de formulaire de manière dynamique en fonction de la saisie de l'utilisateur. Ceci peut être utile pour créer des formulaires qui s'adaptent aux besoins de l'utilisateur.
Exemple : Ajout d'un nombre dynamique d'adresses courriel :
<script>
import { writable } from 'svelte/store';
const emailAddresses = writable(['']);
function addEmailAddress() {
emailAddresses.update(emails => [...emails, '']);
}
function removeEmailAddress(index) {
emailAddresses.update(emails => emails.filter((_, i) => i !== index));
}
</script>
<div>
{#each $emailAddresses as email, index}
<div>
<label for="email-{index}">Courriel {index + 1} :</label>
<input type="email" id="email-{index}" bind:value={$emailAddresses[index]}>
<button type="button" on:click={() => removeEmailAddress(index)}>Supprimer</button>
</div>
{/each}
<button type="button" on:click={addEmailAddress}>Ajouter une adresse courriel</button>
</div>
Points clés :
- magasin `emailAddresses` : Ce magasin contient un tableau d'adresses courriel.
- `addEmailAddress()` : Cette fonction ajoute une nouvelle adresse courriel au tableau.
- `removeEmailAddress()` : Cette fonction supprime une adresse courriel du tableau.
- bloc `{#each}` : Ce bloc itère sur les adresses courriel et rend un champ de saisie pour chacune d'elles.
- `bind:value` : Cette directive lie la valeur du champ de saisie à l'adresse courriel correspondante dans le tableau. *Remarque : La liaison directe à des éléments de tableau dans un magasin nécessite une certaine prudence. Envisagez d'utiliser une solution de gestion d'état plus robuste pour les formulaires dynamiques complexes.*
Intégration avec des services tiers
Vous pouvez intégrer vos formulaires SvelteKit à des services tiers, tels que des plateformes de marketing par courriel, des systèmes CRM ou des passerelles de paiement. Ceci peut être fait à l'aide des actions de formulaire côté serveur.
Exemple : Envoi des données du formulaire à une plateforme de marketing par courriel :
// +page.server.js
import { fail } from '@sveltejs/kit';
/** @type {import('./$types').Actions} */
export const actions = {
submit: async ({ request }) => {
const data = await request.formData();
const name = data.get('name');
const email = data.get('email');
// Validate the form data
try {
// Send the data to the email marketing platform
const response = await fetch('https://api.example.com/subscribe', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Authorization': 'Bearer YOUR_API_KEY'
},
body: JSON.stringify({
name,
email
})
});
if (!response.ok) {
throw new Error(`HTTP error! Status: ${response.status}`);
}
// Handle success
return { success: true };
} catch (error) {
// Handle errors
console.error('Error subscribing to email list:', error);
return fail(500, { message: 'Failed to subscribe. Please try again later.' });
}
}
};
Points clés :
- `fetch` : Envoie les données du formulaire à la plateforme de marketing par courriel à l'aide de `fetch`.
- Clé API : Le code comprend une clé API pour s'authentifier auprès de la plateforme de marketing par courriel. *Important : N'exposez jamais vos clés API directement dans le code côté client. Utilisez des variables d'environnement ou un système de gestion des secrets sécurisé.*
- Gestion des erreurs : Le code gère les erreurs potentielles pendant la requête API.
Conclusion
La création de formulaires accessibles et robustes est essentielle pour créer une expérience utilisateur positive. SvelteKit, avec son orientation sur la performance et l'expérience développeur, fournit les outils dont vous avez besoin pour créer des formulaires qui fonctionnent pour tout le monde, quelles que soient les capacités de leur navigateur ou les conditions du réseau. En adoptant l'amélioration progressive, vous pouvez vous assurer que vos formulaires sont utilisables par le public le plus large possible et que votre application reste résiliente face aux défis techniques. Ce guide a fourni un aperçu complet de la façon de créer des formulaires améliorés de manière progressive dans SvelteKit, couvrant tout, des formulaires HTML de base aux techniques avancées comme les champs de formulaire dynamiques et les intégrations de tiers. En suivant ces meilleures pratiques, vous pouvez créer des formulaires qui sont non seulement fonctionnels et accessibles, mais qui offrent également une expérience utilisateur transparente et agréable.