# Gatsby

> Un formulaire Gatsby qui fonctionne déjà dans le HTML statique avant l'hydratation, amélioré ensuite avec fetch, plus une Gatsby Function pour les envois avec une clé secrète.

Gatsby génère chaque page en HTML au moment du build. Donnez au formulaire une vraie `action` et il envoie avant l'hydratation de React, ou si le bundle ne se charge pas ; une fois hydraté, le composant envoie avec `fetch` et affiche le résultat sur place.

## Envoyer depuis le navigateur

### Étape 1 : Ajoutez l'id du formulaire

`.env.production`:

```bash
GATSBY_IKIFORM_FORM_ID=frm_xxxxxxxxxxxxxxxx
```

Gatsby n'expose au code navigateur que les variables qui commencent par `GATSBY_`, et les intègre au moment du build. Ajoutez la même ligne à `.env.development` pour `gatsby develop`.

### Étape 2 : Ajoutez le composant

`src/components/contact-form.js`:

```jsx
import * as React from "react";

const endpoint = `https://ikiform.com/f/${process.env.GATSBY_IKIFORM_FORM_ID}`;

export default function ContactForm() {
  const [status, setStatus] = React.useState("idle");
  const [message, setMessage] = React.useState("");

  async function onSubmit(event) {
    event.preventDefault();
    setStatus("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) return setStatus("sent");
      setMessage(result.error.message);
    } catch {
      setMessage("Couldn't reach the server. Try again.");
    }
    setStatus("error");
  }

  if (status === "sent") return <p>Thanks, we got it.</p>;

  return (
    <form action={endpoint} method="post" onSubmit={onSubmit}>
      <label>
        Email
        <input name="email" type="email" autoComplete="email" required />
      </label>
      <label>
        Message
        <textarea name="message" rows={5} />
      </label>
      <input type="hidden" name="_redirect" value="https://example.com/thanks/" />
      <input name="_gotcha" type="text" tabIndex={-1} autoComplete="off" hidden />
      {status === "error" ? <p role="alert">{message}</p> : null}
      <button disabled={status === "sending"}>Send</button>
    </form>
  );
}
```

Affichez-le depuis n'importe quelle page, par exemple `src/pages/contact.js`, et ajoutez `src/pages/thanks.js` pour la redirection sans JavaScript. Pour les erreurs de champ et la vérification humaine du SDK, complétez-le comme dans le [guide React](https://ikiform.com/fr/docs/guides/react.md#component).

## Envoyer depuis une Gatsby Function

Une Gatsby Function peut transmettre l'envoi avec une clé secrète, ce qui contourne les domaines autorisés et la vérification humaine. Elle ne tourne que chez les hébergeurs compatibles avec les Gatsby Functions, comme Netlify avec l'adaptateur Gatsby ; un hébergeur purement statique comme GitHub Pages ne peut pas l'exécuter. Stockez `IKIFORM_FORM_ID` et une clé secrète avec la portée `submissions:write` dans `IKIFORM_SECRET_KEY`, sans le préfixe `GATSBY_`, pour qu'elles n'atteignent jamais le navigateur.

`src/api/contact.js`:

```js
export default async function handler(req, res) {
  if (req.method !== "POST") return res.status(405).end();
  const response = await fetch(`https://ikiform.com/f/${process.env.IKIFORM_FORM_ID}`, {
    method: "POST",
    headers: {
      "Content-Type": "application/json",
      Accept: "application/json",
      Authorization: `Bearer ${process.env.IKIFORM_SECRET_KEY}`,
    },
    body: JSON.stringify(req.body),
  });
  res.status(response.status).json(await response.json());
}
```

Gatsby analyse les corps JSON et form-encoded dans `req.body`, donc la page peut envoyer vers `/api/contact` dans les deux formats. Tous les envois partagent alors l'adresse IP de votre fonction pour les limites de débit ; voir [Depuis un serveur](https://ikiform.com/fr/docs/guides/server.md).

## Domaines autorisés

Cela s'applique aux envois depuis le navigateur. Les envois depuis la Gatsby Function utilisent une clé secrète et contournent ce contrôle.

| Où tourne le formulaire | À ajouter aux domaines autorisés |
| --- | --- |
| `gatsby develop` et `gatsby serve` | `localhost`. Correspond à `http://localhost:8000` et `http://localhost:9000` : Ikiform compare uniquement le nom d'hôte, jamais le port. |
| Votre domaine | `example.com`, qui couvre aussi `www.example.com` |
| Netlify | `your-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. |
| Cloudflare Pages | `your-project.pages.dev`. Les URL de prévisualisation comme `abc123.your-project.pages.dev` en sont des sous-domaines, donc elles correspondent déjà. |

- N'ajoutez jamais `netlify.app` ou `pages.dev` seul. Tous les sites de cet hébergeur correspondraient, y compris ceux des autres.

## Checklist de test

1. Lancez `gatsby build` et ouvrez `public/contact/index.html`. L'`action` du formulaire doit se terminer par l'id de votre formulaire, pas par `undefined`.
2. Lancez `gatsby serve` avec `localhost` dans les domaines autorisés et envoyez. Le message de remerciement doit remplacer le formulaire.
3. Désactivez JavaScript, rechargez et envoyez. Vous devez voir la page de remerciement d'Ikiform en local, ou `/thanks/` sur votre domaine `https:`.
4. Si vous utilisez la fonction, envoyez vers `/api/contact` sur un déploiement de prévisualisation et vérifiez que la soumission apparaît dans Ikiform.

## Dépannage

| Ce que vous voyez | Pourquoi | Solution |
| --- | --- | --- |
| `404 not_found`, et l'action se termine par `/f/undefined` | La variable n'est pas préfixée par `GATSBY_`, ou n'était pas définie au moment du build | Nommez-la `GATSBY_IKIFORM_FORM_ID` et relancez le build. |
| La fonction répond `403 forbidden` | La clé secrète provient d'un autre espace de travail, est révoquée ou n'a pas `submissions:write` | Créez une clé secrète avec cette portée. |
| `/api/contact` renvoie `404` après le déploiement | L'hébergeur ne sert que des fichiers statiques | Déployez chez un hébergeur compatible avec les Gatsby Functions, ou utilisez la version navigateur. |
| Les soumissions arrivent dans le filtre spam avec `origin_mismatch` | La page qui a envoyé ne fait pas partie des domaines autorisés du formulaire | Ajoutez l'hôte du tableau ci-dessus. Avec **Reject**, les mêmes envois reçoivent plutôt `403 origin_not_allowed`. |

## Voir aussi

- [React](https://ikiform.com/fr/docs/guides/react.md): États d'attente, d'erreur et de succès.
- [Depuis un serveur](https://ikiform.com/fr/docs/guides/server.md): Envoyez avec une clé API secrète.
- [Domaines autorisés](https://ikiform.com/fr/docs/spam.md#allowed-domains): Comment les origines sont comparées, et ce qui se passe en cas de non-correspondance.
- [Erreurs](https://ikiform.com/fr/docs/errors.md): Chaque code d'erreur, avec sa cause et sa solution.
