跳到內容

Adapter Server Entrypoint API Reference

本頁內容尚未翻譯。

This module helps adapter authors build a server entrypoint while supporting pages rendered in development mode or that have been prebuilt through astro build.

astro/app is used internally for Astro’s official server adapters, and is also publicly available for you to build a custom adapter for your specific runtime or deploy host.

Astro uses the standard Request and Response objects. Hosts using a different API for requests/responses should convert to these types in their adapter. For example, Astro exposes helpers to work with NodeJS.

The following helpers are imported from the entrypoint directory in the app module:

import {
createApp
} from "astro/app/entrypoint";

Type: (options?: { streaming: boolean }) => App

新增於: astro@6.0.0 Beta

Returns an App instance that includes methods to work with standard Request and Response objects when building an adapter’s server entrypoint.

import { createApp } from "astro/app/entrypoint";
import http from "http";
const app = createApp();
addEventListener("fetch", event => {
event.respondWith(
app.render(event.request)
);
});

The createApp() function accepts the following options.

Type: boolean
Default: true

Defines whether HTML streaming is enabled. In most cases, disabling streaming is not recommended as it improves performance and generally provides a better visitor experience.

HTML streaming breaks a document into chunks to send over the network and render on the page in order. This normally results in visitors seeing your HTML as fast as possible, but factors such as network conditions and waiting for data fetches can block page rendering.

However, when you need to disable HTML streaming (e.g. your host only supports non-streamed HTML caching at the CDN level), you can opt out of the default behavior by passing streaming: false to createApp():

import { createApp } from 'astro/app/entrypoint'
const app = createApp({ streaming: false })

The createApp() function returns a class instance with the following methods.

Type: (request: Request, options?: RenderOptions) => Promise<Response>

Calls the Astro page that matches the Request, renders it, and returns a promise to a Response object. This also works for API routes that do not render pages.

const response = await app.render(request);

Type: (request: Request, allowPrerenderedRoutes = false) => RouteData | undefined

Determines whether a request is matched by the Astro app’s routing rules.

if(app.match(request)) {
const response = await app.render(request);
}

You can usually call app.render(request) without using .match because Astro handles 404s if you provide a 404.astro file. Use app.match(request) if you want to handle 404s in a different way.

By default, prerendered routes aren’t returned, even if they are matched. You can change this behavior by using true as the second argument.

Type: () => AstroIntegrationLogger

新增於: astro@v3.0.0

Returns an instance of the Astro logger available to the adapter’s runtime environment.

const logger = app.getAdapterLogger();
try {
/* Some logic that can throw */
} catch {
logger.error("Your custom error message using Astro logger.");
}

Type: () => Partial<RemotePattern>[] | undefined

新增於: astro@5.14.2

Returns a list of permitted host patterns for incoming requests when using on-demand rendering as configured in security.allowedDomains.

Type: (pathname: string) => string

新增於: astro@1.6.4

Removes the base from the given path. This is useful when you need to look up assets from the filesystem.

Type: (response: Response) => Generator<string, string[], any>

新增於: astro@1.4.0

Returns a generator that yields individual cookie header values from a Response object. This is used to properly handle multiple cookies that may have been set during request processing.

The following example appends a Set-Cookie header for each header obtained from a response:

for (const setCookieHeader of app.setCookieHeaders(response)) {
response.headers.append('Set-Cookie', setCookieHeader);
}

The following helpers are imported from the node directory in the app module:

import {
createRequest,
writeResponse
} from "astro/app/node";

This module is used in conjunction with the methods provided by createApp() to convert a NodeJS IncomingMessage into a web-standard Request and stream a web-standard Response into a NodeJS ServerResponse.

Type: (req: NodeRequest, options?: { skipBody?: boolean; allowedDomains?: Partial<RemotePattern>[]; }) => Request

新增於: astro@6.0.0 Beta

Converts a NodeJS IncomingMessage into a standard Request object. An optional object can be passed as a second argument to further control how the request is created. This is useful if you want to ignore the body (defaults to false) or pass the configured allowedDomains to the request.

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

import { createApp } from "astro/app/entrypoint";
import { createRequest } from "astro/app/node";
import { createServer } from "node:http";
const app = createApp();
const server = createServer(async (req, res) => {
const request = createRequest(req);
const response = await app.render(request);
})

Type: (source: Response, destination: ServerResponse) => Promise<ServerResponse<IncomingMessage> | undefined>

新增於: astro@6.0.0 Beta

Streams a web-standard Response into a NodeJS server response. This function 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:

import { createApp } from "astro/app/entrypoint";
import { createRequest, writeResponse } from "astro/app/node";
import { createServer } from "node:http";
const app = createApp();
const server = createServer(async (req, res) => {
const request = createRequest(req);
const response = await app.render(request);
await writeResponse(response, res);
})

The following types are imported from the app module:

import type {
RenderOptions,
} from "astro/app";

Type: {addCookieHeader?: boolean; clientAddress?: string; locals?: object; prerenderedErrorPageFetch?: (url: ErrorPagePath) => Promise<Response>; routeData?: RouteData;}

Describes the options for controlling the routes rendering.

Type: boolean
Default: false

Whether or not to automatically add all cookies written by Astro.cookie.set() to the response headers.

When set to true, they will be added to the Set-Cookie header of the response as comma-separated key-value pairs. You can use the standard response.headers.getSetCookie() API to read them individually.

const response = await app.render(request, { addCookieHeader: true });

Type: string
Default: request[Symbol.for("astro.clientAddress")]

The client IP address that will be made available as Astro.clientAddress in pages, and as ctx.clientAddress in API routes and middleware.

The example below reads the x-forwarded-for header and passes it as clientAddress. This value becomes available to the user as Astro.clientAddress.

const clientAddress = request.headers.get("x-forwarded-for");
const response = await app.render(request, { clientAddress });

Type: object

The context.locals object used to store and access information during the lifecycle of a request.

The example below reads a header named x-private-header, attempts to parse it as an object, and passes it to locals, which can then be passed to any middleware function.

const privateHeader = request.headers.get("x-private-header");
let locals = {};
try {
if (privateHeader) {
locals = JSON.parse(privateHeader);
}
} finally {
const response = await app.render(request, { locals });
}

Type: (url: ErrorPagePath) => Promise<Response>
Default: fetch

新增於: astro@5.6.0

A function that allows you to provide custom implementations for fetching prerendered error pages.

This is used to override the default fetch() behavior, for example, when fetch() is unavailable or when you cannot call the server from itself.

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

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");
return new Response(content, {
status: 404,
headers: { "Content-Type": "text/html" },
});
}
});

If not provided, Astro will fallback to its default behavior for fetching error pages.

Type: RouteData
Default: app.match(request)

Defines the information about a route. This is useful when you already know the route to render. Doing so will bypass the internal call to app.match() to determine the route to render.

const routeData = app.match(request);
if (routeData) {
return app.render(request, { routeData });
} else {
/* adapter-specific 404 response */
return new Response(..., { status: 404 });
}
貢獻 社群 贊助