Saltar al contenido

Referencia de la API de Actions

Añadido en: astro@4.15.0

Las Actions te ayudan a construir un backend type-safe que puedes llamar desde código del cliente y formularios HTML. Todas las utilidades para definir y llamar actions se exponen a través del módulo astro:actions. Para ejemplos e instrucciones de uso, consulta la guía de Actions.

import {
ACTION_QUERY_PARAMS,
ActionError,
actions,
defineAction,
getActionContext,
getActionPath,
isActionError,
isInputError,
} from 'astro:actions';

Type: ({ accept, input, handler }) => ActionClient

Una utilidad para definir nuevas actions en el archivo src/actions/index.ts. Esta acepta una función handler() que contiene la lógica del servidor a ejecutar, y una propiedad opcional input para validar los parámetros de entrada en runtime.

src/actions/index.ts
import { defineAction } from 'astro:actions';
import { z } from 'astro/zod';
export const server = {
getGreeting: defineAction({
input: z.object({
name: z.string(),
}),
handler: async (input, context) => {
return `Hello, ${input.name}!`
}
})
}

Type: (input: TInputSchema, context: ActionAPIContext) => TOutput | Promise<TOutput>

Una función requerida que contiene la lógica del servidor a ejecutar cuando se llama la action. Los datos devueltos por el handler() se serializan automáticamente y se envían al llamador.

El handler() se llama con la entrada del usuario como primer argumento. Si se establece un validador de input, la entrada del usuario se validará antes de pasarse al handler. El segundo argumento es un subconjunto del objeto context de Astro.

Los valores de retorno se parsean usando la librería devalue. Esta soporta valores JSON e instancias de Date(), Map(), Set(), y URL().

Type: ZodType | undefined

Una propiedad opcional que acepta un validador Zod (ej. Zod object, Zod discriminated union) para validar las entradas del handler en runtime. Si la action falla la validación, se devuelve un error BAD_REQUEST y no se llama al handler.

Si se omite input, el handler recibirá una entrada de tipo unknown para peticiones JSON y de tipo FormData para peticiones de formulario.

Type: "form" | "json"
Default: json

Define el formato esperado por una action:

  • Usa form cuando tu action acepta FormData.
  • Usa json, el valor por defecto, para todos los demás casos.

Cuando tu action acepta entradas de formulario, el validador z.object() parseará automáticamente FormData a un objeto tipado. Todos los validadores Zod son soportados para validar tus entradas.

Aprende sobre el uso de validadores con entradas de formulario en la guía de Actions, incluyendo ejemplos de uso y manejo especial de entradas.

Type: Record<string, ActionClient>

Un objeto que contiene todas tus actions con el nombre de la action como clave asociada a una función para llamar esta action.

src/pages/index.astro
---
---
<script>
import { actions } from 'astro:actions';
async () => {
const { data, error } = await actions.myAction({ /* ... */ });
}
</script>

Para que Astro reconozca esta propiedad, puede que necesites reiniciar el dev server o ejecutar el comando astro sync (s + enter).

Type: (error?: unknown) => boolean

Una utilidad usada para comprobar si un ActionError es un error de validación de entrada. Cuando el validador de input es un z.object(), los errores de entrada incluyen un objeto fields con mensajes de error agrupados por nombre.

Consulta la guía de errores de entrada de formulario para más información sobre el uso de isInputError().

Type: (error?: unknown) => boolean

Una utilidad para comprobar si tu action lanzó un ActionError dentro de la propiedad handler. Esto es útil al estrechar el tipo de un error genérico.

src/pages/index.astro
---
---
<script>
import { isActionError, actions } from 'astro:actions';
async () => {
const { data, error } = await actions.myAction({ /* ... */ });
if (isActionError(error)) {
// Handle action-specific errors
console.log(error.code);
}
}
</script>

El constructor ActionError() se usa para crear errores lanzados por un handler de una action. Este acepta una propiedad code que describe el error ocurrido (ejemplo: "UNAUTHORIZED"), y una propiedad opcional message con más detalles.

El siguiente ejemplo crea un nuevo ActionError cuando el usuario no está logueado:

src/actions/index.ts
import { defineAction, ActionError } from "astro:actions";
export const server = {
getUserOrThrow: defineAction({
accept: 'form',
handler: async (_, { locals }) => {
if (locals.user?.name !== 'florian') {
throw new ActionError({
code: 'UNAUTHORIZED',
message: 'Not logged in',
});
}
return locals.user;
},
}),
}

También puedes usar ActionError para estrechar el tipo de error al manejar los resultados de una action:

src/pages/index.astro
---
---
<script>
import { ActionError, actions } from 'astro:actions';
async () => {
const { data, error } = await actions.myAction({ /* ... */ });
if (error instanceof ActionError) {
// Handle action-specific errors
console.log(error.code);
}
}
</script>

Type: ActionErrorCode

Define una versión legible de un código de estado HTTP.

Type: string

Una propiedad opcional para describir el error (ej. “El usuario debe estar logueado.”).

Type: string

Una propiedad opcional para pasar el stack trace.

Type: (context: APIContext) => AstroActionContext

Añadido en: astro@5.0.0

Una función llamada desde tu handler de middleware para obtener información sobre peticiones de action entrantes. Esta devuelve un objeto action con información sobre la petición, un método deserializeActionResult(), y las funciones setActionResult() y serializeActionResult() para establecer programáticamente el valor devuelto por Astro.getActionResult().

getActionContext() te permite obtener y establecer programáticamente resultados de actions usando middleware, permitiéndote persistir resultados de actions desde formularios HTML, proteger peticiones de actions con comprobaciones de seguridad adicionales, y más.

src/middleware.ts
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();
});

Type: { calledFrom: “rpc” | “form”; name: string; handler: () => Promise<SafeResult>; } | undefined

Un objeto que contiene información sobre una petición de action entrante. Está disponible desde getActionContext(), y proporciona el name de la action, el handler, y si la action fue llamada desde una función RPC del lado del cliente (ej. actions.newsletter()) o desde una action de formulario HTML.

src/middleware.ts
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')) {
// Check for a valid session token
}
// ...
});

Type: "rpc" | "form"

Si una action fue llamada usando una función RPC o una action de formulario HTML.

Type: string

El nombre de la action. Útil para rastrear el origen del resultado de una action durante una redirección.

Type: () => Promise<SafeResult>

Un método para llamar programáticamente una action y obtener el resultado.

Type: (actionName: string, actionResult: SerializedActionResult) => void

Una función para establecer programáticamente el valor devuelto por Astro.getActionResult() en el middleware. Se le pasa el nombre de la action y un resultado de action serializado por serializeActionResult(). Llamar a esta función desde el middleware deshabilitará el manejo propio de resultados de actions de Astro.

Esto es útil cuando se llaman actions desde un formulario HTML para persistir y cargar resultados desde una sesión.

src/middleware.ts
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();
// ... handle the action result
setActionResult(action.name, serializeActionResult(result));
}
return next();
});
Consulta la guía avanzada de sesiones para una implementación de ejemplo usando Netlify Blob.

Type: (res: SafeResult) => SerializedActionResult

Serializa un resultado de action a JSON para su persistencia. Esto es necesario para manejar correctamente valores de retorno no JSON como Map o Date así como el objeto ActionError.

Llama a esta función al serializar un resultado de action para pasarlo a setActionResult():

src/middleware.ts
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));
}
// ...
});

Type: (res: SerializedActionResult) => SafeResult

Revierte el efecto de serializeActionResult() y devuelve un resultado de action a su estado original. Esto es útil para acceder a los objetos data y error en un resultado de action serializado.

Type: (action: ActionClient) => string

Añadido en: astro@5.1.0

Una utilidad que acepta una action y devuelve una ruta URL para que puedas ejecutar una llamada a la action como una operación fetch() directamente. Esto te permite proporcionar detalles como headers personalizados cuando llamas a tu action. Luego, puedes manejar los datos devueltos con formato personalizado según sea necesario, igual que si hubieras llamado a una action directamente.

Este ejemplo muestra cómo llamar a una action like definida pasando el header Authorization y la opción keepalive:

src/components/my-component.astro
<script>
import { actions, getActionPath } from 'astro:actions'
await fetch(getActionPath(actions.like), {
method: 'POST',
headers: {
'Content-Type': 'application/json',
Authorization: 'Bearer YOUR_TOKEN'
},
body: JSON.stringify({ id: 'YOUR_ID' }),
keepalive: true
})
</script>

Este ejemplo muestra cómo llamar a la misma action like usando la API sendBeacon:

src/components/my-component.astro
<script>
import { actions, getActionPath } from 'astro:actions'
navigator.sendBeacon(
getActionPath(actions.like),
new Blob([JSON.stringify({ id: 'YOUR_ID' })], {
type: 'application/json'
})
)
</script>

Type: { actionName: string, actionPayload: string }

Un objeto que contiene los nombres de los parámetros de consulta usados internamente por Astro al manejar envíos de formularios con actions.

Cuando envías un formulario usando una action, los siguientes parámetros de consulta se añaden a la URL para rastrear la llamada a la action:

  • actionName - El parámetro de consulta que contiene el nombre de la action que se está llamando
  • actionPayload - El parámetro de consulta que contiene los datos del formulario serializados

Esta constante puede ser útil cuando necesitas limpiar URLs después de un envío de formulario. Por ejemplo, podrías querer eliminar los parámetros de consulta relacionados con la action durante una redirección:

src/pages/api/contact.ts
import type { APIRoute } from "astro";
import { ACTION_QUERY_PARAMS } from 'astro:actions'
export const GET: APIRoute = ({ params, request }) => {
const link = request.url.searchParams;
link.delete(ACTION_QUERY_PARAMS.actionName);
link.delete(ACTION_QUERY_PARAMS.actionPayload);
return redirect(link, 303);
};
import type {
ActionAPIContext,
ActionClient,
ActionErrorCode,
ActionInputSchema,
ActionReturnType,
SafeResult,
} from 'astro:actions';

Un subconjunto del objeto context de Astro. Las siguientes propiedades no están disponibles: callAction, getActionResult, props, y redirect.

Types:

  • (input?: any) => Promise<SafeResult>
  • { queryString?: string; orThrow: (input?: any) => Promise<Awaited<TOutput>>; }

Representa una action a ser llamada en el cliente. Puedes usarla como una función que acepta datos de entrada y devuelve una Promise con un objeto SafeResult que contiene el resultado de la action o errores de validación.

El siguiente ejemplo muestra cómo puedes proporcionar manejo de errores con una declaración if cuando falla el incremento del contador de likes:

src/pages/posts/post-1.astro
---
---
<!-- your template -->
<script>
import { actions } from 'astro:actions';
const post = document.querySelector('article');
const button = document.querySelector('button');
button?.addEventListener('click', async () => {
const { data: updatedLikes, error } = await actions.likePost({ postId: post?.id });
if (error) {
/* handle errors */
}
})
</script>

Alternativamente, puedes usarla como un objeto que te da acceso al queryString y a un método alternativo orThrow().

Type: string

Una representación en cadena de la action que puede usarse para construir URLs de actions de formulario. Esto puede ser útil cuando tu componente de formulario se usa en múltiples lugares pero necesitas redirigir a una URL diferente al enviar.

El siguiente ejemplo usa queryString para construir una URL que se pasará al atributo action del formulario a través de una prop personalizada:

src/pages/postal-service.astro
---
import { actions } from 'astro:actions';
import FeedbackForm from "../components/FeedbackForm.astro";
const feedbackUrl = new URL('/feedback', Astro.url);
feedbackUrl.search = actions.myAction.queryString;
---
<FeedbackForm sendTo={feedbackUrl.pathname} />

Type: (input?: any) => Promise<Awaited<TOutput>>

Un método que lanza un error en caso de fallo en lugar de devolver los errores. Esto es útil cuando quieres excepciones en lugar de manejo de errores.

El siguiente ejemplo usa orThrow() para omitir el manejo de errores cuando falla el incremento del contador de likes:

src/pages/posts/post-1.astro
---
---
<!-- your template -->
<script>
import { actions } from 'astro:actions';
const post = document.querySelector('article');
const button = document.querySelector('button');
button?.addEventListener('click', async () => {
const updatedLikes = await actions.likePost.orThrow({ postId: post?.id });
})
</script>

Type: string

Un tipo unión de códigos de estado HTTP estándar definidos por IANA usando las versiones legibles como cadenas en mayúsculas separadas por un guion bajo (ej. BAD_REQUEST o PAYLOAD_TOO_LARGE).

Type: ZodType

Añadido en: astro@5.16.0

Un tipo utilidad que infiere automáticamente el tipo de TypeScript de la entrada de una action basándose en su esquema Zod. Esto puede ser útil para referenciar el tipo de validador de input de una action como un objeto en tus propias definiciones de tipos.

Devuelve never cuando se omite el validador de input.

El siguiente ejemplo usa ActionInputSchema en una action llamada contact para:

  • Obtiene el tipo de esquema Zod para la entrada de la action.
  • Obtiene el tipo de entrada esperado del validador de la action.
src/components/Form.astro
---
import { actions, ActionInputSchema } from 'astro:actions';
import { z } from 'astro/zod';
type ContactSchema = ActionInputSchema<typeof actions.contact>;
type ContactInput = z.input<ContactSchema>;
---

Type: Awaited<ReturnType<ActionHandler>>

Un tipo utilidad que extrae el tipo de output de un handler de action. Esto desenvuelve tanto la Promise (si el handler es async) como el ReturnType para darte el tipo de output real. Esto puede ser útil si necesitas referenciar el tipo de output de una action en tus propias definiciones de tipos.

El siguiente ejemplo usa ActionReturnType para obtener el tipo de output esperado para una action llamada contact:

src/components/Form.astro
---
import { actions, ActionReturnType } from 'astro:actions';
type ContactResult = ActionReturnType<typeof actions.contact>;
---

Type: { data: TOutput, error: undefined } | { data: undefined, error: ActionError }

Representa el resultado de una llamada a una action:

  • en caso de éxito, data contiene el output de la action y error es undefined.
  • en caso de fallo, error contiene un ActionError con errores de validación o errores de runtime, y data es undefined.
Contribuir Comunidad Patrocinar