diff options
author | 2022-09-28 10:55:06 -0400 | |
---|---|---|
committer | 2022-09-28 10:55:06 -0400 | |
commit | ff7ba0ee0fd652a92f5d06d9b644dd646cebe65c (patch) | |
tree | b9993e9d5a5cb8f224b7e50ad1f662980ecd9fe2 | |
parent | 649e9080cbf780905c42fb59c353d5aae8256df6 (diff) | |
download | astro-ff7ba0ee0fd652a92f5d06d9b644dd646cebe65c.tar.gz astro-ff7ba0ee0fd652a92f5d06d9b644dd646cebe65c.tar.zst astro-ff7ba0ee0fd652a92f5d06d9b644dd646cebe65c.zip |
Ensure head content rendered once with lazy layouts (#4892)
* Ensure head content rendered once with lazy layouts
* Add changeset
-rw-r--r-- | .changeset/popular-horses-lie.md | 5 | ||||
-rw-r--r-- | packages/astro/src/@types/astro.ts | 1 | ||||
-rw-r--r-- | packages/astro/src/core/render/result.ts | 1 | ||||
-rw-r--r-- | packages/astro/src/runtime/server/render/head.ts | 5 | ||||
-rw-r--r-- | packages/astro/test/fixtures/lazy-layout/package.json | 6 | ||||
-rw-r--r-- | packages/astro/test/fixtures/lazy-layout/src/layouts/Main.astro | 13 | ||||
-rw-r--r-- | packages/astro/test/fixtures/lazy-layout/src/pages/index.astro | 6 | ||||
-rw-r--r-- | packages/astro/test/lazy-layout.test.js | 19 | ||||
-rw-r--r-- | pnpm-lock.yaml | 6 |
9 files changed, 59 insertions, 3 deletions
diff --git a/.changeset/popular-horses-lie.md b/.changeset/popular-horses-lie.md new file mode 100644 index 000000000..6d9ffdbbd --- /dev/null +++ b/.changeset/popular-horses-lie.md @@ -0,0 +1,5 @@ +--- +'astro': patch +--- + +Prevent multiple rendering of head content diff --git a/packages/astro/src/@types/astro.ts b/packages/astro/src/@types/astro.ts index 6a392f840..c423a1abf 100644 --- a/packages/astro/src/@types/astro.ts +++ b/packages/astro/src/@types/astro.ts @@ -1212,6 +1212,7 @@ export interface SSRMetadata { pathname: string; hasHydrationScript: boolean; hasDirectives: Set<string>; + hasRenderedHead: boolean; } export interface SSRResult { diff --git a/packages/astro/src/core/render/result.ts b/packages/astro/src/core/render/result.ts index 9eb618cb3..d4704ca1f 100644 --- a/packages/astro/src/core/render/result.ts +++ b/packages/astro/src/core/render/result.ts @@ -270,6 +270,7 @@ const canonicalURL = new URL(Astro.url.pathname, Astro.site); renderers, pathname, hasHydrationScript: false, + hasRenderedHead: false, hasDirectives: new Set(), }, response, diff --git a/packages/astro/src/runtime/server/render/head.ts b/packages/astro/src/runtime/server/render/head.ts index ed4b73f3e..9afed33fe 100644 --- a/packages/astro/src/runtime/server/render/head.ts +++ b/packages/astro/src/runtime/server/render/head.ts @@ -12,9 +12,8 @@ const uniqueElements = (item: any, index: number, all: any[]) => { ); }; -const alreadyHeadRenderedResults = new WeakSet<SSRResult>(); export function renderHead(result: SSRResult): Promise<string> { - alreadyHeadRenderedResults.add(result); + result._metadata.hasRenderedHead = true; const styles = Array.from(result.styles) .filter(uniqueElements) .map((style) => renderElement('style', style)); @@ -36,7 +35,7 @@ export function renderHead(result: SSRResult): Promise<string> { // is called before a component's first non-head HTML element. If the head was // already injected it is a noop. export async function* maybeRenderHead(result: SSRResult): AsyncIterable<string> { - if (alreadyHeadRenderedResults.has(result)) { + if (result._metadata.hasRenderedHead) { return; } yield renderHead(result); diff --git a/packages/astro/test/fixtures/lazy-layout/package.json b/packages/astro/test/fixtures/lazy-layout/package.json new file mode 100644 index 000000000..4fe627073 --- /dev/null +++ b/packages/astro/test/fixtures/lazy-layout/package.json @@ -0,0 +1,6 @@ +{ + "name": "@test/lazy-layout", + "dependencies": { + "astro": "workspace:*" + } +} diff --git a/packages/astro/test/fixtures/lazy-layout/src/layouts/Main.astro b/packages/astro/test/fixtures/lazy-layout/src/layouts/Main.astro new file mode 100644 index 000000000..d19faadcb --- /dev/null +++ b/packages/astro/test/fixtures/lazy-layout/src/layouts/Main.astro @@ -0,0 +1,13 @@ +<html> + <head> + <title>Testing</title> + <style> + body { + background: green; + } + </style> + </head> + <body> + <slot /> + </body> +</html> diff --git a/packages/astro/test/fixtures/lazy-layout/src/pages/index.astro b/packages/astro/test/fixtures/lazy-layout/src/pages/index.astro new file mode 100644 index 000000000..603057e53 --- /dev/null +++ b/packages/astro/test/fixtures/lazy-layout/src/pages/index.astro @@ -0,0 +1,6 @@ +--- +const Layout = (await import('../layouts/Main.astro')).default; +--- +<Layout> + <div>Stuff here</div> +</Layout> diff --git a/packages/astro/test/lazy-layout.test.js b/packages/astro/test/lazy-layout.test.js new file mode 100644 index 000000000..4ed22f5a0 --- /dev/null +++ b/packages/astro/test/lazy-layout.test.js @@ -0,0 +1,19 @@ +import { expect } from 'chai'; +import * as cheerio from 'cheerio'; +import { loadFixture } from './test-utils.js'; + +describe('Lazily imported layouts', () => { + /** @type {import('./test-utils').Fixture} */ + let fixture; + + before(async () => { + fixture = await loadFixture({ root: './fixtures/lazy-layout/' }); + await fixture.build(); + }); + + it('Renders styles only once', async () => { + const html = await fixture.readFile('/index.html'); + const $ = cheerio.load(html); + expect($('link')).to.have.a.lengthOf(1); + }); +}); diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index bb386d8d9..e12b7f63b 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -1664,6 +1664,12 @@ importers: '@astrojs/solid-js': link:../../../../integrations/solid astro: link:../../.. + packages/astro/test/fixtures/lazy-layout: + specifiers: + astro: workspace:* + dependencies: + astro: link:../../.. + packages/astro/test/fixtures/legacy-astro-flavored-markdown: specifiers: '@astrojs/preact': workspace:* |