# La bibliothèque Formspree React

> Formspree Docs · Utiliser React · 8 janvier 2026

## Installation

Cette bibliothèque suppose que React est déjà installé dans votre environnement en tant que dépendance pair. Nos utilitaires reposent sur les [**React Hooks**](https://reactjs.org/docs/hooks-intro.html), vous devez donc être sur la **version 16.8.0 ou supérieure**.

```bash
npm install @formspree/react
```

[**Code source sur GitHub**](https://github.com/formspree/formspree-react) | **[Package npm](https://www.npmjs.com/package/@formspree/react)**  
  
Vous pouvez utiliser cette bibliothèque avec ou sans la CLI Formspree. Cet article suppose que vous créez des formulaires depuis le tableau de bord. Pour obtenir de l'aide sur les projets CLI, consultez notre article sur l'utilisation de la [CLI Formspree](/articles/using-the-cli/the-formspree-cli/).

## Utilisation

Le hook [**React**](https://reactjs.org/docs/hooks-intro.html) `useForm` est le moyen le plus simple de configurer un formulaire React avec Formspree. Il suffit d'importer `@formspree/react` puis d'appeler `useForm` avec le [hashid](/articles/the-forms-api/getting-your-form-s-hashid/) du formulaire, obtenu en créant un formulaire dans le tableau de bord Formspree.

```jsx
import { useForm } from '@formspree/react';

function MyForm() {
  const [state, handleSubmit, reset] = useForm('{your-form-id}');
  if (state.succeeded) {
    return <div>Thank you for signing up!</div>;
  }
  return (
    <form onSubmit={handleSubmit}>
      <label htmlFor="email">Email</label>
      <input id="email" type="email" name="email" />
      <button type="submit" disabled={state.submitting}>Sign up</button>
    </form>
  )
}
```

## Objet d'état

La première valeur du tableau retourné par ce hook est un objet d'état :

```jsx
const [state, handleSubmit, reset] = useForm('{your-form-id}');
```

L'objet d'état contient les propriétés suivantes :

| Clé | Description |
| --- | --- |
| `submitting` | Un booléen indiquant si le formulaire est en cours de soumission (par défaut `false`) |
| `succeeded` | Un booléen indiquant si le formulaire a été soumis avec succès (par défaut `false`) |
| `errors` | Une instance de la classe `SubmissionError` contenant les erreurs de validation côté serveur (par défaut `null`) |
| `result` | Un objet avec une propriété `next` qui est l'URL de redirection lorsque la soumission réussit (par défaut `null`) |

L'état évolue dans le temps de la façon suivante :

-   Lorsque `handleSubmit` est appelé, `submitting` devient `true`
-   Si la soumission échoue aux validations côté serveur, une nouvelle instance de `errors` est créée avec les erreurs spécifiques
-   Si la soumission réussit, `succeeded` devient `true` et `result` n'est plus `null`
-   Une fois la requête de soumission terminée, `submitting` redevient toujours `false`

L'objet `errors` dispose des méthodes suivantes :

| Clé | Description |
| --- | --- |
| `getFormErrors()` | Retourne un tableau d'erreurs au niveau du formulaire |
| `getFieldErrors(field)` | Retourne un tableau d'erreurs pour le champ `field` |
| `getAllFieldErrors()` | Retourne un tableau de paires clé-valeur des erreurs de chaque champ (`[field, errors][]`) |

Les éléments d'erreur dans l'objet `errors` possèdent les propriétés suivantes :

| Clé | Description |
| --- | --- |
| `message` | Un fragment de message d'erreur lisible par l'humain (ex. : "is required") |
| `code` | Un code d'erreur adapté aux machines (voir les [codes d'erreur](#errorcodes) ci-dessous) |
| `details` | Un objet contenant diverses propriétés supplémentaires sur l'erreur. Par exemple, lors de l'utilisation avec Stripe, il contiendra un champ `stripeCode` avec l'erreur exacte retournée par Stripe |

## Réinitialisation

La troisième valeur du tableau retourné par le hook est une fonction de réinitialisation.

```jsx
const [state, handleSubmit, reset] = useForm('{your-form-id}');
```

Cette fonction permet de réinitialiser l'objet d'état après qu'une requête de soumission de formulaire a été complétée. Elle efface les propriétés `result` et `errors`, et remet les propriétés booléennes `submitting` et `succeeded` à leur état par défaut (c'est-à-dire `false`). Vous pouvez utiliser cette méthode sur la page de remerciement affichée après la soumission pour permettre à l'utilisateur de réinitialiser le formulaire et de le soumettre à nouveau.

Voici un exemple montrant comment utiliser la fonction `reset()` dans un formulaire :

```jsx
function TestForm() {
    const [state, submit, reset] = useForm('{your-form-id}');

    if (state.submitting) {
        return <p>Submitting…</p>;
    }

    if (state.succeeded) {
        return (
            <div>
                <p>Thanks!</p>;<button onClick={reset}>Reset</button>
            </div>
        );
    }

    return (
        <div>
            <h1>Form</h1>
            <form onSubmit={submit}>
                <label htmlFor="email">Email</label>
                <input
                    id="email"
                    type="email"
                    name="email"
                    defaultValue="test@example.com"
                />

                <button type="submit">Sign up</button>

            </form>
        </div>
    );
}
```

## Erreurs de validation

Voici un exemple de formulaire utilisant le composant `ValidationError` pour afficher les erreurs de champ :

```jsx
import { ValidationError, useForm } from '@formspree/react';

function MyForm() {
  const [state, handleSubmit] = useForm('{your-form-id}');
  if (state.succeeded) {
    return <div>Thank you for signing up!</div>;
  }
  return (
    <form onSubmit={handleSubmit}>
      <label htmlFor="email">Email</label>
      <input id="email" type="email" name="email" required />
      <ValidationError field="email" prefix="Email" errors={state.errors} />
      <button type="submit" disabled={state.submitting}>Sign up</button>
    </form>
  )
}
```

Le composant `ValidationError` accepte les propriétés spéciales suivantes :

-   `field` — le nom du champ pour lequel afficher les erreurs. Si aucun attribut `field` n'est fourni, les erreurs générales (non liées à un champ) seront affichées. (Voir les [codes d'erreur](#errorcodes) ci-dessous)
-   `errors` — l'objet contenant les erreurs de validation (requis)
-   `prefix` — le nom convivial du champ (optionnel, par défaut "This field")

Toutes les autres propriétés (comme `className`) sont transmises au wrapper `<div>`. Si le champ est invalide, ce composant affiche un `<div>` contenant le message d'erreur :

```jsx
<div {...props}>
  {prefix} {message}
</div>
```

## Options supplémentaires

Ce hook accepte deux arguments : la clé du formulaire et un objet contenant des options.

```jsx
const [state, handleSubmit, reset] = useForm('{your-form-key}', options);
```

Les options acceptées sont les suivantes :

| Clé | Type | Description |
| --- | --- | --- |
| `data` | object | Un objet contenant des chaînes ou des fonctions à fusionner avec les données de votre formulaire |
| `client` | Formspree | Une instance du client Formspree |

**Exemple d'utilisation**

```jsx
const [state, handleSubmit, reset] = useForm('{your-form-id}', {
  data: {
    subject: 'Someone joined the newsletter',
    pageTitle: function() {
      // This function will be evaluated at submission time
      return document.title;
    }
  }
});
```

## Utilisation avec Stripe

La bibliothèque Formspree React inclut la prise en charge des paiements via Stripe. Elle gère la majeure partie de la gestion d'état côté front-end nécessaire pour créer des paiements et effectuer l'[authentification forte du client (SCA)](https://stripe.com/docs/strong-customer-authentication). Le backend Formspree se charge ensuite de soumettre les paiements à Stripe. Ensemble, ils réduisent considérablement l'effort de développement nécessaire pour créer un formulaire de paiement.

La fonctionnalité Stripe est chargée à la demande. Cela signifie que seul un wrapper Stripe minimal (seulement 6 ko compressé) est inclus dans le bundle de `@formspree/react`. Le reste de la bibliothèque Stripe n'est chargé que si et quand les éléments Stripe sont rendus pour la première fois.

Pour utiliser Stripe, enveloppez d'abord votre application avec le composant `FormspreeProvider` en incluant la prop `stripePK` avec votre clé publique Stripe.

```jsx
import { FormspreeProvider } from '@formspree/react';

function MyApp() {
  return (
    <FormspreeProvider
      stripePK={'{your-stripe-publishable-key}'}
    >
      <PaymentForm />
    </FormspreeProvider>
  )
}
```

Ensuite, lors de la construction de votre formulaire, utilisez le composant `CardElement` exporté par `@formspree/react`.

```jsx
import { useForm, CardElement, ValidationError } from '@formspree/react';

function PaymentForm() {
  const [state, handleSubmit] = useForm('{your-form-id}');

  if (state.succeeded) {
    return <div>Payment has been handled successfully!</div>;
  }

  return (
    <form onSubmit={handleSubmit}>
      <div>
        <label htmlFor="email">Email</label>
        <input id="email" type="email" name="email" />
      </div>
      <div>
        <label>Card details</label>
        <CardElement />
        <ValidationError
          field="paymentMethod"
          errors={state.errors}
        />
      </div>
      <button type="submit" disabled={state.submitting}>
        {state.submitting ? 'Handling payment...' : 'Pay'}
      </button>
    </form>
  )
}
```

Le composant `CardElement` est transmis directement depuis `@stripe/react-stripe-js`. Il est exporté par Formspree React uniquement pour garantir la cohérence des versions. La documentation du composant `CardElement` est disponible [ici](https://stripe.com/docs/payments/accept-card-payments?platform=web&ui=elements&html-or-react=react#add-and-configure-a-component).

Notez le nom de champ "paymentMethod" sur `ValidationError`. C'est le nom de champ utilisé pour transmettre les données de Stripe à Formspree, et il doit être passé à `ValidationError` pour intercepter les erreurs Stripe pertinentes.

## Utilisation avec une bibliothèque de formulaires externe

Le hook [**React**](https://reactjs.org/docs/hooks-intro.html) `useSubmit` est un moyen simple d'intégrer une autre bibliothèque de formulaires avec Formspree. Il suffit d'importer `@formspree/react` puis d'appeler `useSubmit` avec le [hashid](/articles/the-forms-api/getting-your-form-s-hashid/) du formulaire, obtenu en créant un formulaire dans le tableau de bord Formspree.

```tsx
import { useSubmit } from '@formspree/react';
import { useForm } from 'react-hook-form';

type Inputs = {
  email: string;
  message: string;
  name: string;
};

export function WithReactHookForm() {
  const {
    formState: { errors, isSubmitSuccessful, isSubmitting },
    handleSubmit,
    register,
    setError,
  } = useForm<Inputs>();

  const submit = useSubmit<Inputs>(
    process.env.REACT_APP_REACT_HOOK_FORM_ID as string,
    {
      onError(errs) {
        const formErrs = errs.getFormErrors();
        for (const { code, message } of formErrs) {
          setError(`root.${code}`, {
            type: code,
            message,
          });
        }

        const fieldErrs = errs.getAllFieldErrors();
        for (const [field, errs] of fieldErrs) {
          setError(field, {
            message: errs.map((e) => e.message).join(', '),
          });
        }
      },
    }
  );

  return (
    <div>
      {isSubmitSuccessful ? (
        <h2>Your message has been sent successfully!</h2>
      ) : (
        <form onSubmit={handleSubmit(submit)}>
          <div className="block">
            <label htmlFor="email">Email</label>
            <input {...register('email')} id="email" type="email" />
            {errors.email && <p className="error">{errors.email.message}</p>}
          </div>
          <div className="block">
            <label htmlFor="name">Name</label>
            <input {...register('name')} id="name" />
            {errors.name && <p className="error">{errors.name.message}</p>}
          </div>
          <div className="block">
            <label htmlFor="message">Message</label>
            <textarea {...register('message')} id="message" rows={10} />
          </div>
          {errors.root && (
            <div className="block">
              <ul className="error">
                {Object.values(errors.root).map((err) => {
                  if (typeof err !== 'object') {
                    return <li key={err}>{err}</li>;
                  }
                  const { type, message } = err;
                  return <li key={type}>{message}</li>;
                })}
              </ul>
            </div>
          )}
          <button type="submit" disabled={isSubmitting}>
            {isSubmitting ? 'Submitting...' : 'Submit'}
          </button>
        </form>
      )}
    </div>
  );
}
```

## Codes d'erreur

Les codes d'erreur suivants peuvent apparaître dans le tableau d'erreurs de l'objet d'état :

| Code | Erreur de champ | Description |
| --- | --- | --- |
| `INACTIVE` |   | Le formulaire a été désactivé |
| `BLOCKED` |   | Le formulaire a été bloqué |
| `EMPTY` |   | Aucune donnée n'a été soumise |
| `PROJECT_NOT_FOUND` |   | Une clé de projet invalide a été utilisée pour soumettre le formulaire |
| `FORM_NOT_FOUND` |   | Un hashid de formulaire invalide a été utilisé pour soumettre le formulaire |
| `NO_FILE_UPLOADS` |   | Les téléversements de fichiers ne sont pas pris en charge pour ce formulaire |
| `TOO_MANY_FILES` |   | Le formulaire a été soumis avec trop de fichiers joints |
| `FILES_TOO_BIG` |   | Un ou plusieurs fichiers téléversés dépassent la taille maximale autorisée |
| `REQUIRED_FIELD_MISSING` | ✓ | Un champ est obligatoire mais aucune valeur n'a été fournie |
| `REQUIRED_FIELD_EMPTY` | ✓ | Un champ est obligatoire mais une chaîne vide ou nulle a été fournie |
| `TYPE_EMAIL` | ✓ | Un champ doit contenir une adresse e-mail |
| `TYPE_NUMERIC` | ✓ | Un champ doit contenir un nombre |
| `TYPE_TEXT` | ✓ | Un champ doit contenir du texte |
| `STRIPE_CLIENT_ERROR` | ✓ | Clé Stripe manquante |
| `STRIPE_SCA_ERROR` | ✓ | Erreur SCA Stripe. Voir `details` |
