ID du formulaire

SvelteKit

Une page SvelteKit prérendue dont le formulaire envoie directement à Ikiform, améliorée avec fetch une fois JavaScript chargé. Compatible avec adapter-static.

Cette page n'a pas besoin de serveur : l'action du formulaire est votre endpoint Ikiform, donc elle fonctionne avec adapter-static et n'importe quel hébergeur statique. Sans JavaScript, elle envoie et redirige comme du HTML classique ; avec JavaScript, elle envoie avec fetch et affiche le résultat sur place. Pour envoyer plutôt via une form action avec une clé secrète, voir Svelte.

Pourquoi pas use:enhance

Le use:enhance de SvelteKit ne fonctionne qu'avec des formulaires method="POST" qui pointent vers des actions définies dans un fichier +page.server.js. Ikiform est une URL externe, donc la page utilise à la place un petit handler onsubmit. L'amélioration progressive est la même : le formulaire fonctionne d'abord, le script l'améliore ensuite.

Mise en place

  1. Ajoutez des variables d'environnement publiques

    .env
    PUBLIC_IKIFORM_FORM_ID=frm_xxxxxxxxxxxxxxxx
    PUBLIC_SITE_URL=https://example.com

    PUBLIC_SITE_URL sert à la redirection sans JavaScript. Pendant le prérendu, page.url.origin vaut http://sveltekit-prerender et non votre domaine, donc la redirection ne peut pas être construite à partir de lui.

  2. Prérendez la page

    src/routes/contact/+page.js
    export const prerender = true;
  3. Ajoutez le formulaire

    src/routes/contact/+page.svelte
    <script>
      import { PUBLIC_IKIFORM_FORM_ID, PUBLIC_SITE_URL } from "$env/static/public";
    
      const endpoint = `https://ikiform.com/f/${PUBLIC_IKIFORM_FORM_ID}`;
    
      let status = $state("idle");
      let errors = $state({});
      let message = $state("");
    
      async function onsubmit(event) {
        event.preventDefault();
        status = "sending";
        try {
          const response = await fetch(endpoint, {
            method: "POST",
            headers: { Accept: "application/json" },
            body: new FormData(event.currentTarget),
          });
          const result = await response.json();
          if (result.ok) {
            status = "sent";
            return;
          }
          errors = result.error.fields ?? {};
          message = result.error.message;
        } catch {
          message = "Couldn't reach the server. Try again.";
        }
        status = "error";
      }
    </script>
    
    {#if status === "sent"}
      <p>Thanks, we got it.</p>
    {:else}
      <form action={endpoint} method="POST" {onsubmit}>
        <label>
          Email
          <input name="email" type="email" autocomplete="email" required aria-invalid={errors.email ? "true" : undefined} />
        </label>
        {#if errors.email}<p>{errors.email[0]}</p>{/if}
        <label>
          Message
          <textarea name="message" rows="5"></textarea>
        </label>
        <input type="hidden" name="_redirect" value={`${PUBLIC_SITE_URL}/contact/thanks`} />
        <input name="_gotcha" type="text" tabindex="-1" autocomplete="off" hidden />
        {#if status === "error" && !errors.email}<p role="alert">{message}</p>{/if}
        <button disabled={status === "sending"}>{status === "sending" ? "Sending" : "Send"}</button>
      </form>
    {/if}

    Ajoutez un src/routes/contact/thanks/+page.svelte comme cible de redirection.

Si vous utilisez la CSP de SvelteKit

Avec kit.csp configuré, autorisez Ikiform à la fois pour l'envoi fetch et pour l'envoi de formulaire classique. Sinon, le navigateur bloque l'un ou l'autre.

svelte.config.js
const config = {
  kit: {
    csp: {
      directives: {
        "connect-src": ["self", "https://ikiform.com"],
        "form-action": ["self", "https://ikiform.com"],
      },
    },
  },
};

export default config;

Domaines autorisés

Listez la production ainsi que vos hôtes de prévisualisation.

Où tourne le formulaireÀ ajouter aux domaines autorisés
vite devlocalhost. Correspond à http://localhost:5173 : Ikiform compare uniquement le nom d'hôte, jamais le port.
Votre domaineexample.com, qui couvre aussi www.example.com
Vercelyour-project.vercel.app. Les URL de prévisualisation comme your-project-git-branch-team.vercel.app ne correspondent pas ; ajoutez l'hôte de prévisualisation exact le temps de le tester.
Cloudflare Pagesyour-project.pages.dev. Les URL de prévisualisation comme abc123.your-project.pages.dev en sont des sous-domaines, donc elles correspondent déjà.
Netlifyyour-site.netlify.app. Les deploy previews (deploy-preview-12--your-site.netlify.app) et les branch deploys (branch--your-site.netlify.app) n'en sont pas des sous-domaines : ajoutez l'hôte de prévisualisation exact le temps de le tester.
  • N'ajoutez jamais vercel.app, pages.dev ou netlify.app seul. Tous les sites de cet hébergeur correspondraient, y compris ceux des autres.

Checklist de test

  1. Lancez le serveur de développement avec localhost dans les domaines autorisés et envoyez. Le message de remerciement doit remplacer le formulaire.
  2. Lancez vite build et vérifiez que le résultat contient contact.html avec le formulaire déjà présent.
  3. Désactivez JavaScript, rechargez et envoyez. Sur votre domaine https:, vous devez arriver sur /contact/thanks.
  4. Envoyez depuis un déploiement de prévisualisation et vérifiez que l'envoi n'est pas marqué comme spam.

Dépannage

Ce que vous voyezPourquoiSolution
Le build échoue en indiquant que PUBLIC_IKIFORM_FORM_ID n'est pas exporté par $env/static/publicLa variable n'est pas définie là où le build s'exécuteAjoutez-la à .env en local et aux réglages de build de votre hébergeur.
Rien ne se passe à l'envoi, et la console affiche une erreur CORS à propos de l'en-tête x-sveltekit-actionuse:enhance sur un formulaire qui envoie hors de votre appRetirez-le et gardez le handler onsubmit.
Le navigateur refuse d'envoyer le formulaire à cause de form-action ou connect-srckit.csp ne liste pas IkiformAjoutez https://ikiform.com aux deux directives.
Sans JavaScript, vous arrivez sur la page de remerciement d'IkiformPUBLIC_SITE_URL est en http:, ou le domaine ne fait pas partie des domaines autorisésUtilisez votre adresse https: et ajoutez le domaine.
Les soumissions arrivent dans le filtre spam avec origin_mismatchLa page qui a envoyé ne fait pas partie des domaines autorisés du formulaireAjoutez l'hôte du tableau ci-dessus. Avec Reject, les mêmes envois reçoivent plutôt 403 origin_not_allowed.