summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.changeset/metal-ducks-invite.md5
-rw-r--r--packages/astro/src/core/render/dev/vite.ts11
-rw-r--r--packages/astro/test/content-collections-render.test.js19
-rw-r--r--packages/astro/test/fixtures/content/src/components/LayoutProp.astro38
-rw-r--r--packages/astro/test/fixtures/content/src/content/blog/with-layout-prop.md9
-rw-r--r--packages/astro/test/fixtures/content/src/pages/with-layout-prop.astro7
6 files changed, 88 insertions, 1 deletions
diff --git a/.changeset/metal-ducks-invite.md b/.changeset/metal-ducks-invite.md
new file mode 100644
index 000000000..9ee7653e0
--- /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 a3f0b6437..724ad172f 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 8410487c6..2aea21a74 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 000000000..df7493c3e
--- /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;
+---
+
+<html lang="en">
+ <head>
+ <meta charset="utf-8" />
+ <link rel="icon" type="image/svg+xml" href="/favicon.svg" />
+ <meta name="viewport" content="width=device-width" />
+ <meta name="generator" content={Astro.generator} />
+ <title>With Layout Prop</title>
+ </head>
+ <body data-layout-prop="true">
+ <h1>{title}</h1>
+ <nav>
+ <ul>
+ {blog.map((post) => (
+ <li>
+ <a href={post.slug}>{post.data.title}</a>
+ </li>
+ ))}
+ </ul>
+ </nav>
+ <slot />
+ </body>
+</html>
+
diff --git a/packages/astro/test/fixtures/content/src/content/blog/with-layout-prop.md b/packages/astro/test/fixtures/content/src/content/blog/with-layout-prop.md
new file mode 100644
index 000000000..ce8a866cb
--- /dev/null
+++ b/packages/astro/test/fixtures/content/src/content/blog/with-layout-prop.md
@@ -0,0 +1,9 @@
+---
+title: With Layout Prop
+description: Use a layout prop in a content collection
+layout: "../../components/LayoutProp.astro"
+---
+
+## Content with a layout prop
+
+Sure, why not?
diff --git a/packages/astro/test/fixtures/content/src/pages/with-layout-prop.astro b/packages/astro/test/fixtures/content/src/pages/with-layout-prop.astro
new file mode 100644
index 000000000..672430ab5
--- /dev/null
+++ b/packages/astro/test/fixtures/content/src/pages/with-layout-prop.astro
@@ -0,0 +1,7 @@
+---
+import { getEntryBySlug } from 'astro:content';
+
+const entry = await getEntryBySlug('blog', 'with-layout-prop');
+const { Content } = await entry.render();
+---
+<Content />