Skip to content

Commit

Permalink
fix(runtime): check head+content component before throwing an error (#…
Browse files Browse the repository at this point in the history
…11141)

* fix(runtime): check head+content component before throwing an error

* add test
  • Loading branch information
ematipico authored May 29, 2024
1 parent 6b97634 commit 19df89f
Show file tree
Hide file tree
Showing 3 changed files with 83 additions and 1 deletion.
13 changes: 13 additions & 0 deletions .changeset/silver-bananas-move.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
---
"astro": patch
---

Fixes an internal error that prevented the `AstroContainer` to render the `Content` component.

You can now write code similar to the following to render content collections:

```js
const entry = await getEntry(collection, slug);
const { Content } = await entry.render();
const content = await container.renderToString(Content);
```
21 changes: 20 additions & 1 deletion packages/astro/src/runtime/server/render/astro/render.ts
Original file line number Diff line number Diff line change
Expand Up @@ -148,6 +148,25 @@ async function callComponentAsTemplateResultOrResponse(

if (factoryResult instanceof Response) {
return factoryResult;
}
// we check if the component we attempt to render is a head+content
else if (isHeadAndContent(factoryResult)) {
// we make sure that content is valid template result
if (!isRenderTemplateResult(factoryResult.content)) {
throw new AstroError({
...AstroErrorData.OnlyResponseCanBeReturned,
message: AstroErrorData.OnlyResponseCanBeReturned.message(
route?.route,
typeof factoryResult
),
location: {
file: route?.component,
},
});
}

// return the content
return factoryResult.content;
} else if (!isRenderTemplateResult(factoryResult)) {
throw new AstroError({
...AstroErrorData.OnlyResponseCanBeReturned,
Expand All @@ -158,7 +177,7 @@ async function callComponentAsTemplateResultOrResponse(
});
}

return isHeadAndContent(factoryResult) ? factoryResult.content : factoryResult;
return factoryResult;
}

// Recursively calls component instances that might have head content
Expand Down
50 changes: 50 additions & 0 deletions packages/astro/test/container.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ import {
renderComponent,
renderHead,
renderSlot,
createHeadAndContent,
renderTemplate
} from '../dist/runtime/server/index.js';

const BaseLayout = createComponent((result, _props, slots) => {
Expand Down Expand Up @@ -140,6 +142,54 @@ describe('Container', () => {
assert.match(result, /Bar name/);
});

it('Renders content and head component', async () => {
const Page = createComponent(
(result, _props, slots) => {

return createHeadAndContent(
'',
renderTemplate`${renderComponent(
result,
'BaseLayout',
BaseLayout,
{},
{
default: () => render`
${maybeRenderHead(result)}
${renderSlot(result, slots['custom-name'])}
${renderSlot(result, slots['foo-name'])}
`,
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, {
slots: {
'custom-name': 'Custom name',
'foo-name': 'Bar name',
},
});

assert.match(result, /Custom name/);
assert.match(result, /Bar name/);
});

it('Renders props', async () => {
const Page = createComponent(
(result, props, _slots) => {
Expand Down

0 comments on commit 19df89f

Please sign in to comment.