Fix: Session Configuration Missing in Astro

Error message:
Session configuration is required.
Sessions & Cookies 2025-01-25

What Causes This Error?

This error occurs when you try to use Astro.session without configuring sessions in your Astro config. Sessions are an experimental feature that requires explicit configuration.

The Problem

---
// ❌ Using sessions without config
const session = Astro.session;
const user = await session.get('user');
---
// astro.config.mjs
export default defineConfig({
  // No session configuration!
});

The Fix

Add Session Configuration

// astro.config.mjs
import { defineConfig } from 'astro/config';
import node from '@astrojs/node';

export default defineConfig({
  output: 'server',
  adapter: node({ mode: 'standalone' }),
  experimental: {
    session: {
      driver: 'memory',  // ✅ Configure session driver
    },
  },
});

Common Scenarios

Minimal Session Setup

// astro.config.mjs
import { defineConfig } from 'astro/config';
import node from '@astrojs/node';

export default defineConfig({
  output: 'server',
  adapter: node({ mode: 'standalone' }),
  experimental: {
    session: {
      driver: 'cookie',
      options: {
        secret: process.env.SESSION_SECRET,
      },
    },
  },
});

Choose a Session Driver

// Available drivers:
export default defineConfig({
  experimental: {
    session: {
      // Option 1: Memory (dev only, data lost on restart)
      driver: 'memory',

      // Option 2: Cookie (limited to ~4KB)
      // driver: 'cookie',
      // options: { secret: 'your-secret' },

      // Option 3: Filesystem
      // driver: 'fs',
      // options: { base: './.sessions' },

      // Option 4: Redis
      // driver: 'redis',
      // options: { url: 'redis://localhost:6379' },

      // Option 5: Upstash (serverless Redis)
      // driver: 'upstash',
      // options: { url: '...', token: '...' },
    },
  },
});

Enable Server-Side Rendering

// Sessions require SSR
export default defineConfig({
  output: 'server',  // ✅ Required
  // or
  output: 'hybrid',  // ✅ Also works

  // NOT:
  // output: 'static',  // ❌ Won't work with sessions

  adapter: node({ mode: 'standalone' }),
  experimental: {
    session: {
      driver: 'memory',
    },
  },
});

Using Sessions in Components

---
// After configuration, sessions are available
export const prerender = false;  // Must be SSR page

const session = Astro.session;

// Read session data
const user = await session.get('user');
const cart = await session.get('cart') || [];

// Write session data
await session.set('lastVisit', new Date().toISOString());
---

<html>
  <body>
    {user ? (
      <p>Welcome back, {user.name}!</p>
    ) : (
      <a href="/login">Log in</a>
    )}
  </body>
</html>

Session Methods

---
const session = Astro.session;

// Get value (returns undefined if not set)
const value = await session.get('key');

// Set value
await session.set('key', { any: 'data' });

// Check if key exists
const exists = await session.has('key');

// Delete specific key
await session.delete('key');

// Regenerate session ID (do this after login)
await session.regenerate();

// Destroy entire session (logout)
await session.destroy();
---

Authentication Example

---
// src/pages/login.astro
export const prerender = false;

if (Astro.request.method === 'POST') {
  const formData = await Astro.request.formData();
  const email = formData.get('email');
  const password = formData.get('password');

  const user = await validateCredentials(email, password);

  if (user) {
    // Regenerate session to prevent fixation
    await Astro.session.regenerate();
    await Astro.session.set('user', {
      id: user.id,
      email: user.email,
      name: user.name,
    });
    return Astro.redirect('/dashboard');
  }
}
---

<form method="POST">
  <input type="email" name="email" required />
  <input type="password" name="password" required />
  <button type="submit">Log In</button>
</form>

Protected Routes

---
// src/pages/dashboard.astro
export const prerender = false;

const user = await Astro.session.get('user');

if (!user) {
  return Astro.redirect('/login');
}
---

<h1>Welcome, {user.name}</h1>

Logout Handler

---
// src/pages/logout.astro
export const prerender = false;

// Destroy the session
await Astro.session.destroy();

return Astro.redirect('/');
---

Session with Cookies Config

// Full cookie session configuration
export default defineConfig({
  output: 'server',
  adapter: node({ mode: 'standalone' }),
  experimental: {
    session: {
      driver: 'cookie',
      options: {
        name: 'session',          // Cookie name
        secret: 'your-secret',    // Encryption key (32+ chars)
        cookie: {
          httpOnly: true,
          secure: true,           // HTTPS only
          sameSite: 'lax',
          maxAge: 60 * 60 * 24,   // 1 day in seconds
        },
      },
    },
  },
});

Quick Checklist

  • Add experimental.session to astro.config.mjs
  • Choose a session driver (memory, cookie, fs, redis)
  • Set output: 'server' or output: 'hybrid'
  • Install an SSR adapter
  • Use prerender: false on pages using sessions
  • Set SESSION_SECRET environment variable
  • Use session.regenerate() after login