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) {
|
if (factoryResult instanceof Response) {
|
||||||
return factoryResult;
|
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)) {
|
} else if (!isRenderTemplateResult(factoryResult)) {
|
||||||
throw new AstroError({
|
throw new AstroError({
|
||||||
...AstroErrorData.OnlyResponseCanBeReturned,
|
...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
|
// Recursively calls component instances that might have head content
|
||||||
|
|
|
@ -9,6 +9,8 @@ import {
|
||||||
renderComponent,
|
renderComponent,
|
||||||
renderHead,
|
renderHead,
|
||||||
renderSlot,
|
renderSlot,
|
||||||
|
createHeadAndContent,
|
||||||
|
renderTemplate
|
||||||
} from '../dist/runtime/server/index.js';
|
} from '../dist/runtime/server/index.js';
|
||||||
|
|
||||||
const BaseLayout = createComponent((result, _props, slots) => {
|
const BaseLayout = createComponent((result, _props, slots) => {
|
||||||
|
@ -140,6 +142,54 @@ describe('Container', () => {
|
||||||
assert.match(result, /Bar name/);
|
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 () => {
|
it('Renders props', async () => {
|
||||||
const Page = createComponent(
|
const Page = createComponent(
|
||||||
(result, props, _slots) => {
|
(result, props, _slots) => {
|
||||||
|
|
Loading…
Reference in a new issue