@nuxt/docs-nightly 5.0.0-29824817.35cc2cb5 → 5.0.0-29824891.6f2fc18e

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -396,6 +396,52 @@ Server auto-imports resolve to `nuxt/server` too, so a project that leaves them
396
396
  Learn what the surface covers, and what it means for module authors.
397
397
  ::
398
398
 
399
+ ### Sessions Come From `nuxt/server`
400
+
401
+ 🚦 **Impact Level**: Medium
402
+
403
+ #### What Changed
404
+
405
+ `useSession`, `getSession`, `updateSession` and `clearSession` are now part of [`nuxt/server`](/docs/guide/going-further/server-imports#sessions), and are what the auto-imported names resolve to. They seal the session with `iron-webcrypto` on web-standard `Request` and `Response`, so they run under any [`server.builder`](/docs/guide/going-further/builders) rather than only under Nitro.
406
+
407
+ A session issued by the h3 helpers does not unseal with these, and the default cookie name is `nuxt-session` rather than `h3`. Everyone signed in before the upgrade gets a fresh, empty session once.
408
+
409
+ A `password` is no longer required. Without one, the session is sealed with a secret derived from [`appSecret`](/docs/guide/going-further/runtime-config#application-secret), which `NUXT_APP_SECRET` sets:
410
+
411
+ ```diff [server/api/me.ts]
412
+ export default defineEventHandler(async (event) => {
413
+ - const session = await useSession<{ user?: string }>(event, {
414
+ - password: process.env.NUXT_SESSION_PASSWORD!,
415
+ - })
416
+ + const session = await useSession<{ user?: string }>(event)
417
+ return { user: session.data.user }
418
+ })
419
+ ```
420
+
421
+ Passing a `password` of at least 32 characters still seals with that instead.
422
+
423
+ To keep h3's implementation, import it explicitly:
424
+
425
+ ```diff [server/api/me.ts]
426
+ + import { useSession } from 'nitro/h3'
427
+
428
+ export default defineEventHandler(async (event) => {
429
+ const session = await useSession(event, { password: process.env.NUXT_SESSION_PASSWORD! })
430
+ return { user: session.data.user }
431
+ })
432
+ ```
433
+
434
+ #### Migration Steps
435
+
436
+ 1. Plan for existing sessions ending: users are signed out once, on the deploy that upgrades them.
437
+ 2. Where you relied on h3-specific options (`sessionHeader`, `crypto`, `seal`), either import `useSession` from `nitro/h3` or move to the `nuxt/server` equivalents: `name`, `maxAge` and `cookie`.
438
+ 3. Set `NUXT_APP_SECRET` in every deployed environment if you drop `password`; in development Nuxt generates one.
439
+ 4. Set the cookie name to `h3` only if you also keep h3's helpers; the two implementations should not share a cookie.
440
+
441
+ ::read-more{to="/docs/guide/going-further/server-imports#sessions"}
442
+ Learn what the session helpers cover.
443
+ ::
444
+
399
445
  ### Migration to Nitro v3
400
446
 
401
447
  🚦 **Impact Level**: Significant
@@ -35,7 +35,7 @@ Public runtime config is accessible in Vue templates with `$config.public`.
35
35
 
36
36
  ### Application Secret
37
37
 
38
- Nuxt provides a private `runtimeConfig.appSecret` as the application's root secret. Modules and server features can use it to derive their own secrets. The value defaults to an empty string, is only available on the server, and you can set it with `NUXT_APP_SECRET` without declaring the key in `nuxt.config`.
38
+ Nuxt provides a private `runtimeConfig.appSecret` as the application's root secret. Modules and server features derive their own secrets from it with [`deriveSecret`](/docs/guide/going-further/server-imports#deriving-secrets), and the [session helpers](/docs/guide/going-further/server-imports#sessions) seal with one by default. The value defaults to an empty string, is only available on the server, and you can set it with `NUXT_APP_SECRET` without declaring the key in `nuxt.config`.
39
39
 
40
40
  Generate a secret that contains at least 32 random bytes:
41
41
 
@@ -42,11 +42,13 @@ This code can run under `@nuxt/nitro-server` and under `@nuxt/vite-server`, and
42
42
  | `setResponseStatus` | Set the response status and reason phrase. |
43
43
  | `setResponseHeader`, `setResponseHeaders` | Set response headers. |
44
44
  | `sendRedirect` | Redirect the request. |
45
+ | `useSession`, `getSession`, `updateSession`, `clearSession` | Read and write a [sealed session cookie](#sessions). |
46
+ | `deriveSecret` | A purpose-specific secret [derived from `appSecret`](#deriving-secrets). |
45
47
  | `getRouteRules` | The [route rules](/docs/guide/concepts/rendering#route-rules) matched for the request. |
46
48
  | `useRuntimeConfig` | The server's [runtime configuration](/docs/guide/going-further/runtime-config). |
47
49
  | `toNuxtRequestEvent` | The event in the shape the server runtime provides. |
48
50
 
49
- Types are exported alongside the utilities: `RequestEvent`, `RequestEventContext`, `NuxtRequestEvent`, `EventHandler`, `AppRouteRules`, `ServerRoutes`, `NuxtError`, `NuxtErrorDetails`, `NuxtErrorJSON` and `NuxtErrorLike`.
51
+ Types are exported alongside the utilities: `RequestEvent`, `RequestEventContext`, `NuxtRequestEvent`, `EventHandler`, `AppRouteRules`, `ServerRoutes`, `NuxtError`, `NuxtErrorDetails`, `NuxtErrorJSON`, `NuxtErrorLike`, `Session`, `SessionConfig`, `SessionData`, `SessionEvent`, `SessionManager`, `SessionPassword` and `SessionUpdate`.
50
52
 
51
53
  These names are [auto-imported](/docs/directory-structure/server) in server code, so the import statement above is optional. Writing it keeps the file working in a project with server auto-imports off, and is what a module should do.
52
54
 
@@ -78,6 +80,44 @@ export default defineEventHandler(async (event) => {
78
80
 
79
81
  `NuxtRequestEvent` is the same request in the shape the configured builder provides, which is h3's `H3Event` under `@nuxt/nitro-server`. You can get a type-safe version of the event for the server builder you're using by calling `toNuxtRequestEvent(event)`.
80
82
 
83
+ ## Sessions
84
+
85
+ `useSession` reads the session for the request, sealing a new one into a cookie when there is none to read. The data is sealed with [iron](https://github.com/brc-dd/iron-webcrypto), so it lives in the cookie rather than in server storage, and the cookie defaults to `httpOnly`, `secure`, `sameSite: 'lax'` and `path: '/'`.
86
+
87
+ ```ts [server/api/visits.ts]
88
+ import { defineEventHandler, useSession } from 'nuxt/server'
89
+
90
+ export default defineEventHandler(async (event) => {
91
+ const session = await useSession<{ visits: number }>(event)
92
+ await session.update(data => ({ visits: (data.visits ?? 0) + 1 }))
93
+ return { visits: session.data.visits }
94
+ })
95
+ ```
96
+
97
+ With no `password`, the session is sealed with a secret derived from the application's [`appSecret`](/docs/guide/going-further/runtime-config#application-secret), so `NUXT_APP_SECRET` is the only thing to set. Pass a `password` of at least 32 characters to seal with a secret of your own instead. Set `maxAge` (in seconds) to expire both the cookie and the sealed value, `name` to change the cookie name from `nuxt-session`, and `cookie` to override any cookie attribute.
98
+
99
+ The session is unsealed once per request, so `getSession` may be called from as many places as you like. `updateSession` and `clearSession` are the same operations without the manager object.
100
+
101
+ ### Deriving Secrets
102
+
103
+ `deriveSecret(purpose)` resolves a secret for one purpose from `appSecret`: 32 bytes, hex-encoded, stable for as long as `appSecret` is unchanged, and distinct for every purpose. It is what the session helpers use, and what a module should use in place of asking for a secret of its own. Namespace the purpose to what owns it.
104
+
105
+ ```ts
106
+ import { deriveSecret } from 'nuxt/server'
107
+
108
+ const password = await deriveSecret('my-module:tokens')
109
+ ```
110
+
111
+ It throws a `500` naming `NUXT_APP_SECRET` when `appSecret` is unset or shorter than 32 characters.
112
+
113
+ ::note
114
+ h3 ships session helpers of the same names, reachable as `import { useSession } from 'nitro/h3'`. They are a separate implementation and are not interchangeable with these: they default to the `h3` cookie name rather than `nuxt-session`, take their own configuration, and a session one of them issues will not unseal with the other.
115
+ ::
116
+
117
+ ::warning
118
+ The session travels in the cookie, so it is limited to what a browser will accept. Writing a session that serialises to more than 4096 bytes throws; keep large data server-side and reference it from the session by id.
119
+ ::
120
+
81
121
  ## Reaching Past the Surface
82
122
 
83
123
  `nuxt/server` isn't a re-export of h3, so if you need something else that h3 and Nitro offer, such as the server lifecycle (`definePlugin`, `defineErrorHandler` and the Nitro app hooks), you would import it directly.
@@ -94,7 +134,7 @@ export default defineEventHandler(async (event) => {
94
134
  })
95
135
  ```
96
136
 
97
- That works for any h3 helper that only reads the request: `readValidatedBody`, `getValidatedQuery`, `getRouterParam`, `getRouterParams`, `getRequestIP`, `assertMethod`, and the session helpers (`useSession`, `getSession`, `updateSession`, `clearSession`).
137
+ That works for any h3 helper that only reads the request: `readValidatedBody`, `getValidatedQuery`, `getRouterParam`, `getRouterParams`, `getRequestIP` and `assertMethod`.
98
138
 
99
139
  A helper that needs the runtime's own event gets it from `toNuxtRequestEvent`:
100
140
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nuxt/docs-nightly",
3
- "version": "5.0.0-29824817.35cc2cb5",
3
+ "version": "5.0.0-29824891.6f2fc18e",
4
4
  "repository": {
5
5
  "type": "git",
6
6
  "url": "git+https://github.com/nuxt/nuxt.git",