diff --git a/.changeset/cloudflare-prebundle-server-entry.md b/.changeset/cloudflare-prebundle-server-entry.md new file mode 100644 index 000000000000..b880fc2189e4 --- /dev/null +++ b/.changeset/cloudflare-prebundle-server-entry.md @@ -0,0 +1,5 @@ +--- +'@astrojs/cloudflare': patch +--- + +Prevents warnings in the Cloudflare adapter about optimizing the `@astrojs/cloudflare/entrypoints/server` module in dev. diff --git a/.changeset/cuddly-games-sleep.md b/.changeset/cuddly-games-sleep.md new file mode 100644 index 000000000000..7a5c188cd2ad --- /dev/null +++ b/.changeset/cuddly-games-sleep.md @@ -0,0 +1,7 @@ +--- +'astro': patch +--- + +Refactors path alias resolution to use Vite's native `tsconfigPaths` option + +This is an internal change with no expected impact on user projects. Astro now defers tsconfig and jsconfig `paths` alias resolution to Vite, keeping a small fallback for a few CSS cases Vite does not yet handle. diff --git a/.changeset/every-breads-hope.md b/.changeset/every-breads-hope.md new file mode 100644 index 000000000000..03b8e81ced48 --- /dev/null +++ b/.changeset/every-breads-hope.md @@ -0,0 +1,5 @@ +--- +'astro': patch +--- + +Fixes an issue where the ClientRouter wipes head elements after page transitions if the `` contains a `server:defer` component. diff --git a/.changeset/proud-pugs-jump.md b/.changeset/proud-pugs-jump.md new file mode 100644 index 000000000000..11c796ee19ba --- /dev/null +++ b/.changeset/proud-pugs-jump.md @@ -0,0 +1,5 @@ +--- +'astro': patch +--- + +Fixes a bug where ` diff --git a/packages/astro/test/fixtures/config-vite-css-target-no-minify/src/styles/global.css b/packages/astro/test/fixtures/config-vite-css-target-no-minify/src/styles/global.css new file mode 100644 index 000000000000..00ce50186417 --- /dev/null +++ b/packages/astro/test/fixtures/config-vite-css-target-no-minify/src/styles/global.css @@ -0,0 +1,44 @@ +/* Global CSS - tests that imported CSS also respects target */ +@media screen and (min-width: 500px) { + body { + background: skyblue; + } +} + +@media screen and (width >= 1000px) { + body { + background: plum; + } +} + +/* Padding to ensure this doesn't get inlined */ +.pad1 { color: red; } +.pad2 { color: blue; } +.pad3 { color: green; } +.pad4 { color: yellow; } +.pad5 { color: orange; } +.pad6 { color: purple; } +.pad7 { color: pink; } +.pad8 { color: brown; } +.pad9 { color: black; } +.pad10 { color: white; } +.pad11 { color: gray; } +.pad12 { color: cyan; } +.pad13 { color: magenta; } +.pad14 { color: lime; } +.pad15 { color: olive; } +.pad16 { color: navy; } +.pad17 { color: teal; } +.pad18 { color: maroon; } +.pad19 { color: aqua; } +.pad20 { color: fuchsia; } +.pad21 { color: silver; } +.pad22 { color: coral; } +.pad23 { color: salmon; } +.pad24 { color: tomato; } +.pad25 { color: crimson; } +.pad26 { color: orchid; } +.pad27 { color: violet; } +.pad28 { color: indigo; } +.pad29 { color: khaki; } +.pad30 { color: linen; } diff --git a/packages/astro/test/fixtures/content-collections-base/src/components/SlotLayout.astro b/packages/astro/test/fixtures/content-collections-base/src/components/SlotLayout.astro new file mode 100644 index 000000000000..e80ebc4e91b5 --- /dev/null +++ b/packages/astro/test/fixtures/content-collections-base/src/components/SlotLayout.astro @@ -0,0 +1,11 @@ + + + + Async slot + + +
+ +
+ + diff --git a/packages/astro/test/fixtures/content-collections-base/src/pages/async-slot.astro b/packages/astro/test/fixtures/content-collections-base/src/pages/async-slot.astro new file mode 100644 index 000000000000..b46407cc9a69 --- /dev/null +++ b/packages/astro/test/fixtures/content-collections-base/src/pages/async-slot.astro @@ -0,0 +1,15 @@ +--- +import { getEntry, render } from 'astro:content'; +import SlotLayout from '../components/SlotLayout.astro'; +const entry = await getEntry('docs', 'one'); +const { Content } = await render(entry); +--- + + +

{await new Promise((resolve) => setTimeout(() => resolve('ready'), 50))}

+ +
diff --git a/packages/astro/test/units/render/head-propagation/buffer.test.ts b/packages/astro/test/units/render/head-propagation/buffer.test.ts index 6d1807b0ff0a..df64aee236aa 100644 --- a/packages/astro/test/units/render/head-propagation/buffer.test.ts +++ b/packages/astro/test/units/render/head-propagation/buffer.test.ts @@ -17,8 +17,12 @@ function isHeadAndContent(value: unknown): value is { head: string } { return typeof value === 'object' && value !== null && headAndContentSym in value; } -function createResult(): SSRResult { - return {} as SSRResult; +function createResult(pendingSlotEvaluations: Promise[] = []): SSRResult { + return { _metadata: { pendingSlotEvaluations } } as unknown as SSRResult; +} + +function tick(): Promise { + return new Promise((resolve) => setTimeout(resolve, 0)); } describe('head propagation buffer', () => { @@ -89,4 +93,47 @@ describe('head propagation buffer', () => { '', ]); }); + + it('drains async slot pre-renders that register propagators after an await', async () => { + const propagators = new Set(); + // Mimics an async slot whose markup registers a propagating component + // (e.g. content `Content` with styles) only after an `await` resolves. + const slotEvaluation = tick().then(() => { + propagators.add({ + init: () => createHeadAndContentLike(''), + }); + }); + + const result = createResult([slotEvaluation]); + const collected = await collectPropagatedHeadParts({ propagators, result, isHeadAndContent }); + + assert.deepEqual(collected, ['']); + // The queue is fully drained. + assert.equal(result._metadata.pendingSlotEvaluations.length, 0); + }); + + it('drains nested async slot pre-renders queued while collecting', async () => { + const propagators = new Set(); + const result = createResult(); + + // Outer async slot resolves, registers a propagator AND queues a deeper + // async slot pre-render — the case a one-shot `Promise.all` would miss. + const outer = tick().then(() => { + propagators.add({ + init: () => createHeadAndContentLike(''), + }); + const inner = tick().then(() => { + propagators.add({ + init: () => createHeadAndContentLike(''), + }); + }); + result._metadata.pendingSlotEvaluations.push(inner); + }); + result._metadata.pendingSlotEvaluations.push(outer); + + const collected = await collectPropagatedHeadParts({ propagators, result, isHeadAndContent }); + + assert.deepEqual(collected, ['', '']); + assert.equal(result._metadata.pendingSlotEvaluations.length, 0); + }); }); diff --git a/packages/astro/test/units/server-islands/server-islands-render.test.ts b/packages/astro/test/units/server-islands/server-islands-render.test.ts index f0e0d8093017..aa62183c8f50 100644 --- a/packages/astro/test/units/server-islands/server-islands-render.test.ts +++ b/packages/astro/test/units/server-islands/server-islands-render.test.ts @@ -65,6 +65,8 @@ async function createStubResult(overrides: Partial = {}): Promise html-escaper', diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 012ff010abe1..b7c70c6fd29d 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -2564,6 +2564,12 @@ importers: specifier: workspace:* version: link:../../.. + packages/astro/test/fixtures/config-vite-css-target-no-minify: + dependencies: + astro: + specifier: workspace:* + version: link:../../.. + packages/astro/test/fixtures/container-custom-renderers: dependencies: '@astrojs/react':