diff --git a/.changeset/good-parrots-work.md b/.changeset/good-parrots-work.md new file mode 100644 index 000000000..7a58bac96 --- /dev/null +++ b/.changeset/good-parrots-work.md @@ -0,0 +1,5 @@ +--- +'astro': patch +--- + +fix a bug when Fragment is as a slot diff --git a/packages/astro/src/core/render/result.ts b/packages/astro/src/core/render/result.ts index e18ed7eb9..22ca5bc80 100644 --- a/packages/astro/src/core/render/result.ts +++ b/packages/astro/src/core/render/result.ts @@ -18,6 +18,7 @@ import { renderJSX } from '../../runtime/server/jsx.js'; import { AstroCookies } from '../cookies/index.js'; import { AstroError, AstroErrorData } from '../errors/index.js'; import { warn, type LogOptions } from '../logger/core.js'; +import { isHTMLString } from '../../runtime/server/escape.js'; const clientAddressSymbol = Symbol.for('astro.clientAddress'); const responseSentSymbol = Symbol.for('astro.responseSent'); @@ -110,9 +111,11 @@ class Slots { // Astro const expression = getFunctionExpression(component); if (expression) { - const slot = () => expression(...args); - return await renderSlotToString(result, slot).then((res) => - res != null ? String(res) : res + const slot = async () => isHTMLString(await expression) ? expression : expression(...args) + return await renderSlotToString(result, slot).then((res) =>{ + return res != null ? String(res) : res + } + ); } // JSX diff --git a/packages/astro/src/runtime/server/render/slot.ts b/packages/astro/src/runtime/server/render/slot.ts index 0cd477322..1dfe2f5d9 100644 --- a/packages/astro/src/runtime/server/render/slot.ts +++ b/packages/astro/src/runtime/server/render/slot.ts @@ -7,7 +7,7 @@ import { renderChild } from './any.js'; type RenderTemplateResult = ReturnType; export type ComponentSlots = Record; -export type ComponentSlotValue = (result: SSRResult) => RenderTemplateResult; +export type ComponentSlotValue = (result: SSRResult) => RenderTemplateResult | Promise; const slotString = Symbol.for('astro:slot-string'); diff --git a/packages/astro/test/fixtures/set-html/components/Slot.astro b/packages/astro/test/fixtures/set-html/components/Slot.astro new file mode 100644 index 000000000..a5b6f5a17 --- /dev/null +++ b/packages/astro/test/fixtures/set-html/components/Slot.astro @@ -0,0 +1,2 @@ + + diff --git a/packages/astro/test/fixtures/set-html/src/pages/children.astro b/packages/astro/test/fixtures/set-html/src/pages/children.astro new file mode 100644 index 000000000..360b8208a --- /dev/null +++ b/packages/astro/test/fixtures/set-html/src/pages/children.astro @@ -0,0 +1,22 @@ +--- +import Slot from '../../components/Slot.astro'; +--- + + + +

Bug: Astro.slots.render() with arguments does not work with <Fragment> slot

+

Comment out working example and uncomment non working exmaples

+
+ + + + Test + + + + + + + diff --git a/packages/astro/test/set-html.test.js b/packages/astro/test/set-html.test.js index e43984513..dab80d48c 100644 --- a/packages/astro/test/set-html.test.js +++ b/packages/astro/test/set-html.test.js @@ -35,6 +35,12 @@ describe('set:html', () => { expect($('#fetched-html')).to.have.a.lengthOf(1); expect($('#fetched-html').text()).to.equal('works'); }); + it('test Fragment when Fragment is as a slot', async () => { + let res = await fixture.fetch('/children'); + expect(res.status).to.equal(200); + let html = await res.text(); + expect(html).include('Test'); + }) }); describe('Build', () => { @@ -77,5 +83,10 @@ describe('set:html', () => { const $ = cheerio.load(html); expect($('#readable-inner')).to.have.a.lengthOf(1); }); + + it('test Fragment when Fragment is as a slot', async () => { + let res = await fixture.readFile('/children/index.html'); + expect(res).include('Test'); + }) }); });