diff --git a/.changeset/metal-ducks-invite.md b/.changeset/metal-ducks-invite.md new file mode 100644 index 000000000000..9ee7653e0a6f --- /dev/null +++ b/.changeset/metal-ducks-invite.md @@ -0,0 +1,5 @@ +--- +'astro': patch +--- + +Fix: prevent dev server hanging for `getCollection()` calls within a layout when using the `layout` prop diff --git a/packages/astro/src/core/render/dev/vite.ts b/packages/astro/src/core/render/dev/vite.ts index a3f0b6437821..724ad172f3ae 100644 --- a/packages/astro/src/core/render/dev/vite.ts +++ b/packages/astro/src/core/render/dev/vite.ts @@ -60,7 +60,16 @@ export async function* crawlGraph( if (entryIsStyle && !isCSSRequest(importedModulePathname)) { continue; } - if (fileExtensionsToSSR.has(npath.extname(importedModulePathname))) { + if ( + fileExtensionsToSSR.has( + npath.extname( + // Use `id` instead of `pathname` to preserve query params. + // Should not SSR a module with an unexpected query param, + // like "?astroPropagatedAssets" + importedModule.id + ) + ) + ) { const mod = loader.getModuleById(importedModule.id); if (!mod?.ssrModule) { try { diff --git a/packages/astro/test/content-collections-render.test.js b/packages/astro/test/content-collections-render.test.js index 8410487c62a4..2aea21a74711 100644 --- a/packages/astro/test/content-collections-render.test.js +++ b/packages/astro/test/content-collections-render.test.js @@ -191,5 +191,24 @@ describe('Content Collections - render()', () => { expect(h2).to.have.a.lengthOf(1); expect(h2.attr('data-components-export-applied')).to.equal('true'); }); + + it('Supports layout prop with recursive getCollection() call', async () => { + const response = await fixture.fetch('/with-layout-prop', { method: 'GET' }); + expect(response.status).to.equal(200); + + const html = await response.text(); + const $ = cheerio.load(html); + + const body = $('body'); + expect(body.attr('data-layout-prop')).to.equal('true'); + + const h1 = $('h1'); + expect(h1).to.have.a.lengthOf(1); + expect(h1.text()).to.equal('With Layout Prop'); + + const h2 = $('h2'); + expect(h2).to.have.a.lengthOf(1); + expect(h2.text()).to.equal('Content with a layout prop'); + }); }); }); diff --git a/packages/astro/test/fixtures/content/src/components/LayoutProp.astro b/packages/astro/test/fixtures/content/src/components/LayoutProp.astro new file mode 100644 index 000000000000..df7493c3e05c --- /dev/null +++ b/packages/astro/test/fixtures/content/src/components/LayoutProp.astro @@ -0,0 +1,38 @@ +--- +import { CollectionEntry, getCollection } from 'astro:content'; + +// Test for recursive `getCollection()` calls +const blog = await getCollection('blog'); + +type Props = { + content: CollectionEntry<'blog'>['data']; +}; + +const { + content: { title }, +} = Astro.props; +--- + + +
+ + + + +