Skip to content
Merged
Show file tree
Hide file tree
Changes from 4 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
66 changes: 66 additions & 0 deletions src/content/docs/en/guides/upgrade-to/v6.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,8 @@
- [generating routes with `RouteData`](#removed-routedatagenerate-adapter-api)
- [routes with percent-encoded percent signs (e.g. `%25`)](#removed-percent-encoding-in-routes)
- [`astro:ssr-manifest` virtual module](#removed-astrossr-manifest-virtual-module-integration-api)
- [`NodeApp` from `astro/app/node`](#deprecated-nodeapp-from-astroappnode-adapter-api)
- [`loadManifest()` and `loadApp()` from `astro/app/node`](#deprecated-loadmanifest-and-loadapp-from-astroappnode-adapter-api)

### Zod 4

Expand Down Expand Up @@ -374,6 +376,70 @@

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

### Deprecated: `NodeApp` from `astro/app/node` (Adapter API)

<SourcePR number="15535" title="feat: deprecate NodeApp" />

In Astro 5.x, adapters could implement their server entrypoint using `App` for standard web requests/responses, or `NodeApp` for node requests/responses.

Astro 6.0 deprecates `NodeApp` in favor of `createApp()` and new utilities: `createRequest()` and `writeResponse()`. This allows a more consistent API while preserving the same features as before. It also deprecates the `NodeAppHeadersJson` type.

#### What should I do?

If you have built an adapter, update any usage of `NodeApp` with `createApp()`:

```js title="my-adapter/server.js" del={1-12} ins={13-22}
import { NodeApp } from 'astro/app/node';

export function createExports(manifest) {
const app = new NodeApp(manifest);

const handler = async (req, res) => {
const response = await app.render(req);
await NodeApp.writeResponse(response, res);
};

return { handler };
}
import { createApp } from 'astro/app/entrypoint';
import { createRequest, writeResponse } from 'astro/app/node';

const app = createApp();

export const handler = async (req, res) => {
const request = createRequest(req);
const response = await app.render(request);
await writeResponse(response, res);
}
```

<ReadMore>Learn more about [the `astro/app/node` module](/en/reference/adapter-reference/#astroappnode).</ReadMore>

### Deprecated: `loadManifest()` and `loadApp()` from `astro/app/node` (Adapter API)

<SourcePR number="15535" title="feat: deprecate NodeApp" />

In Astro 5.x, the `astro/app/node` exposed `loadManifest()` and `loadApp()` utilities to allow loading the SSR manifest or a `NodeApp` instance from a `URL` instance. However, these were not documented and are no longer recommended usage with the v6 Adapter API.

Astro 6.0 deprecates both functions.

#### What should I do?

If you have built an adapter, remove `loadManifest()` and replace `loadApp()` by `createApp()`:

```js title="my-adapter/server.js" del={1-5} ins={6-8}
import { loadManifest, loadApp, NodeApp } from 'astro/app/node';

const manifest = await loadManifest(new URL(import.meta.url));
const app1 = new NodeApp(loadManifest);
const app2 = await loadApp(new URL(import.meta.url));
import { createApp } from 'astro/app/entrypoint';

const app = createApp();
```

<ReadMore>Learn more about [the `astro/app/entrypoint` module](/en/reference/adapter-reference/#astroappentrypoint).</ReadMore>

Check failure on line 441 in src/content/docs/en/guides/upgrade-to/v6.mdx

View workflow job for this annotation

GitHub Actions / Check Links

Broken fragment link in src/content/docs/en/guides/upgrade-to/v6.mdx, line 441: The linked page does not contain a fragment with the name "#astroappentrypoint". Available fragments: #theme-icons, #gradient, #starlight__sidebar, #__tab-start, #__tab-guides-and-recipes, #__tab-reference, #__tab-integrations, #__tab-third-party-services, #starlight__mobile-toc, #starlight__on-this-page--mobile, #starlight__on-this-page, #learn-astro-course-2, #_top, #what-is-an-adapter, #building-an-adapter, #name, #serverentrypoint, #supportedastrofeatures, #adapterfeatures, #args, #client, #internalfetchheaders, #assetqueryparams, #exports, #previewentrypoint, #entrytype, #custom-prerenderer, #building-a-server-entrypoint, #createexports, #start, #astroapp, #apprender, #renderoptions, #addcookieheader, #clientaddress, #locals, #prerenderederrorpagefetch, #routedata, #appmatch, #appgetadapterlogger, #appgetalloweddomains, #appremovebase, #appsetcookieheaders, #appgetsetcookiefromresponse, #appvalidateforwardedhost, #appsanitizehost, #appvalidateforwardedheaders, #astroappnode, #createrequest, #writeresponse, #astro-features, #staticoutput, #hybridoutput, #serveroutput, #i18ndomains, #envgetsecret, #sharpimageservice, #adapter-features, #edgemiddleware, #buildoutput, #staticheaders, #adapter-types-reference, #adaptersupport, #adaptersupportskind, #adaptersupportwithmessage, #support, #message, #suppress, #allow-installation-via-astro-add, #docsearch-lvl0, #learn-astro-course-1
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Depends on #13253


## 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
100 changes: 10 additions & 90 deletions src/content/docs/en/reference/adapter-reference.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -770,130 +770,50 @@ export function start(manifest) {

### `astro/app/node`

Just like [`astro/app`](#astroapp), this module is used for rendering pages that have been prebuilt through `astro build`. This allows you to create a `NodeApp` providing all the methods available from `App` and additional methods useful for Node environments.
This module is used in conjunction with [`astro/app`](#astroapp) to convert a NodeJS `IncomingMessage` into a web-standard `Request` and stream a web-standard `Response` into a NodeJS `ServerResponse`.

The `NodeApp` constructor accepts a required SSR manifest argument, and optionally an argument to enable or disable streaming, defaulting to `true`.

```js
import { NodeApp } from 'astro/app/node';
import http from 'http';

export function start(manifest) {
const nodeApp = new NodeApp(manifest);

addEventListener('fetch', event => {
event.respondWith(
nodeApp.render(event.request)
);
});
}
```

The following additional methods are provided:

#### `nodeApp.render()`

<p>

**Type:** `(request: NodeRequest | Request, options?: RenderOptions) => Promise<Response>`<br />
<Since v="4.0.0" />
</p>

Extends [`app.render()`](#apprender) to also accept [Node.js `IncomingMessage`](https://nodejs.org/api/http.html#class-httpincomingmessage) objects in addition to standard `Request` objects as the first argument. The second argument is an optional object allowing you to [control the rendering](#renderoptions).

```js
const response = await nodeApp.render(request);
```

#### `nodeApp.match()`

<p>

**Type:** `(req: NodeRequest | Request, allowPrerenderedRoutes?: boolean) => RouteData | undefined`
</p>

Extends [`app.match()`](#appmatch) to also accept [Node.js `IncomingMessage`](https://nodejs.org/api/http.html#class-httpincomingmessage) objects in addition to standard `Request` objects.

```js
if(nodeApp.match(request)) {
const response = await nodeApp.render(request);
}
```

#### `nodeApp.headersMap`

<p>

**Type:** `NodeAppHeadersJson | undefined`<br />
**Default:** `undefined`<br />
<Since v="5.11.0" />
</p>

An array containing the headers configuration. Each entry maps a pathname to a list of headers that should be applied for that route. This is useful for applying headers such as CSP directives to prerendered routes.

#### `nodeApp.setHeadersMap()`

<p>

**Type:** `(headers: NodeAppHeadersJson) => void`<br />
<Since v="5.11.0" />
</p>

Loads [headers configuration](#nodeappheadersmap) into the `NodeApp` instance.

```js
nodeApp.setHeadersMap([
{
pathname: "/blog",
headers: [
{ key: "Content-Security-Policy", value: "default-src 'self'" },
]
}
]);
```

#### `NodeApp.createRequest()`
#### `createRequest()`

<p>

**Type:** `(req: NodeRequest, options?: { skipBody?: boolean; allowedDomains?: Partial<RemotePattern>[]; }) => Request`<br />
<Since v="4.2.0" />
<Since v="6.0.0" />
</p>

Converts a NodeJS `IncomingMessage` into a standard `Request` object. This static method accepts an optional object as the second argument, allowing you to define if the body should be ignored, defaulting to `false`, and the [`allowedDomains`](/en/reference/configuration-reference/#securityalloweddomains).

The following example creates a `Request` and passes it to `app.render()`:

```js {5}
import { NodeApp } from 'astro/app/node';
import { createRequest } from 'astro/app/node';
import { createServer } from 'node:http';

const server = createServer(async (req, res) => {
const request = NodeApp.createRequest(req);
const request = createRequest(req);
const response = await app.render(request);
})
```

#### `NodeApp.writeResponse()`
#### `writeResponse()`

<p>

**Type:** `(source: Response, destination: ServerResponse) => Promise<ServerResponse<IncomingMessage> | undefined>`<br />
<Since v="4.2.0" />
<Since v="6.0.0" />
</p>

Streams a web-standard `Response` into a NodeJS server response. This static method takes a `Response` object and the initial `ServerResponse` before returning a promise of a `ServerResponse` object.

The following example creates a `Request`, passes it to `app.render()`, and writes the response:

```js {7}
import { NodeApp } from 'astro/app/node';
import { createRequest, writeResponse } from 'astro/app/node';
import { createServer } from 'node:http';

const server = createServer(async (req, res) => {
const request = NodeApp.createRequest(req);
const request = createRequest(req);
const response = await app.render(request);
await NodeApp.writeResponse(response, res);
await writeResponse(response, res);
})
```

Expand Down
Loading