New

Launch your link-in-bio page in minutes Linkk

Getting started with the Sessions API in Astro

Learn how to use Astro's new Sessions API to manage server-side state like shopping carts and user data, without relying on cookies or client-side JavaScript.

Nathan Lawson

Managing per-user state in a web app can be challenging, especially when you want to keep things fast, secure, and server-rendered. Astro’s Sessions API offers a straightforward way to handle things like logged-in users, carts, or temporary form state. It avoids the complexity of cookies and client-side workarounds by keeping everything on the server.

What are sessions in Astro?

Sessions in Astro offer a secure, scalable way to store data between requests without relying on cookies or client-side storage. This feature is especially useful for things like:

  • Shopping carts
  • Authenticated user sessions
  • Form state
  • Visit tracking

Unlike cookies, session data is stored on the server. This means there’s no size limit, no need for encryption, and no risk of tampering from the client.

When should you use sessions?

Use Astro Sessions when you need to:

  • Share state across pages without relying on query params or localStorage.
  • Store sensitive or bulky data you don’t want exposed in the client.
  • Avoid shipping unnecessary client-side JavaScript for dynamic behavior.

How sessions work in Astro

The Astro.session object is available globally in server-rendered .astro components and pages. In server endpoints, actions, and middleware, it’s available as context.session.

Basic example: shopping cart button

---
export const prerender = false;
const cart = await Astro.session?.get('cart');
---

<a href="/checkout">🛒 {cart?.length ?? 0} items</a>

This component fetches the user’s cart from the session and displays the number of items, without any JavaScript sent to the client.

Setting up sessions

Most adapters like Node, Netlify, and Cloudflare come with a default session driver pre-configured.

For others like Vercel, you’ll need to specify a storage driver:

// astro.config.mjs
import vercel from "@astrojs/vercel/serverless";

export default {
  adapter: vercel(),
  session: {
    driver: 'redis',
  },
};

See the Astro adapter docs for info on supported drivers.

Working with session data

Astro’s Sessions API gives you five key methods:

  • get(key) - Fetch a value
  • set(key, value) - Store a value
  • destroy() - Delete the session entirely
  • regenerate() - Create a new session ID
  • id - Access the current session ID

Example: API route

// src/pages/api/addToCart.ts
export async function POST(context) {
  const cart = await context.session?.get('cart') || [];
  const data = await context.request.json();
  
  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);
}

Example: server actions

// src/actions/addToCart.ts
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;
    },
  }),
};

Using sessions in middleware

You can read and write session data during a request using Astro middleware:

// src/middleware.ts
import { defineMiddleware } from 'astro:middleware';

export const onRequest = defineMiddleware(async (context, next) => {
  context.session?.set('lastVisit', new Date());
  return next();
});

Note: Sessions are not currently supported in edge middleware.

You can define types for your session data using App.SessionData:

// src/env.d.ts
declare namespace App {
  interface SessionData {
    user: {
      id: string;
      name: string;
    };
    cart: string[];
  }
}

This enables type-checking and auto-complete in your editor, helping you catch bugs early.

Performance benefits of server-side sessions

Using Astro’s server-side sessions provides several important advantages over traditional cookie-based or client-side state management:

Faster page loads

Session data stays on the server, so you don’t need to serialize and send bulky state back and forth on every request. That means smaller payloads and faster pages, especially important for mobile users and low-bandwidth connections.

Improved security

Unlike cookies or localStorage, session data isn’t exposed to the client. That makes it immune to tampering, accidental leaks, or XSS attacks. Sensitive information like user IDs, roles, or in-progress form data stays safely on the server.

Centralized state management

With sessions, state is always accurate and available across routes and requests, regardless of the client’s environment. There’s no need to rehydrate state from the browser, making your code simpler and easier to maintain.

Use only what you need

Because session values are requested explicitly (for example, get('cart')), you’re not bloating every response with unnecessary data like you might with cookies. It’s efficient by design.

Common pitfalls and how to avoid them

Even though Astro Sessions are simple to use, there are a few common mistakes that can trip up developers. Here’s what to watch out for:

Sessions don’t work in static builds

Sessions require server-side rendering to function. If you’re using export const prerender = true or have static output configured, session data won’t be available.

Fix: Set prerender = false in any component or page that uses session data.

---
export const prerender = false;
---

Missing session driver for some adapters

Not all adapters (like Vercel) have a session driver configured out of the box.

Fix: Be sure to define a session.driver in your astro.config.mjs:

session: {
  driver: 'redis',
},

Trying to store unsupported data types

Session values are serialized using devalue, which means functions, class instances, or complex types like Promise or Symbol can’t be stored.

Fix: Stick to serializable types like strings, numbers, arrays, plain objects, Date, Map, and Set.

Forgetting to await session methods

Since methods like get() and set() are async, forgetting await can lead to subtle bugs.

Fix: Always await session method calls:

const cart = await context.session?.get('cart');

Final thoughts

Astro’s Sessions API introduces powerful new patterns for building dynamic, server-first web apps while keeping your frontend fast and JavaScript-free.

Whether you’re building a simple form or a complex ecommerce experience, sessions provide a secure and elegant way to manage state on the server.


Further reading

Ready to try it? Install Astro 5.7 and start managing state efficiently using server-side sessions.

Tags

astro tutorials sessions
<Layout>
  <header class="astro-fast">
    <nav>...</nav>
  </header>
  <main>
    <Hero client:idle />
    <Features />
    <Testimonials />
    <Pricing client:visible />
  </main>
  <footer>...</footer>
</Layout>
Premium Themes

Build blazing-fast websites with astrothem.es

Production-ready themes optimized for performance and designed to save you weeks of development time.

Linkk Theme Preview
Lightning Fast