summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGravatar Emanuele Stoppa <my.burning@gmail.com> 2024-05-24 14:41:56 +0100
committerGravatar GitHub <noreply@github.com> 2024-05-24 14:41:56 +0100
commit98e0372cfd47a3e025be2ac68d1e9ebf06cf548b (patch)
tree12fa392c7c98cb54254c97b68349af45ce1473b8
parentaaf0635cc0fb7e9f892c710ec6ff3b16d3f90ab4 (diff)
downloadastro-98e0372cfd47a3e025be2ac68d1e9ebf06cf548b.tar.gz
astro-98e0372cfd47a3e025be2ac68d1e9ebf06cf548b.tar.zst
astro-98e0372cfd47a3e025be2ac68d1e9ebf06cf548b.zip
feat: pass props to container (#11138)
-rw-r--r--.changeset/thirty-dots-end.md17
-rw-r--r--packages/astro/src/container/index.ts14
-rw-r--r--packages/astro/src/core/render-context.ts7
-rw-r--r--packages/astro/test/container.test.js42
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/);
+ });
});