Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions astro.sidebar.ts
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,7 @@ export const sidebar = [
'reference/content-loader-reference',
'reference/image-service-reference',
'reference/dev-toolbar-app-reference',
'reference/session-driver-reference',
'reference/container-reference',
'reference/programmatic-reference',
],
Expand Down
17 changes: 11 additions & 6 deletions src/content/docs/en/guides/sessions.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -28,13 +28,18 @@ const cart = await Astro.session?.get('cart');

Sessions require a storage driver to store the session data. The [Node](/en/guides/integrations-guide/node/#sessions), [Cloudflare](/en/guides/integrations-guide/cloudflare/#sessions), and [Netlify](/en/guides/integrations-guide/netlify/#sessions) adapters automatically configure a default driver for you, but other adapters currently require you to [specify a driver manually](/en/reference/configuration-reference/#sessiondriver).

```js title="astro.config.mjs" ins={4}
{
adapter: vercel(),
session: {
driver: "redis",
},
```js title="astro.config.mjs" ins={7-9} ins=" sessionDrivers "
import { defineConfig, sessionDrivers } from 'astro/config'
import vercel from '@astrojs/vercel'

export default defineConfig({
adapter: vercel()
session: {
driver: sessionDrivers.redis({
url: process.env.REDIS_URL
}),
}
})
```

<ReadMore>
Expand Down
65 changes: 65 additions & 0 deletions src/content/docs/en/guides/upgrade-to/v6.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -304,6 +304,41 @@ console.log('astro:after-swap');

<ReadMore>Learn more about all utilities available in the [View Transitions Router API Reference](/en/reference/modules/astro-transitions/).</ReadMore>

### Deprecated: session driver string signature

<SourcePR number="15006" title="feat(sessions): drivers" />

In Astro 5.x, any [unstorage provider](https://unstorage.unjs.io/drivers) name or a custom entrypoint could be provided to define a session driver, and options were also provided directly to the `session` configuration. However, we felt that this API was limited and inconsistent with other parts of the Astro config.

Astro 6.0 deprecates the driver string signature and options in favor of a new object shape.

#### What should I do?

Update your session config to use the newly exported `sessionDrivers`:

```js title="astro.config.mjs" del={1,6-9} ins={2,10-12}
import { defineConfig } from 'astro/config'
import { defineConfig, sessionDrivers } from 'astro/config'

export default defineConfig({
session: {
driver: 'redis',
options: {
url: process.env.REDIS_URL
},
driver: sessionDrivers.redis({
url: process.env.REDIS_URL
}),
cookie: {
secure: true
},
ttl: 3600
}
})
```

<ReadMore>Learn more about [available session drivers](/en/reference/session-driver-reference/#building-a-session-driver).</ReadMore>

## Removed

The following features have now been entirely removed from the code base and can no longer be used. Some of these features may have continued to work in your project even after deprecation. Others may have silently had no effect.
Expand Down Expand Up @@ -812,6 +847,8 @@ export const server = {

### Removed: schema function signature (Content Loader API)

<SourcePR number="14759" title="feat: loader.createSchema()" />

In Astro 5.x, a content loader could choose to define a schema as a function instead of defining a Zod schema object for validation. This is useful to dynamically generate the schema based on the configuration options or by introspecting an API.

Astro 6.0 removes this signature and introduces a new `createSchema()` property as a replacement for those who still want to dynamically define a schema in their content loader.
Expand Down Expand Up @@ -853,6 +890,34 @@ function myLoader() {

<ReadMore>Learn more about [`createSchema()`](/en/reference/content-loader-reference/#createschema) in the Content Loader API reference.</ReadMore>

### Removed: session `test` driver

<SourcePR number="15006" title="feat(sessions): drivers" />

In Astro 5.x, the internal session `test` driver was exported in the Astro config types, but it was not meant to be exposed for public use.

Astro 6.0 removes the session `test` driver as it is no longer used internally to test `context.session`.

#### What should I do?

It is unlikely that you are using this internal API. If you do, you must remove any usage of the session `test` driver:

```js title="astro.config.mjs" del={2,6-9}
import { defineConfig } from 'astro/config'
import { createMockStorage } from './utils'

export default defineConfig({
session: {
driver: 'test',
options: {
mockStorage: createMockStorage()
}
}
})
```

<ReadMore>Learn more about the [Session Driver API](/en/reference/session-driver-reference/).</ReadMore>

### Experimental Flags

Experimental flags allow you to opt in to features while they are in early development. Astro may also use experimental flags to test breaking changes to default behavior. The following experimental flags have been removed in Astro 6.0 and are now stable, or the new default behavior.
Expand Down
191 changes: 191 additions & 0 deletions src/content/docs/en/reference/session-driver-reference.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,191 @@
---
title: Astro Session Driver API
sidebar:
label: Session Driver API
i18nReady: true
tableOfContents:
minHeadingLevel: 2
maxHeadingLevel: 4
---
import Since from '~/components/Since.astro';

Astro [sessions](/en/guides/sessions/) allow to share data between requests for on-demand rendered pages. They require an Astro Session Driver to store session data.

## Built-in drivers

Astro exports built-in session drivers from `astro/config`:

```js
import { sessionDrivers } from 'astro/config'
```

Any [unstorage driver](https://unstorage.unjs.io/drivers) can be used, for example:

```js title="astro.config.mjs" ins={5-7} ins=" sessionDrivers "
import { defineConfig, sessionDrivers } from 'astro/config'

export default defineConfig({
session: {
driver: sessionDrivers.redis({
url: process.env.REDIS_URL
}),
}
})
```

:::note
Some drivers may need extra packages to be installed. Some drivers may also require environment variables or credentials to be set. See the [Unstorage documentation](https://unstorage.unjs.io/drivers) for more information.
:::

## Building a session driver

A session driver is made of two parts:

- The [driver config](#the-session-driver-config), which lets Astro know what implementation to use at runtime and what config to forward
- The [driver implementation](#the-session-driver-implementation), which handles the storage logic at runtime

### The session driver config

A `SessionDriverConfig` is an object containing a required runtime [`entrypoint`](#entrypoint) and an optional [`config`](#config). The preferred method for implementing it is to export a function that returns this object and takes the configuration as an optional parameter.

The following example defines a memory driver config:

```ts title="driver/config.ts"
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,
}
}
```

It is then registered in the Astro config:

```ts title="astro.config.ts"
import { defineConfig } from 'astro/config'
import { memoryDriver } from './driver/config'

export default defineConfig({
session: {
driver: memoryDriver({
max: 500
})
}
})
```

#### `entrypoint`

<p>

**Type:** `string | URL`
<Since v="6.0.0" />
</p>

Defines the entrypoint for the [driver implementation](#the-session-driver-implementation).

#### `config`

<p>

**Type:** `Record<string, any> | undefined`
<Since v="6.0.0" />
</p>

Defines the serializable config passed to [driver implementation](#the-session-driver-implementation) at runtime.

### The session driver implementation

A `SessionDriver` is an object responsible for [storing](#setitem), [retrieving](#getitem) and [deleting](#removeitem) data when [using sessions at runtime](/en/reference/api-reference/#session) (e.g. `context.session.set()`). You can implement it in your session driver module by exporting a default function that takes the [driver config](#config) as parameter.

The following example implements a memory driver:

```ts title="driver/runtime.ts"
import type { SessionDriver } from 'astro'
import type { Config } from './config'
import { LRUCache } from 'lru-cache'

export default function(config: Config): SessionDriver {
const cache = new LRUCache({ max: config.max })
return {
setItem: async (key, value) => {
cache.set(key, value)
},
getItem: async (key) => {
return cache.get(key)
},
removeItem: async (key) => {
cache.delete(key)
},
}
}
```

#### `setItem()`

<p>

**Type:** `(key: string, value: any) => Promise<void>`
<Since v="6.0.0" />
</p>

Defines a function that sets session data by key.

#### `getItem()`

<p>

**Type:** `(key: string) => Promise<any>`
<Since v="6.0.0" />
</p>

Defines a function that retrieves session data by key.

#### `removeItem()`

<p>

**Type:** `(key: string) => Promise<void>`
<Since v="6.0.0" />
</p>

Defines a function that removes session data by key.

## Unstorage compatibility

Unstorage driver types are compatible with Astro's `SessionDriver` type.

That means you can use an unstorage package export as an [entrypoint](#entrypoint). For example:

```ts title="driver/config.ts" {5}
import type { SessionDriverConfig } from 'astro'

export function configuredRedisDriver(): SessionDriverConfig {
return {
entrypoint: 'unstorage/drivers/redis',
config: {
tls: true
}
}
}
```

Alternatively, you can import and use an unstorage driver directly in the implementation. For example:

```ts title="driver/runtime.ts" {2}
import type { SessionDriver } from 'astro'
import redisDriver from "unstorage/drivers/redis";

export default function(config): SessionDriver {
return redisDriver({
...config,
tls: true
})
}
```