diff options
author | 2024-05-24 14:41:56 +0100 | |
---|---|---|
committer | 2024-05-24 14:41:56 +0100 | |
commit | 98e0372cfd47a3e025be2ac68d1e9ebf06cf548b (patch) | |
tree | 12fa392c7c98cb54254c97b68349af45ce1473b8 | |
parent | aaf0635cc0fb7e9f892c710ec6ff3b16d3f90ab4 (diff) | |
download | astro-98e0372cfd47a3e025be2ac68d1e9ebf06cf548b.tar.gz astro-98e0372cfd47a3e025be2ac68d1e9ebf06cf548b.tar.zst astro-98e0372cfd47a3e025be2ac68d1e9ebf06cf548b.zip |
feat: pass props to container (#11138)
-rw-r--r-- | .changeset/thirty-dots-end.md | 17 | ||||
-rw-r--r-- | packages/astro/src/container/index.ts | 14 | ||||
-rw-r--r-- | packages/astro/src/core/render-context.ts | 7 | ||||
-rw-r--r-- | packages/astro/test/container.test.js | 42 |
4 files changed, 76 insertions, 4 deletions
diff --git a/.changeset/thirty-dots-end.md b/.changeset/thirty-dots-end.md new file mode 100644 index 000000000..399d0dc81 --- /dev/null +++ b/.changeset/thirty-dots-end.md @@ -0,0 +1,17 @@ +--- +"astro": patch +--- + +You can now pass `props` when rendering a component using the Container APIs: + +```js +import { experimental_AstroContainer as AstroContainer } from "astro/contaienr"; +import Card from "../src/components/Card.astro"; + +const container = await AstroContainer.create(); +const result = await container.renderToString(Card, { + props: { + someState: true + } +}); +``` diff --git a/packages/astro/src/container/index.ts b/packages/astro/src/container/index.ts index 82859799b..824bc96a4 100644 --- a/packages/astro/src/container/index.ts +++ b/packages/astro/src/container/index.ts @@ -3,7 +3,7 @@ import type { AstroRenderer, AstroUserConfig, ComponentInstance, - MiddlewareHandler, + MiddlewareHandler, Props, RouteData, RouteType, SSRLoadedRenderer, @@ -70,6 +70,15 @@ export type ContainerRenderOptions = { * ``` */ routeType?: RouteType; + + /** + * Allows to pass `Astro.props` to an Astro component: + * + * ```js + * container.renderToString(Endpoint, { props: { "lorem": "ipsum" } }); + * ``` + */ + props?: Props }; function createManifest( @@ -369,6 +378,9 @@ export class experimental_AstroContainer { if (options.params) { renderContext.params = options.params; } + if (options.props) { + renderContext.props = options.props; + } return renderContext.render(componentInstance, slots); } diff --git a/packages/astro/src/core/render-context.ts b/packages/astro/src/core/render-context.ts index 27eebc632..307a3f240 100644 --- a/packages/astro/src/core/render-context.ts +++ b/packages/astro/src/core/render-context.ts @@ -3,7 +3,7 @@ import type { AstroGlobal, AstroGlobalPartial, ComponentInstance, - MiddlewareHandler, + MiddlewareHandler, Props, RewritePayload, RouteData, SSRResult, @@ -47,7 +47,8 @@ export class RenderContext { public status: number, protected cookies = new AstroCookies(request), public params = getParams(routeData, pathname), - protected url = new URL(request.url) + protected url = new URL(request.url), + public props: Props = {} ) {} /** @@ -97,7 +98,7 @@ export class RenderContext { ): Promise<Response> { const { cookies, middleware, pathname, pipeline } = this; const { logger, routeCache, serverLike, streaming } = pipeline; - const props = await getProps({ + const props = Object.keys(this.props).length > 0 ? this.props : await getProps({ mod: componentInstance, routeData: this.routeData, routeCache, diff --git a/packages/astro/test/container.test.js b/packages/astro/test/container.test.js index 228844e70..6704aa03f 100644 --- a/packages/astro/test/container.test.js +++ b/packages/astro/test/container.test.js @@ -139,4 +139,46 @@ describe('Container', () => { assert.match(result, /Custom name/); assert.match(result, /Bar name/); }); + + + it('Renders props', async () => { + const Page = createComponent( + (result, props, _slots) => { + return render`${renderComponent( + result, + 'BaseLayout', + BaseLayout, + {}, + { + default: () => render` + ${maybeRenderHead(result)} + ${props.isOpen ? "Is open" : "Is closed"} + `, + head: () => render` + ${renderComponent( + result, + 'Fragment', + Fragment, + { slot: 'head' }, + { + default: () => render`<meta charset="utf-8">`, + } + )} + `, + } + )}`; + }, + 'Component2.astro', + undefined + ); + + const container = await experimental_AstroContainer.create(); + const result = await container.renderToString(Page, { + props: { + isOpen: true + }, + }); + + assert.match(result, /Is open/); + }); }); |