mirror of
https://github.com/withastro/astro.git
synced 2025-01-06 22:10:10 -05:00
fix(runtime): check head+content component before throwing an error (#11141)
* fix(runtime): check head+content component before throwing an error * add test
This commit is contained in:
parent
6b97634396
commit
19df89f87c
3 changed files with 83 additions and 1 deletions
13
.changeset/silver-bananas-move.md
Normal file
13
.changeset/silver-bananas-move.md
Normal file
|
@ -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);
|
||||
```
|
|
@ -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,
|
||||
|
@ -158,7 +177,7 @@ async function callComponentAsTemplateResultOrResponse(
|
|||
});
|
||||
}
|
||||
|
||||
return isHeadAndContent(factoryResult) ? factoryResult.content : factoryResult;
|
||||
return factoryResult;
|
||||
}
|
||||
|
||||
// Recursively calls component instances that might have head content
|
||||
|
|
|
@ -9,6 +9,8 @@ import {
|
|||
renderComponent,
|
||||
renderHead,
|
||||
renderSlot,
|
||||
createHeadAndContent,
|
||||
renderTemplate
|
||||
} from '../dist/runtime/server/index.js';
|
||||
|
||||
const BaseLayout = createComponent((result, _props, slots) => {
|
||||
|
@ -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) => {
|
||||
|
|
Loading…
Reference in a new issue