返回介绍

Astro Container API (experimental)

发布于 2024-06-05 21:19:57 字数 10902 浏览 0 评论 0 收藏 0

添加于: astro@4.9.0

The Container API allows you to render Astro components in isolation.

This experimental server-side API unlocks a variety of potential future uses, but is currently scoped to allow testing of .astro component output. This API allows you to create a new container, and render an Astro component returning a string or a Response.

This API is experimental and subject to breaking changes, even in minor or patch releases. Please consult the Astro CHANGELOG for changes as they occur. This page will always be updated with the most current information for the latest version of Astro.

create()

Section titled create()

Creates a new instance of the container.

import { experimental_AstroContainer } from "astro/container";


const container = await experimental_AstroContainer.create();

It accepts an object with the following options:

export type AstroContainerOptions = {
  streaming?: boolean;
  renderers?: AstroRenderer[];
};

streaming option

Section titled streaming option

Type: boolean

Enables rendering components using HTML streaming.

renderers option

Section titled renderers option

Type: AstroRenderer[]

A list of client renderers required by the component. Use this if your .astro component renders any UI framework components using an official Astro integration (e.g. React, Vue, etc.). For each framework rendered, you must provide an object stating the integration package name, as well as both its client and server rendering script

The following example provides the necessary object to render an Astro component that renders a React component:

const container = await experimental_AstroContainer.create({
    renderers: [
      {
        name: "@astrojs/react",
        clientEntrypoint: "@astrojs/react/client.js",
        serverEntrypoint: "@astrojs/react/server.js"
      }
    ]
})
const result = await container.renderToString(ReactWrapper);

renderToString()

Section titled renderToString()

This function renders a specified component inside a container. It takes an Astro component as an argument and it returns a string that represents the HTML/content rendered by the Astro component.

import { experimental_AstroContainer } from "astro/container";
import Card from "../src/components/Card.astro";


const container = await experimental_AstroContainer.create();
const result = await container.renderToString(Card);

Under the hood, this function calls renderToResponse and calls Response.text().

It also accepts an object as a second argument that can contain a number of options.

renderToResponse()

Section titled renderToResponse()

It renders a component, and it returns a Response object.

import { experimental_AstroContainer } from "astro/container";
import Card from "../src/components/Card.astro";


const container = await experimental_AstroContainer.create();
const result = await container.renderToResponse(Card);

It also accepts an object as a second argument that can contain a number of options.

Rendering options

Section titled Rendering options

Both renderToResponse and renderToString accept an object as their second argument:

export type ContainerRenderOptions = {
  slots?: Record<string, any>;
  request?: Request;
  params?: Record<string, string | undefined>;
  locals?: App.Locals;
  routeType?: "page" | "endpoint";


};

These optional values can be passed to the rendering function in order to provide additional information necessary for an Astro component to properly render.

slots

Section titled slots

Type: Record<string, any>;

An option to pass content to be rendered with <slots>.

If your Astro component renders one default slot, pass an object with default as the key:

import Card from "../src/components/Card.astro";


const result = await container.renderToString(Card, {
  slots: { default: "Some value"}
});

If your component renders named slots, use the slot names as the object keys:

---
---
<div>
  <slot name="header" />
  <slot name="footer" />
</div>
import Card from "../src/components/Card.astro";


const result = await container.renderToString(Card, {
  slots: { "header": "Header content", "footer": "Footer" }
});

You can also render components in cascade:

---
---
<div>
  <slot name="header" />
  <slot name="footer" />
</div>
import Card from "../src/components/Card.astro";
import CardHeader from "../src/components/CardHeader.astro";
import CardFooter from "../src/components/CardFooter.astro";


const result = await container.renderToString(Card, {
  slots: {
    "header": await container.renderToString(CardHeader),
    "footer":  await container.renderToString(CardFooter),
  }
});

request option

Section titled request option

Type: Request

An option to pass a Request with information about the path/URL the component will render.

Use this option when your component needs to read information like Astro.url or Astro.request.

You can also inject possible headers or cookies.

import Card from "../src/components/Card.astro";


const result = await container.renderToString(Card, {
  request: new Request("https://example.com/blog", {
    headers: {
      "X-some-secret-header": "test-value"
    }
  })
});

params option

Section titled params option

Type: Record<string, string | undefined>;

An object to pass information about the path parameter to an Astro component responsible for generating dynamic routes.

Use this option when your component needs a value for Astro.params in order to generate a single route dynamically.

---
const { locale, slug } = Astro.params;
---
<div></div>
import LocaleSlug from "../src/components/[locale]/[slug].astro";


const result = await container.renderToString(LocaleSlug, {
  params: {
    locale: "en",
    slug: "getting-started"
  }
});

locals options

Section titled locals options

Type: App.Locals

An option to pass information from Astro.locals for rendering your component.

Use this option to when your component needs information stored during the lifecycle of a request in order to render, such as logged in status.

---
const { checkAuth } = Astro.locals;
const isAuthenticated = checkAuth();
---
{isAuthenticated ? <span>You're in</span> : <span>You're out</span> }
import Card from "../src/components/Card.astro";


test("User is in", async () => {
  const result = await container.renderToString(Card, {
    locals: {
      checkAuth() { return true }
    }
  });


  // assert result contains "You're in"
})




test("User is out", async () => {
  const result = await container.renderToString(Card, {
    locals: {
      checkAuth() { return false }
    }
  });


  // assert result contains "You're out"
})

routeType option

Section titled routeType option

Type: "page" | "endpoint"

An option available when using renderToResponse to specify that you are rendering an endpoint:

container.renderToString(Endpoint, { routeType: "endpoint" });
import * as Endpoint from "../src/pages/api/endpoint.js";


const response = await container.renderToResponse(Endpoint, {
  routeType: "endpoint"
});
const json = await response.json();

To test your endpoint on methods such as POST, PATCH, etc., use the request option to call the correct function:

export function GET() {}


// need to test this
export function POST() {}
import * as Endpoint from "../src/pages/api/endpoint.js";


const response = await container.renderToResponse(Endpoint, {
    routeType: "endpoint",    request: new Request("https://example.com", {      method: "POST" //    })
});
const json = await response.json();
Reference

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文