From 4829216aa79a030fd43c5912e71a15e74b1ca8bc Mon Sep 17 00:00:00 2001
From: Armand Philippot
Date: Tue, 3 Dec 2024 16:56:07 +0100
Subject: [PATCH 1/3] i18n(fr): update `guides/actions.mdx` &
`modules/astro-actions.mdx`
See #9240
---
src/content/docs/fr/guides/actions.mdx | 192 ++++++++++++++----
.../fr/reference/modules/astro-actions.mdx | 121 ++++++++++-
2 files changed, 267 insertions(+), 46 deletions(-)
diff --git a/src/content/docs/fr/guides/actions.mdx b/src/content/docs/fr/guides/actions.mdx
index 731476fc3bb08..48431dbda94ff 100644
--- a/src/content/docs/fr/guides/actions.mdx
+++ b/src/content/docs/fr/guides/actions.mdx
@@ -398,7 +398,7 @@ if (isInputError(error)) {
## Appeler des actions depuis une action de formulaire HTML
:::note
-Les pages doivent être rendues à la demande lors de l'appel d'actions à l'aide d'une action de formulaire. [Assurez-vous que le prérendu est désactivé sur la page](/fr/guides/on-demand-rendering/) avant d'utiliser cette API.
+Les pages doivent être rendues à la demande lors de l'appel d'actions à l'aide d'une action de formulaire. [Assurez-vous que le prérendu est désactivé sur la page](/fr/guides/on-demand-rendering/#enabling-on-demand-rendering) avant d'utiliser cette API.
:::
Vous pouvez activer les soumissions de formulaires zéro-JS avec des attributs standard sur n'importe quel élément `
-```
-
-#### Redirection dynamique en cas de réussite de l'action
-
-Si vous devez décider vers où rediriger de manière dynamique, vous pouvez utiliser le résultat d'une action sur le serveur. Un exemple courant est la création d'un enregistrement de produit et la redirection vers la page du nouveau produit, par exemple `/products/[id]`.
+Si vous devez rediriger vers une nouvelle route en cas de succès, vous pouvez utiliser le résultat d'une action sur le serveur. Un exemple courant est la création d'un enregistrement de produit et la redirection vers la page du nouveau produit, par exemple `/products/[id]`.
Par exemple, supposons que vous ayez une action `createProduct` qui renvoie l'identifiant du produit généré :
@@ -479,7 +462,7 @@ if (result && !result.error) {
### Gérer les erreurs d'action du formulaire
-Astro ne redirige pas vers votre route `action` lorsqu'une action échoue. Au lieu de cela, la page actuelle est rechargée avec toutes les erreurs renvoyées par l'action. L'appel de `Astro.getActionResult()` dans le composant Astro contenant votre formulaire vous donne accès à l'objet `error` pour une gestion personnalisée des erreurs.
+L'appel de `Astro.getActionResult()` dans le composant Astro contenant votre formulaire vous donne accès aux objets `data` et `error` pour la gestion personnalisée des erreurs.
L'exemple suivant affiche un message d'échec général lorsqu'une action `newsletter` échoue :
@@ -493,7 +476,7 @@ const result = Astro.getActionResult(actions.newsletter);
{result?.error && (
Impossible de s'inscrire. Veuillez réessayer ultérieurement.
)}
-
```
-:::note
-Astro conserve les données (`data`) et erreurs (`error`) de l'action avec un cookie à usage unique. Cela signifie que `getActionResult()` renverra un résultat sur la première requête _uniquement_, et `undefined` lors de la nouvelle consultation de la page.
-:::
-
#### Conserver les valeurs d'entrée en cas d'erreur
Les entrées seront effacées à chaque fois qu'un formulaire sera soumis. Pour conserver les valeurs d'entrée, vous pouvez [activer les transitions de vue](/fr/guides/view-transitions/#ajouter-des-transitions-de-vue-à-une-page) sur la page et appliquer la directive `transition:persist` à chaque entrée :
@@ -538,13 +517,9 @@ Les entrées seront effacées à chaque fois qu'un formulaire sera soumis. Pour
### Mettre à jour l'interface utilisateur avec un résultat d'action de formulaire
-Le résultat renvoyé par `Astro.getActionResult()` est à usage unique et sera réinitialisé à `undefined` à chaque actualisation de la page. Ceci est idéal pour [afficher les erreurs de saisie](#gérer-les-erreurs-daction-du-formulaire) et afficher des notifications temporaires à l'utilisateur en cas de réussite.
+Pour utiliser la valeur de retour d'une action pour afficher une notification à l'utilisateur en cas de réussite, transmettez l'action à `Astro.getActionResult()`. Utilisez la propriété `data` renvoyée pour restituer l'interface utilisateur que vous souhaitez afficher.
-:::tip
-Si vous avez besoin d'afficher un résultat lors des actualisations de page, envisagez de stocker le résultat dans une base de données ou [dans un cookie](/fr/reference/api-reference/#astrocookies).
-:::
-
-Transmettez une action à `Astro.getActionResult()` et utilisez la propriété `data` renvoyée pour restituer n'importe quelle interface utilisateur temporaire que vous souhaitez afficher. Cet exemple utilise la propriété `productName` renvoyée par une action `addToCart` pour afficher un message de réussite :
+Cet exemple utilise la propriété `productName` renvoyée par une action `addToCart` pour afficher un message de réussite.
```astro title="src/pages/products/[slug].astro"
---
@@ -560,31 +535,160 @@ const result = Astro.getActionResult(actions.addToCart);
```
-:::caution
-Les données d'action sont transmises à l'aide d'un cookie persistant. **Ce cookie n'est pas chiffré** et sa taille est limitée à 4 Ko, bien que la limite exacte puisse varier d'un navigateur à l'autre.
+### Avancé : Persistance des résultats d'action avec une session
-En général, nous recommandons de renvoyer le minimum d'informations nécessaires à votre gestionnaire d'actions (`handler`) pour éviter les vulnérabilités, et de conserver les autres informations sensibles dans une base de données.
+
-Par exemple, vous pouvez renvoyer le nom d'un produit dans une action `addToCart`, plutôt que de renvoyer l'intégralité de l'objet `product` :
+Les résultats de l'action sont affichés sous forme de soumission POST. Cela signifie que le résultat sera réinitialisé sur `undefined` lorsqu'un utilisateur fermera et revisitera la page. L'utilisateur verra également une boîte de dialogue « Confirmer la nouvelle soumission du formulaire ?» s'il tente d'actualiser la page.
-```ts title="src/actions/index.ts" del={7} ins={8}
-import { defineAction } from 'astro:actions';
+Pour personnaliser ce comportement, vous pouvez ajouter un middleware pour gérer manuellement le résultat de l'action. Vous pouvez choisir de conserver le résultat de l'action à l'aide d'un cookie ou d'un stockage de session.
+
+Commencez par [créer un fichier middleware](/fr/guides/middleware/) et par importer [l'utilitaire `getActionContext()`](/fr/reference/modules/astro-actions/#getactioncontext) depuis `astro:actions`. Cette fonction renvoie un objet `action` avec des informations sur la demande d'action entrante, y compris le gestionnaire d'action et si l'action a été appelée à partir d'un formulaire HTML. `getActionContext()` renvoie également les fonctions `setActionResult()` et `serializeActionResult()` pour définir par programmation la valeur renvoyée par `Astro.getActionResult()` :
+
+```ts title="src/middleware.ts" {2,5}
+import { defineMiddleware } from 'astro:middleware';
+import { getActionContext } from 'astro:actions';
+
+export const onRequest = defineMiddleware(async (context, next) => {
+ const { action, setActionResult, serializeActionResult } = getActionContext(context);
+ if (action?.calledFrom === 'form') {
+ const result = await action.handler();
+ // ... gérer le résultat de l'action
+ setActionResult(action.name, serializeActionResult(result));
+ }
+ return next();
+});
+```
+
+Une pratique courante pour conserver les résultats des formulaires HTML est le [modèle POST / Redirect / GET](https://fr.wikipedia.org/wiki/Post-redirect-get). Cette redirection supprime la boîte de dialogue « Confirmer la nouvelle soumission du formulaire ?» lorsque la page est actualisée et permet aux résultats de l'action d'être conservés tout au long de la session de l'utilisateur.
+
+Cet exemple applique le modèle POST / Redirect / GET à toutes les soumissions de formulaire utilisant le stockage de session avec [l'adaptateur de serveur Netlify](/fr/guides/integrations-guide/netlify/) installé. Les résultats de l'action sont écrits dans un magasin de sessions à l'aide de [Netlify Blob](https://docs.netlify.com/blobs/overview/) et récupérés après une redirection à l'aide d'un ID de session :
+
+```ts title="src/middleware.ts"
+import { defineMiddleware } from 'astro:middleware';
+import { getActionContext } from 'astro:actions';
+import { randomUUID } from "node:crypto";
+import { getStore } from "@netlify/blobs";
+
+export const onRequest = defineMiddleware(async (context, next) => {
+ // Ignorer les demandes de pages pré-rendues
+ if (context.isPrerendered) return next();
+
+ const { action, setActionResult, serializeActionResult } =
+ getActionContext(context);
+ // Créer un magasin Blob pour conserver les résultats des actions avec Netlify Blob
+ const actionStore = getStore("action-session");
+
+ // Si un résultat d'action a été transmis sous forme de cookie, définir le
+ // résultat pour qu'il soit accessible à partir de `Astro.getActionResult()`
+ const sessionId = context.cookies.get("action-session-id")?.value;
+ const session = sessionId
+ ? await actionStore.get(sessionId, {
+ type: "json",
+ })
+ : undefined;
+
+ if (session) {
+ setActionResult(session.actionName, session.actionResult);
+
+ // Facultatif : supprimer la session une fois la page rendue.
+ // N'hésitez pas à mettre en œuvre votre propre stratégie de persistance
+ await actionStore.delete(sessionId);
+ ctx.cookies.delete("action-session-id");
+ return next();
+ }
+
+ // Si une action a été appelée à partir d'une action de formulaire HTML,
+ // appeler le gestionnaire d'action et rediriger vers la page de destination
+ if (action?.calledFrom === "form") {
+ const actionResult = await action.handler();
+
+ // Conserver le résultat de l'action à l'aide du stockage de session
+ const sessionId = randomUUID();
+ await actionStore.setJSON(sessionId, {
+ actionName: action.name,
+ actionResult: serializeActionResult(actionResult),
+ });
+
+ // Transmettre l'ID de session sous forme de cookie
+ // à récupérer après la redirection vers la page
+ context.cookies.set("action-session-id", sessionId);
+
+ // Rediriger vers la page précédente en cas d'erreur
+ if (actionResult.error) {
+ const referer = context.request.headers.get("Referer");
+ if (!referer) {
+ throw new Error(
+ "Internal: Referer unexpectedly missing from Action POST request.",
+ );
+ }
+ return context.redirect(referer);
+ }
+ // Rediriger vers la page de destination en cas de succès
+ return context.redirect(context.originPathname);
+ }
+
+ return next();
+});
+```
+
+## Sécurité lors de l'utilisation des actions
+
+Les actions sont accessibles en tant que points de terminaison publics en fonction du nom de l'action. Par exemple, l'action `blog.like()` sera accessible depuis `/_actions/blog.like`. Cela est utile pour tester les résultats des actions et déboguer les erreurs de production. Cependant, cela signifie que vous **devez** utiliser les mêmes contrôles d'autorisation que ceux que vous envisageriez pour les points de terminaison d'API et les pages rendues à la demande.
+
+### Autoriser les utilisateurs à partir d'un gestionnaire d'actions
+
+Pour autoriser les demandes d'action, ajoutez une vérification d'authentification à votre gestionnaire d'actions. Vous souhaiterez peut-être utiliser [une bibliothèque d'authentification](/fr/guides/authentication/) pour gérer la gestion des sessions et les informations utilisateur.
+
+Les actions exposent l'objet `APIContext` complet pour accéder aux propriétés transmises par le middleware à l'aide de `context.locals`. Lorsqu'un utilisateur n'est pas autorisé, vous pouvez générer une `ActionError` avec le code `UNAUTHORIZED` :
+
+```ts title="src/actions/index.ts" {6-8}
+import { defineAction, ActionError } from 'astro:actions';
export const server = {
- addToCart: defineAction({
- handler: async () => {
- /* ... */
- return product;
- return { productName: product.name };
+ getUserSettings: defineAction({
+ handler: async (_input, context) => {
+ if (!context.locals.user) {
+ throw new ActionError({ code: 'UNAUTHORIZED' });
+ }
+ return { /* les données en cas de réussite */ };
}
})
}
```
-:::
+
+### Limiter les actions depuis le middleware
+
+
+
+Astro recommande d'autoriser les sessions utilisateur à partir de votre gestionnaire d'actions pour respecter les niveaux d'autorisation et la limitation de débit par action. Cependant, vous pouvez également limiter les demandes à toutes les actions (ou à un sous-ensemble d'actions) à partir du middleware.
+
+Utilisez la fonction `getActionContext()` de votre middleware pour récupérer des informations sur les demandes d'action entrantes. Cela inclut le nom de l'action et si cette action a été appelée à l'aide d'une fonction d'appel de procédure à distance (RPC) côté client (par exemple, `actions.blog.like()`) ou d'un formulaire HTML.
+
+L'exemple suivant rejette toutes les demandes d'action qui ne disposent pas d'un jeton de session valide. Si la vérification échoue, une réponse « Interdit » est renvoyée. Remarque : cette méthode garantit que les actions ne sont accessibles que lorsqu'une session est présente, mais ne remplace _pas_ une autorisation sécurisée.
+
+```ts title="src/middleware.ts"
+import { defineMiddleware } from 'astro:middleware';
+import { getActionContext } from 'astro:actions';
+
+export const onRequest = defineMiddleware(async (context, next) => {
+ const { action } = getActionContext(context);
+ // Vérifier si l'action a été appelée à partir d'une fonction côté client
+ if (action?.calledFrom === 'rpc') {
+ // Si tel est le cas, rechercher un jeton de session utilisateur
+ if (context.cookies.has('user-session')) {
+ return new Response('Forbidden', { status: 403 });
+ }
+ }
+
+ context.cookies.set('user-session', /* jeton de session */);
+ return next();
+});
+```
## Appeler des actions à partir des composants Astro et des points de terminaison du serveur
-Vous pouvez appeler des actions directement à partir des scripts de composants Astro en utilisant le wrapper `Astro.callAction()` (ou `context.callAction()` lors de l'utilisation d'un [point de terminaison de serveur](/fr/guides/endpoints/#points-de-terminaison-du-serveur-routes-api)). Il est courant de réutiliser la logique de vos actions dans un autre code serveur.
+Vous pouvez appeler des actions directement à partir des scripts de composants Astro en utilisant l'enveloppe `Astro.callAction()` (ou `context.callAction()` lors de l'utilisation d'un [point de terminaison de serveur](/fr/guides/endpoints/#points-de-terminaison-du-serveur-routes-api)). Il est courant de réutiliser la logique de vos actions dans un autre code serveur.
Transmettez l'action comme premier argument et tous les paramètres d'entrée comme deuxième argument. Cela renvoie les mêmes objets `data` et `error` que vous recevez lors de l'appel d'actions sur le client :
diff --git a/src/content/docs/fr/reference/modules/astro-actions.mdx b/src/content/docs/fr/reference/modules/astro-actions.mdx
index 10595f3dd9f88..6aa722ffadf95 100644
--- a/src/content/docs/fr/reference/modules/astro-actions.mdx
+++ b/src/content/docs/fr/reference/modules/astro-actions.mdx
@@ -1,5 +1,7 @@
---
title: Référence de l'API Actions
+sidebar:
+ label: 'astro:actions'
i18nReady: true
tableOfContents:
minHeadingLevel: 2
@@ -59,7 +61,7 @@ export const server = {
`defineAction()` nécessite une fonction `handler()` contenant la logique du serveur à exécuter lorsque l'action est appelée. Les données renvoyées par le gestionnaire sont automatiquement sérialisées et envoyées à l'appelant.
-Le `handler()` est appelé avec la saisie de l'utilisateur comme premier argument. Si un validateur [`input`](#validateur-de-saisie-input) est défini, la saisie de l'utilisateur sera validée avant d'être transmise au gestionnaire. Le deuxième argument est un objet `context` contenant la plupart du [contexte de point de terminaison standard](/fr/reference/api-reference/#contexte-du-point-de-terminaison) d'Astro, à l'exception de `getActionResult()`, `callAction()` et `redirect()`.
+Le `handler()` est appelé avec la saisie de l'utilisateur comme premier argument. Si un validateur [`input`](#validateur-de-saisie-input) est défini, la saisie de l'utilisateur sera validée avant d'être transmise au gestionnaire. Le deuxième argument est un objet `context` contenant la plupart du [contexte de point de terminaison standard](/fr/reference/api-reference/) d'Astro, à l'exception de `getActionResult()`, `callAction()` et `redirect()`.
Les valeurs de retour sont analysées à l'aide de la [bibliothèque devalue](https://github.com/Rich-Harris/devalue). Celle-ci prend en charge les valeurs JSON, ainsi que les instances de `Date()`, `Map()`, `Set()` ou `URL()`.
@@ -70,7 +72,7 @@ Les valeurs de retour sont analysées à l'aide de la [bibliothèque devalue](ht
**Type :** `ZodType | undefined`
-La propriété facultative `input` accepte un validateur Zod pour vérifier les entrées du gestionnaire lors de l'exécution. Si l'action échoue à la validation, [une erreur `BAD_REQUEST`](#actionerror) est renvoyée et la fonction `handler` n'est pas appelée.
+La propriété facultative `input` accepte un validateur Zod (par exemple un objet Zod, une union discriminée Zod) pour vérifier les entrées du gestionnaire lors de l'exécution. Si l'action échoue à la validation, [une erreur `BAD_REQUEST`](#actionerror) est renvoyée et la fonction `handler` n'est pas appelée.
Si `input` est omis, le `handler` recevra une entrée de type `unknown` pour les requêtes JSON et de type `FormData` pour les requêtes de formulaire.
@@ -140,8 +142,10 @@ L'utilitaire `isInputError()` permet de vérifier si une `ActionError` est une e
**Type :** (error?: unknown | ActionError) => boolean
+
La fonction `isActionError()` est utilisée pour vérifier si votre action a déclenché une `ActionError` dans la [propriété du gestionnaire](/fr/reference/modules/astro-actions/#propriété-handler). Ceci est utile pour restreindre le type d'une erreur générique dans un bloc `try / catch`.
+
### `ActionError`
@@ -184,3 +188,116 @@ La propriété `code` accepte les versions lisibles par l'homme de tous les code
La propriété `message` accepte une chaîne de caractères. (par exemple, « L'utilisateur doit être connecté. »)
+
+### `getActionContext()`
+
+
+
+**Type :** `(context: APIContext) => ActionMiddlewareContext`
+
+
+
+`getActionContext()` est une fonction appelée depuis votre gestionnaire middleware pour récupérer des informations sur les demandes d'action entrantes.
+
+Cette fonction renvoie un objet `action` avec des informations sur la requête, ainsi que les fonctions `setActionResult()` et `serializeActionResult()` pour définir par programmation la valeur renvoyée par `Astro.getActionResult()`.
+
+`getActionContext()` vous permet d'obtenir et de définir par programmation les résultats d'actions à l'aide d'un middleware, vous permettant de conserver les résultats d'actions à partir de formulaires HTML, de bloquer les demandes d'actions avec des contrôles de sécurité supplémentaires, et bien plus encore.
+
+```ts title="src/middleware.ts" {5}
+import { defineMiddleware } from 'astro:middleware';
+import { getActionContext } from 'astro:actions';
+
+export const onRequest = defineMiddleware(async (context, next) => {
+ const { action, setActionResult, serializeActionResult } = getActionContext(context);
+ if (action?.calledFrom === 'form') {
+ const result = await action.handler();
+ setActionResult(action.name, serializeActionResult(result));
+ }
+ return next();
+});
+```
+
+#### `action`
+
+
+
+**Type :** `{ calledFrom: 'rpc' | 'form', name: string, handler: () => Promise> } | undefined`
+
+
+`action` est un objet contenant des informations sur une demande d'action entrante.
+
+Il est disponible à partir de `getActionContext()` et fournit le nom de l'action, le gestionnaire et si l'action a été appelée à partir d'une fonction RPC côté client (par exemple `actions.newsletter()`) ou d'une action de formulaire HTML.
+
+```ts title="src/middleware.ts" {6}
+import { defineMiddleware } from 'astro:middleware';
+import { getActionContext } from 'astro:actions';
+
+export const onRequest = defineMiddleware(async (context, next) => {
+ const { action, setActionResult, serializeActionResult } = getActionContext(context);
+ if (action?.calledFrom === 'rpc' && action.name.startsWith('private')) {
+ // Rechercher un jeton de session valide
+ }
+ // ...
+});
+```
+
+#### `setActionResult()`
+
+
+
+**Type :** `(actionName: string, actionResult: SerializedActionResult) => void`
+
+
+`setActionResult()` est une fonction permettant de définir par programmation la valeur renvoyée par `Astro.getActionResult()` dans le middleware. On lui passe le nom de l'action et un résultat d'action sérialisé par [`serializeActionResult()`](#serializeactionresult).
+
+Ceci est utile lors de l'appel d'actions à partir d'un formulaire HTML pour conserver et charger les résultats d'une session.
+
+```ts title="src/middleware.ts" {8}
+import { defineMiddleware } from 'astro:middleware';
+import { getActionContext } from 'astro:actions';
+export const onRequest = defineMiddleware(async (context, next) => {
+ const { action, setActionResult, serializeActionResult } = getActionContext(context);
+ if (action?.calledFrom === 'form') {
+ const result = await action.handler();
+ // ... gérer le résultat de l'action
+ setActionResult(action.name, serializeActionResult(result));
+ }
+ return next();
+});
+```
+
+Consultez le [guide des sessions avancées](/fr/guides/actions/#avancépersistance-des-résultats-daction-avec-une-session) pour un exemple d'implémentation à l'aide de Netlify Blob.
+
+#### `serializeActionResult()`
+
+
+
+**Type :** `(result: SafeResult) => SerializedActionResult`
+
+
+`serializeActionResult()` sérialisera un résultat d'action en JSON pour la persistance. Cela est nécessaire pour gérer correctement les valeurs de retour non JSON telles que `Map` ou `Date` ainsi que l'objet `ActionError`.
+
+Appelez cette fonction lors de la sérialisation d'un résultat d'action à transmettre à `setActionResult()` :
+
+```ts title="src/middleware.ts" {8}
+import { defineMiddleware } from 'astro:middleware';
+import { getActionContext } from 'astro:actions';
+
+export const onRequest = defineMiddleware(async (context, next) => {
+ const { action, setActionResult, serializeActionResult } = getActionContext(context);
+ if (action) {
+ const result = await action.handler();
+ setActionResult(action.name, serializeActionResult(result));
+ }
+ // ...
+});
+```
+
+#### `deserializeActionResult()`
+
+
+
+**Type :** `(result: SerializedActionResult) => SafeResult`
+
+
+`deserializeActionResult()` inversera l'effet de `serializeActionResult()` et renverra le résultat d'une action à son état d'origine. Ceci est utile pour accéder aux objets `data` et `error` sur un résultat d'action sérialisé.
From 3c6be1a6caeb8c72cc41ef9a988967be834b21e8 Mon Sep 17 00:00:00 2001
From: Armand Philippot
Date: Tue, 3 Dec 2024 17:07:07 +0100
Subject: [PATCH 2/3] fix anchor, missing hyphen
---
src/content/docs/fr/reference/modules/astro-actions.mdx | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/content/docs/fr/reference/modules/astro-actions.mdx b/src/content/docs/fr/reference/modules/astro-actions.mdx
index 6aa722ffadf95..6aa7b4943a0a5 100644
--- a/src/content/docs/fr/reference/modules/astro-actions.mdx
+++ b/src/content/docs/fr/reference/modules/astro-actions.mdx
@@ -266,7 +266,7 @@ export const onRequest = defineMiddleware(async (context, next) => {
});
```
-Consultez le [guide des sessions avancées](/fr/guides/actions/#avancépersistance-des-résultats-daction-avec-une-session) pour un exemple d'implémentation à l'aide de Netlify Blob.
+Consultez le [guide des sessions avancées](/fr/guides/actions/#avancé-persistance-des-résultats-daction-avec-une-session) pour un exemple d'implémentation à l'aide de Netlify Blob.
#### `serializeActionResult()`
From a7ed742c848968123e9d8555e56c9f32d58589fe Mon Sep 17 00:00:00 2001
From: Armand Philippot
Date: Thu, 5 Dec 2024 22:37:22 +0100
Subject: [PATCH 3/3] complete Handling returned data section
See #10190
---
src/content/docs/fr/guides/actions.mdx | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/src/content/docs/fr/guides/actions.mdx b/src/content/docs/fr/guides/actions.mdx
index 48431dbda94ff..68548dea37b8b 100644
--- a/src/content/docs/fr/guides/actions.mdx
+++ b/src/content/docs/fr/guides/actions.mdx
@@ -168,6 +168,10 @@ Désormais, toutes vos actions utilisateur peuvent être appelées à partir de
Les actions renvoient un objet contenant soit `data` qui contient la valeur de retour de votre fonction `handler()` avec sûreté du typage, soit `error` qui contient les erreurs du backend. Ces dernières peuvent provenir d'erreurs de validation sur la propriété `input` ou d'erreurs générées dans la fonction `handler()`.
+Les actions renvoient un format de données personnalisé qui peut gérer les Dates, les Maps, les Sets et les URL [à l'aide de la bibliothèque Devalue](https://github.com/Rich-Harris/devalue). Par conséquent, vous ne pouvez pas facilement inspecter la réponse du réseau comme vous le pouvez avec du JSON classique. Pour le débogage, vous pouvez plutôt inspecter l'objet `data` renvoyé par les actions.
+
+[Consultez la référence de l'API `handler()`](/fr/reference/modules/astro-actions/#propriété-handler) pour plus de détails.
+
### Vérification des erreurs
Il est préférable de vérifier si une erreur (`error`) est présente avant d'utiliser la propriété `data`. Cela vous permet à la fois de gérer les erreurs à l'avance et d'être certain que `data` est définie sans vérification additionnelle pour `undefined`.