Skip to content
Merged
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
89 changes: 45 additions & 44 deletions src/content/docs/en/reference/adapter-reference.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -166,7 +166,7 @@ export default function createIntegration() {
**Type:** `URLSearchParams`
</p>

Define the query parameters to append to all asset URLs (e.g. images, stylesheets, scripts, etc.). This is useful for adapters that need to track deployment versions or other metadata.
Defines the query parameters to append to all asset URLs (e.g. images, stylesheets, scripts). This is useful for adapters that need to track deployment versions or other metadata.

The following example retrieves a `DEPLOY_ID` from the environment variables and, if provided, returns an object with a custom search parameter name as key and the deploy id as value:

Expand Down Expand Up @@ -257,7 +257,7 @@ You will need to create a file that executes during server-side requests to enab
Type: `(manifest: SSRManifest, options: any) => Record<string, any>`
</p>

An exported function that takes an SSR manifest as its first argument and an object containing your adapter [args](#args) as its second argument. This should provide the exports required by your host.
An exported function that takes an SSR manifest as its first argument and an object containing your adapter [`args`](#args) as its second argument. This should provide the exports required by your host.

For example, some serverless hosts expect you to export an `handler()` function. With the adapter API, you achieve this by implementing `createExports()` in your server entrypoint:

Expand Down Expand Up @@ -317,9 +317,9 @@ export function createExports(manifest, args) {
Type: `(manifest: SSRManifest, options: any) => Record<string, any>`
</p>

An exported function that takes an SSR manifest as its first argument and an object containing your adapter [args](#args) as its second argument.
An exported function that takes an SSR manifest as its first argument and an object containing your adapter [`args`](#args) as its second argument.

Some hosts expect you to *start* the server yourselves, for example, by listening to a port. For these types of hosts, the adapter API allows you to export a `start` function, which will be called when the bundle script is run.
Some hosts expect you to *start* the server yourselves, for example, by listening to a port. For these types of hosts, the adapter API allows you to export a `start()` function, which will be called when the bundle script is run.

```js title="my-adapter/server.js"
import { App } from 'astro/app';
Expand All @@ -335,7 +335,7 @@ export function start(manifest) {

### `astro/app`

This module is used for rendering pages that have been prebuilt through `astro build`. Astro uses the standard [Request](https://developer.mozilla.org/en-US/docs/Web/API/Request) and [Response](https://developer.mozilla.org/en-US/docs/Web/API/Response) objects. Hosts that have a different API for request/response should convert to these types in their adapter.
This module is used for rendering pages that have been prebuilt through `astro build`. Astro uses the standard [`Request`](https://developer.mozilla.org/en-US/docs/Web/API/Request) and [`Response`](https://developer.mozilla.org/en-US/docs/Web/API/Response) objects. Hosts that have a different API for request/response should convert to these types in their adapter.

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

Expand Down Expand Up @@ -427,11 +427,11 @@ The example below reads a header named `x-private-header`, attempts to parse it
const privateHeader = request.headers.get("x-private-header");
let locals = {};
try {
if (privateHeader) {
locals = JSON.parse(privateHeader);
}
if (privateHeader) {
locals = JSON.parse(privateHeader);
}
} finally {
const response = await app.render(request, { locals });
const response = await app.render(request, { locals });
}
```

Expand All @@ -450,22 +450,23 @@ This is used to override the default `fetch()` behavior, for example, when `fetc

The following example reads `500.html` and `404.html` from disk instead of performing an HTTP call:

```js "prerenderedErrorPageFetch"
```ts "prerenderedErrorPageFetch"
return app.render(request, {
prerenderedErrorPageFetch: async (url: string): Promise<Response> => {
if (url.includes("/500")) {
const content = await fs.promises.readFile("500.html", "utf-8");
return new Response(content, {
status: 500,
headers: { "Content-Type": "text/html" },
});
}

const content = await fs.promises.readFile("404.html", "utf-8");
const content = await fs.promises.readFile("500.html", "utf-8");
return new Response(content, {
status: 404,
status: 500,
headers: { "Content-Type": "text/html" },
});
}

const content = await fs.promises.readFile("404.html", "utf-8");
return new Response(content, {
status: 404,
headers: { "Content-Type": "text/html" },
});
}
});
```

Expand All @@ -479,15 +480,15 @@ If not provided, Astro will fallback to its default behavior for fetching error
**Default:** `app.match(request)`
</p>

Provide a value for [`integrationRouteData`](/en/reference/integrations-reference/#integrationroutedata-type-reference) if you already know the route to render. Doing so will bypass the internal call to [`app.match`](#appmatch) to determine the route to render.
Provides a value for [`integrationRouteData`](/en/reference/integrations-reference/#integrationroutedata-type-reference) if you already know the route to render. Doing so will bypass the internal call to [`app.match()`](#appmatch) to determine the route to render.

```js "routeData"
const routeData = app.match(request);
if (routeData) {
return app.render(request, { routeData });
return app.render(request, { routeData });
} else {
/* adapter-specific 404 response */
return new Response(..., { status: 404 });
/* adapter-specific 404 response */
return new Response(..., { status: 404 });
}
```

Expand Down Expand Up @@ -748,7 +749,7 @@ nodeApp.setHeadersMap([

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`:
The following example creates a `Request` and passes it to `app.render()`:

```js {5}
import { NodeApp } from 'astro/app/node';
Expand All @@ -770,16 +771,16 @@ const server = createServer(async (req, res) => {

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:
The following example creates a `Request`, passes it to `app.render()`, and writes the response:

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

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

Expand Down Expand Up @@ -907,7 +908,7 @@ export default function createIntegration() {
name: '@example/my-adapter',
serverEntrypoint: '@example/my-adapter/server.js',
supportedAstroFeatures: {
envGetSecret: 'stable'
envGetSecret: 'stable'
}
});
},
Expand Down Expand Up @@ -944,21 +945,21 @@ import { setGetEnv } from 'astro/env/setup';
import { createGetEnv } from '../utils/env.js';

type Env = {
[key: string]: unknown;
[key: string]: unknown;
};

export function createExports(manifest: SSRManifest) {
const app = new App(manifest);
const app = new App(manifest);

const fetch = async (request: Request, env: Env) => {
setGetEnv(createGetEnv(env));
const fetch = async (request: Request, env: Env) => {
setGetEnv(createGetEnv(env));

const response = await app.render(request);
const response = await app.render(request);

return response;
};
return response;
};

return { default: { fetch } };
return { default: { fetch } };
}
```

Expand Down Expand Up @@ -997,7 +998,7 @@ export default function createIntegration() {
name: '@example/my-adapter',
serverEntrypoint: '@example/my-adapter/server.js',
adapterFeatures: {
edgeMiddleware: true
edgeMiddleware: true
}
});
},
Expand All @@ -1018,23 +1019,23 @@ export default function createIntegration() {
name: '@example/my-adapter',
serverEntrypoint: '@example/my-adapter/server.js',
adapterFeatures: {
edgeMiddleware: true
edgeMiddleware: true
}
});
},

'astro:build:ssr': ({ middlewareEntryPoint }) => {
// remember to check if this property exits, it will be `undefined` if the adapter doesn't opt in to the feature
if (middlewareEntryPoint) {
createEdgeMiddleware(middlewareEntryPoint)
}
// remember to check if this property exits, it will be `undefined` if the adapter doesn't opt in to the feature
if (middlewareEntryPoint) {
createEdgeMiddleware(middlewareEntryPoint)
}
}
},
};
}

function createEdgeMiddleware(middlewareEntryPoint) {
// emit a new physical file using your bundler
// emit a new physical file using your bundler
}
```

Expand Down