diff --git a/.changeset/smart-nails-push.md b/.changeset/smart-nails-push.md new file mode 100644 index 000000000000..3166e9f468b7 --- /dev/null +++ b/.changeset/smart-nails-push.md @@ -0,0 +1,5 @@ +--- +'astro': patch +--- + +Always return a new array instance from `getCollection` in prod diff --git a/packages/astro/src/content/runtime.ts b/packages/astro/src/content/runtime.ts index a1afb2201226..bb89c60997aa 100644 --- a/packages/astro/src/content/runtime.ts +++ b/packages/astro/src/content/runtime.ts @@ -69,7 +69,8 @@ export function createGetCollection({ // Cache `getCollection()` calls in production only // prevents stale cache in development if (import.meta.env.PROD && cacheEntriesByCollection.has(collection)) { - entries = cacheEntriesByCollection.get(collection)!; + // Always return a new instance so consumers can safely mutate it + entries = [...cacheEntriesByCollection.get(collection)!] } else { entries = await Promise.all( lazyImports.map(async (lazyImport) => { diff --git a/packages/astro/test/content-collections-render.test.js b/packages/astro/test/content-collections-render.test.js index e1107b10f198..8bcc35817e3c 100644 --- a/packages/astro/test/content-collections-render.test.js +++ b/packages/astro/test/content-collections-render.test.js @@ -168,6 +168,22 @@ describe('Content Collections - render()', () => { expect(h2).to.have.a.lengthOf(1); expect(h2.attr('data-components-export-applied')).to.equal('true'); }); + + it('getCollection should return new instances of the array to be mutated safely', async () => { + const app = await fixture.loadTestAdapterApp(); + + let request = new Request('http://example.com/sort-blog-collection'); + let response = await app.render(request); + let html = await response.text(); + let $ = cheerio.load(html); + expect($('li').first().text()).to.equal('With Layout Prop'); + + request = new Request('http://example.com/'); + response = await app.render(request); + html = await response.text(); + $ = cheerio.load(html); + expect($('li').first().text()).to.equal('Hello world'); + }) }); describe('Dev - SSG', () => { diff --git a/packages/astro/test/fixtures/content/src/pages/sort-blog-collection.astro b/packages/astro/test/fixtures/content/src/pages/sort-blog-collection.astro new file mode 100644 index 000000000000..5426068197ad --- /dev/null +++ b/packages/astro/test/fixtures/content/src/pages/sort-blog-collection.astro @@ -0,0 +1,22 @@ +--- +import { getCollection } from 'astro:content'; + +const blog = await getCollection('blog'); + +// Sort descending by title, make sure mutating `blog` doesn't mutate other pages that call `getCollection` too +blog.sort((a, b) => a.data.title < b.data.title ? 1 : -1) +--- + +
+