Sessions
Purpose and Scope
Astro sessions are a server-side mechanism for sharing data between requests in on-demand rendered pages. In application terms, a session gives a user a stable place to keep request-to-request state such as a cart, form progress, or authenticated user data without placing that state directly in browser-visible cookies. The official session guide positions this feature for server-rendered pages and notes that it works without client-side JavaScript, which is important in Astro because the framework’s default authoring model favors lightweight output and only hydrates client islands when requested.
A useful mental model is that a cookie identifies or participates in a session, while the actual session data lives in storage controlled by the server runtime. That distinction matters for security, size, and deployment. Instead of serializing large or sensitive values into the browser, your page or endpoint reads from Astro.session during a request and writes through the configured session storage driver. The code paths supplied for this page do not expose the complete session runtime, but they do show Astro’s broader pattern: runtime-facing features are compiled from package source, adapter behavior can affect request rendering, and build-time configuration is carefully separated from generated output.
Sources: configs/tsconfig.build.json, .changeset/sharp-bags-build.md
Relevant Source Files
.changeset/sharp-bags-build.md- Records a Cloudflare/workerd build fix where rendering errors are buffered and surfaced instead of being swallowed, which is relevant to any request-time feature, including session-backed on-demand pages, that can fail during server rendering.configs/tsconfig.build.json- Defines the shared TypeScript build configuration used by package builds, includingrootDir,outDir, and a privatetsBuildInfoFilelocation underdist/._cache.packages/astro-prism/tsconfig.build.json- Shows a package extending the shared build config while adding package-specific includes, illustrating how Astro packages adapt the common build contract.packages/astro-rss/tsconfig.build.json- Shows another package using the shared build config without extra package-specific include overrides.packages/astro/src/assets/fonts/infra/build-font-file-id-generator.ts- Provides an example of deterministic build-time runtime infrastructure: generated font file identifiers are derived from resolved content and font type.packages/astro/src/assets/fonts/infra/build-url-resolver.ts- Shows runtime-adjacent URL resolution that accounts for base paths, assets prefixes, content security policy resources, emitted URLs, and adapter-level search parameters such as skew-protection tracking.
Core Session Primitives
The first primitive is Astro.session, accessed during an on-demand request. In the official guide, a component reads a cart using await Astro.session?.get('cart') and renders a count in server output. The optional access is intentional in examples because session availability depends on runtime configuration and rendering mode. A prerendered page cannot rely on per-request state, so examples either set export const prerender = false or depend on a project-wide server output mode that makes pages render at request time.
The second primitive is the session driver. A driver is the storage implementation behind the session API. Astro’s documentation says that Node, Cloudflare, and Netlify adapters automatically configure default drivers, while other adapters may require explicit configuration. That creates a deployment boundary: authoring code can stay focused on Astro.session, but the project configuration must still decide where state is stored. For local or small deployments, a built-in in-memory or LRU-style driver may be appropriate; for distributed deployments, an external service-backed driver such as Redis is usually the model described by the driver reference.
The third primitive is SessionDriverConfig, the configuration object that points Astro at a runtime implementation. The official reference describes it as an object with a required entrypoint and optional serializable config. The recommended shape is a function that accepts driver-specific options and returns that object. This mirrors the repository’s broader build pattern: package source is compiled into distributable output, while runtime entrypoints are referenced explicitly so the server environment can load the correct implementation when handling requests.
Sources: configs/tsconfig.build.json, packages/astro-prism/tsconfig.build.json, packages/astro-rss/tsconfig.build.json
Configuration Flow
A typical session setup starts in astro.config.mjs or astro.config.ts by importing defineConfig and sessionDrivers from astro/config. The official docs show a Vercel configuration using sessionDrivers.lruCache({ max: 800 }), and the driver reference shows a Redis-style configuration using sessionDrivers.redis({ url: process.env.REDIS_URL }). These examples highlight two separate choices: the deployment adapter decides where pages run, and the session driver decides where per-user state is stored. In a simple environment those choices may be coupled by adapter defaults, but Astro keeps the concepts separate.
import { defineConfig, sessionDrivers } from 'astro/config';
import vercel from '@astrojs/vercel';
export default defineConfig({
adapter: vercel(),
session: {
driver: sessionDrivers.lruCache({ max: 800 }),
},
});The runtime override story is especially important for external services. The official sessions guide explains that drivers configured at build time can inline environment variables into the build, which means a later runtime environment cannot necessarily change them. When a deployment needs runtime-specific values, the guide recommends defining the driver in a separate file and using that file as the driver entrypoint. The supplied build configuration reinforces why this matters: Astro packages are compiled from src to dist, and build artifacts are intentionally managed outside publishable source files, so anything meant to remain runtime-selectable should be modeled as a runtime entrypoint rather than a value baked into compiled configuration.
Sources: configs/tsconfig.build.json
Runtime and Adapter Considerations
Sessions only become meaningful when a request is handled by a server runtime. That is why the official guide repeatedly frames sessions around on-demand rendered pages rather than static output. In Astro, adapters provide the bridge between the framework’s server rendering model and the platform where requests run. The Cloudflare changeset included in the source evidence is not a session feature announcement, but it is directly relevant to the reliability expectations for request-time rendering: when pages throw during rendering in workerd, the build must surface the failure instead of emitting truncated HTML and exiting successfully.
This matters for session-backed pages because session reads and writes often depend on runtime services: a cache, a database, a platform key-value store, or a custom unstorage driver. If those services fail or a driver is misconfigured, the page should fail in a way that the developer can diagnose. The Cloudflare fix describes buffering the response body inside workerd before sending it back to the build process so streaming errors are caught and reported as build failures. That kind of adapter-level correctness is part of making server features safe to use in production.
Sources: .changeset/sharp-bags-build.md
Astro’s asset infrastructure also shows how runtime-adjacent features preserve deployment context. BuildUrlResolver receives a base path, an assets prefix, and search parameters; it records content security policy resources and final URLs while appending adapter-level query parameters. The inline comment names skew protection as one use case for those search parameters. Sessions are not asset URLs, but both systems share the same architectural pressure: server output must be generated with enough deployment context to be correct after an adapter places it on a hosting platform.
Sources: packages/astro/src/assets/fonts/infra/build-url-resolver.ts
Driver Reference
A session driver config contains the information Astro needs to locate and initialize a storage implementation. The official driver reference describes two parts: the driver config, which tells Astro what implementation to use and what options to forward, and the driver implementation, which performs the runtime storage operations. The documented entrypoint field accepts a string or URL, and the optional config field accepts a serializable record. When writing your own driver, prefer a small exported factory function so application code imports a named driver helper instead of hand-writing object literals throughout configuration files.
import type { SessionDriverConfig } from 'astro';
export interface Config {
max?: number;
}
export function memoryDriver(config: Config = {}): SessionDriverConfig {
return {
entrypoint: new URL('./runtime.js', import.meta.url),
config,
};
}Treat the config field as data that can cross the build/runtime boundary. Avoid passing live connections, functions, or unserializable process state through it. If a driver needs runtime-only environment values, define a runtime entrypoint that reads those values when the platform loads the driver. This is the same design principle visible in BuildFontFileIdGenerator, which separates a content resolver and hasher from the final generated identifier: the caller supplies the pieces, and the infrastructure produces a deterministic output from explicit inputs rather than hidden global state.
Sources: packages/astro/src/assets/fonts/infra/build-font-file-id-generator.ts
System-to-Code Mapping
| Session concept | Repository evidence | What to take from it |
|---|---|---|
| Build-time package compilation | configs/tsconfig.build.json | Package source is compiled from src to dist, so runtime entrypoints and build-time values should be modeled deliberately. |
| Package-specific build surface | packages/astro-prism/tsconfig.build.json | Astro packages can extend the common build contract while adding package-specific inputs. |
| Default package build surface | packages/astro-rss/tsconfig.build.json | Some packages need only the shared build configuration, which keeps distribution behavior consistent. |
| Adapter rendering reliability | .changeset/sharp-bags-build.md | Server rendering failures must be surfaced clearly, especially for request-time features. |
| Deployment-aware runtime output | packages/astro/src/assets/fonts/infra/build-url-resolver.ts | Runtime-adjacent output can depend on base paths, asset prefixes, CSP resources, and adapter search parameters. |
| Deterministic generated artifacts | packages/astro/src/assets/fonts/infra/build-font-file-id-generator.ts | Build infrastructure favors explicit inputs and reproducible output identifiers. |
Practical Workflow
Start by deciding whether the route that needs state is actually on-demand rendered. If the page can be fully prerendered, a session will not add value because there is no per-request server execution to read it. For a component-level example, follow the official guide’s pattern: disable prerendering for that page or use server output, read with await Astro.session?.get('cart'), and render the result into HTML. Then choose the driver that matches the deployment platform and data durability requirements.
Next, make configuration explicit. If your adapter provides a default driver and that driver matches your needs, document that assumption in the project configuration or deployment notes. If you need a specific driver, configure session.driver directly. If the driver uses runtime secrets, create a separate driver entrypoint instead of relying on build-time environment inlining. Finally, test the route in the same rendering mode you will deploy. Session behavior is part API design and part deployment contract, so confidence comes from exercising the configured adapter, the selected driver, and the page that reads or writes the state together.
Related Pages and Next Steps
Read server-side-rendering-adapters next if you need to understand how an Astro adapter changes where on-demand routes execute. Read configuration-reference for the broader shape of astro.config.* and package exports from astro/config. If sessions are being used for sign-in state, continue to authentication, where sessions combine with middleware, endpoints, and actions. For form submissions or cart updates, pair this page with actions, because actions often provide the request handlers that mutate session data before the next page render.