Actions

Purpose and Scope

Astro Actions are the framework’s type-safe bridge between frontend callers and backend functions. The official guide frames them as an alternative to hand-written API endpoints when the task is calling server logic from client code, script tags, UI framework components, or HTML form submissions. In the runtime, this feature is implemented as a small public module surface plus server handlers that parse input, validate it, execute user code, and return a standardized result envelope. This page explains that path from authoring an action to receiving either successful data or an action error. Sources: packages/astro/src/actions/runtime/server.ts, packages/astro/src/actions/runtime/types.ts

The key distinction is that an action is not just a fetch helper. A project author defines a server-side handler with optional Zod input validation, and Astro exposes a callable client shape that returns a safe result object. That result has either data or error, which lets application code branch without manually interpreting HTTP status codes or response bodies. When needed, the same callable also exposes an throwing variant for code paths that prefer exceptions. The types describe this public contract, including accepted input modes, return inference, and the subset of Astro request context passed into handlers. Sources: packages/astro/src/actions/runtime/types.ts

Relevant Source Files

  • packages/astro/src/actions/runtime/client.ts — Shared client-safe runtime utilities for action errors, input errors, status-code mapping, action result deserialization, action path helpers, and proxy creation.
  • packages/astro/src/actions/runtime/entrypoints/client.ts — Browser-facing astro:actions entrypoint that exports actions, getActionPath, error helpers, and type exports while preventing server-only utilities from running on the client.
  • packages/astro/src/actions/runtime/entrypoints/server.ts — Server-facing astro:actions entrypoint that re-exports defineAction and getActionContext, resolves actions through the rendering pipeline, and supports server-side action calls when context is available.
  • packages/astro/src/actions/runtime/server.ts — Core server implementation of defineAction, JSON and form handlers, Zod parsing, safe result wrapping, body handling, serialization, and action lookup behavior.
  • packages/astro/src/actions/runtime/types.ts — Public and internal TypeScript contracts for action clients, handlers, safe results, action context, accepted input types, and serialized result shapes.
  • .github/workflows/build-sandbox-image.yml — CI workflow for publishing the repository sandbox image with pinned GitHub Actions and Docker build steps; useful as a repository automation signal, not part of the Astro Actions runtime.

Core Primitives

The public module is astro:actions. On the server entrypoint it exports defineAction, getActionContext, getActionPath, actions, ActionError, isActionError, and isInputError, plus the public action types. On the client entrypoint it exports the callable actions proxy and error helpers, but intentionally throws if defineAction or getActionContext is used in browser code. That split protects server-only authoring utilities while keeping client imports ergonomic. The client entrypoint also builds action URLs from the application base URL and trailing-slash behavior supplied by virtual configuration. Sources: packages/astro/src/actions/runtime/entrypoints/client.ts, packages/astro/src/actions/runtime/entrypoints/server.ts

defineAction is the authoring primitive used in a project’s server action file. Its options include handler, optional input, and optional accept. The handler receives parsed input and an action-specific API context, then returns either a value or a promise. The accept mode distinguishes JSON-style calls from form submissions; when omitted, the implementation uses JSON behavior. The returned value is typed as an ActionClient, so the same declaration describes how callers invoke the action and how safe results are shaped. Sources: packages/astro/src/actions/runtime/server.ts, packages/astro/src/actions/runtime/types.ts

Execution Flow

A typical JSON action call begins in the browser through the actions proxy. The client entrypoint creates request headers that accept JSON, applies adapter-specific internal fetch headers, and serializes non-FormData input with JSON. If serialization fails, the client throws an ActionError with a bad-request code before any network request is made. Otherwise it posts to the generated action URL. Empty responses become empty serialized results, successful responses are treated as devalue-encoded data, and error responses are interpreted as JSON error payloads before being deserialized for the caller. Sources: packages/astro/src/actions/runtime/entrypoints/client.ts, packages/astro/src/actions/runtime/client.ts

On the server, defineAction chooses a form handler or JSON handler and wraps it in a safe server handler. The wrapper first verifies that it is being called with an action API context rather than as a detached function, then calls the selected handler through safe execution. JSON handlers reject FormData as unsupported media, optionally parse input with Zod, and pass validated data to user code. Form handlers require FormData, optionally convert object-shaped form submissions before validation, and raise an input error when parsing fails. This gives both submission styles one consistent result contract. Sources: packages/astro/src/actions/runtime/server.ts

Server-side imports of actions use a different transport. Instead of issuing a fetch, the server entrypoint looks for Astro’s rendering pipeline on the current context, resolves the action by path, and invokes the action bound to that context. If the context does not carry the pipeline, Astro raises the dedicated “called from server” error. This design means server code can reuse the same action names while still preserving the request-local state that handlers expect, including cookies, locals, route params, session, cache, CSP, and logger access through the narrowed action context type. Sources: packages/astro/src/actions/runtime/entrypoints/server.ts, packages/astro/src/actions/runtime/types.ts

API Components and Result Shapes

Action errors are first-class values. ActionError carries the marker type, an ActionErrorCode, and a numeric HTTP status derived from the code-to-status map. The map covers standard client and server failure cases such as bad request, unauthorized, not found, conflict, unsupported media type, too many requests, and internal server error. ActionInputError specializes this shape for validation failures. It exposes Zod issues and a fields object, intentionally avoiding the full Zod error object so that serialized server errors remain compact and safe to use on the client. Sources: packages/astro/src/actions/runtime/client.ts

The type layer makes the runtime contract explicit. SafeResult is a discriminated success-or-error shape where successful calls have data and no error, while failed calls have error and no data. SerializedActionResult captures the wire format: devalue data with a successful status, JSON error bodies with an arbitrary error status, or an empty response status. ActionInputSchema preserves schema inference for callers, and ErrorInferenceObject lets input errors narrow their fields property after isInputError checks. These types are what make actions feel like local functions while still crossing a client-server boundary. Sources: packages/astro/src/actions/runtime/types.ts

Example Authoring Flow

A project author normally creates an actions index file, exports a server object, and places named action declarations inside it. A greeting action might validate an object with a name string and return a greeting from its handler. A page or component can then import actions and call the action by name, receiving { data, error }. For form-first workflows, the action can accept form data and let the server handler enforce that only FormData reaches that endpoint. For exception-oriented code, the generated client also has orThrow, which bypasses the safe-result envelope and returns the raw handler result or throws. Sources: packages/astro/src/actions/runtime/server.ts, packages/astro/src/actions/runtime/types.ts

CI/CD Signals

The requested source set also includes the repository workflow that builds a sandbox image. That workflow runs on pushes to the main branch when sandbox files or the workflow itself change, and it can also be started manually. It lowercases the image name, checks out the repository with a pinned checkout action, logs in to GitHub Container Registry, configures Buildx, then builds and pushes tags for latest and a content hash. This does not implement Astro Actions, but it shows the repository’s automation style: narrow triggers, explicit permissions, pinned third-party actions, and build cache configuration. Sources: .github/workflows/build-sandbox-image.yml

Next Steps

Use this page when deciding whether backend work should be an Action or a conventional endpoint. Choose Actions when the caller benefits from generated function types, Zod validation, safe result handling, and standardized ActionError behavior. Choose endpoint routes when you need a custom protocol, nonstandard response streaming, or a public HTTP contract that should not look like a local function call. After reading this page, continue to the Endpoints, Middleware, Sessions, and API Reference pages to see how actions interact with lower-level request handling and broader Astro runtime APIs.