Ask your question and get a summary of the document by referencing this page and the AI provider of your choice
If you have an idea for improving this documentation, please feel free to contribute by submitting a pull request on GitHub.
GitHub link to the documentationCopy doc Markdown to clipboard
import Since from '/components/Since.astro';
import ReadMore from '/components/ReadMore.astro';
Sessions are used to share data between requests for on-demand rendered pages.
Unlike cookies, sessions are stored on the server, so you can store larger amounts of data without worrying about size limits or security issues. They are useful for storing things like user data, shopping carts, and form state, and they work without any client-side JavaScript:
Copy the code to the clipboard
---export const prerender = false; // Not needed with 'server' outputconst cart = await Astro.session?.get('cart');---<a href="/checkout">π {cart?.length ?? 0} items</a>
Configuring sessions
Sessions require a storage driver to store the session data. The Node, Cloudflare, and Netlify adapters automatically configure a default driver for you, but other adapters currently require you to specify a driver manually.
Copy the code to the clipboard
{ adapter: vercel(), session: { driver: "redis", }, }
Interacting with session data
The session object allows you to interact with the stored user state (e.g. adding items to a shopping cart) and the session ID (e.g. deleting the session ID cookie when logging out). The object is accessible as Astro.session in your Astro components and pages and as context.session object in API endpoints, middleware, and actions.
The session is generated automatically when it is first used and can be regenerated at any time with session.regenerate() or destroyed with session.destroy().
For many use cases, you will only need to use session.get() and session.set().
Astro components and pages
In .astro components and pages, you can access the session object via the global Astro object. For example, to display the number of items in a shopping cart:
Copy the code to the clipboard
---export const prerender = false; // Not needed with 'server' outputconst cart = await Astro.session?.get('cart');---<a href="/checkout">π {cart?.length ?? 0} items</a>
API endpoints
In API endpoints, the session object is available on the context object. For example, to add an item to a shopping cart:
Copy the code to the clipboard
export async function POST(context: APIContext) { const cart = await context.session?.get('cart') || []; const data = await context.request.json<{ item: string }>(); if(!data?.item) { return new Response('Item is required', { status: 400 }); } cart.push(data.item); await context.session?.set('cart', cart); return Response.json(cart);}
Actions
In actions, the session object is available on the context object. For example, to add an item to a shopping cart:
Copy the code to the clipboard
import { defineAction } from 'astro:actions';import { z } from 'astro:schema';export const server = { addToCart: defineAction({ input: z.object({ productId: z.string() }), handler: async (input, context) => { const cart = await context.session?.get('cart'); cart.push(input.productId); await context.session?.set('cart', cart); return cart; }, }),};
Middleware
:::note Sessions are not supported in edge middleware. :::
In middleware, the session object is available on the context object. For example, to set the last visit time in the session:
Copy the code to the clipboard
import { defineMiddleware } from 'astro:middleware';export const onRequest = defineMiddleware(async (context, next) => { context.session?.set('lastVisit', new Date()); return next();});
Session data types
By default session data is untyped, and you can store arbitrary data in any key. Values are serialized and deserialized using devalue, which is the same library used in content collections and actions. This means that supported types are the same, and include strings, numbers, Date, Map, Set, URL, arrays, and plain objects.
You can optionally define TypeScript types for your session data by creating a src/env.d.ts file and adding a declaration for the App.SessionData type:
Copy the code to the clipboard
declare namespace App { interface SessionData { user: { id: string; name: string; }; cart: string[]; }}
This will allow you to access the session data with type-checking and auto-completion in your editor:
Copy the code to the clipboard
---const cart = await Astro.session?.get('cart');// const cart: string[] | undefinedconst something = await Astro.session?.get('something');// const something: anyAstro.session?.set('user', { id: 1, name: 'Houston' });// Error: Argument of type '{ id: number; name: string }' is not assignable to parameter of type '{ id: string; name: string; }'.---
:::caution This is only used for type-checking and does not affect the runtime behavior of the session. Take extra care if you change the type when users have stored data in the session, as this could cause runtime errors. :::