diff --git a/.changeset/fix-before-hydration-client.md b/.changeset/fix-before-hydration-client.md new file mode 100644 index 000000000000..0c2d37e862d8 --- /dev/null +++ b/.changeset/fix-before-hydration-client.md @@ -0,0 +1,5 @@ +--- +'astro': patch +--- + +Emit the `before-hydration` script chunk for the `client` Vite environment. The chunk was only emitted for `prerender` and `ssr` environments, causing a 404 when browsers tried to load it. This broke hydration for any integration using `injectScript('before-hydration', ...)`, including Lit SSR. diff --git a/.changeset/small-jeans-whisper.md b/.changeset/small-jeans-whisper.md new file mode 100644 index 000000000000..8fa739b57a38 --- /dev/null +++ b/.changeset/small-jeans-whisper.md @@ -0,0 +1,5 @@ +--- +'astro': patch +--- + +Fix `Astro.url.pathname` for the root page when using `build.format: "file"` so it resolves to `/index.html` instead of `/.html` during builds. diff --git a/packages/astro/src/core/build/generate.ts b/packages/astro/src/core/build/generate.ts index 890ba1a8aced..b09a6b1e1ccc 100644 --- a/packages/astro/src/core/build/generate.ts +++ b/packages/astro/src/core/build/generate.ts @@ -541,7 +541,11 @@ function getUrlForPath( } let buildPathname: string; if (pathname === '/' || pathname === '') { - buildPathname = collapseDuplicateTrailingSlashes(base + ending, trailingSlash !== 'never'); + if (format === 'file') { + buildPathname = joinPaths(base, 'index.html'); + } else { + buildPathname = collapseDuplicateTrailingSlashes(base + ending, trailingSlash !== 'never'); + } } else if (routeType === 'endpoint') { const buildPathRelative = removeLeadingForwardSlash(pathname); buildPathname = joinPaths(base, buildPathRelative); diff --git a/packages/astro/src/vite-plugin-scripts/index.ts b/packages/astro/src/vite-plugin-scripts/index.ts index a2dfe3c69d93..1fc42cc62c73 100644 --- a/packages/astro/src/vite-plugin-scripts/index.ts +++ b/packages/astro/src/vite-plugin-scripts/index.ts @@ -61,7 +61,8 @@ export default function astroScriptsPlugin({ settings }: { settings: AstroSettin const hasHydrationScripts = settings.scripts.some((s) => s.stage === 'before-hydration'); if ( hasHydrationScripts && - (this.environment.name === ASTRO_VITE_ENVIRONMENT_NAMES.prerender || + (this.environment.name === ASTRO_VITE_ENVIRONMENT_NAMES.client || + this.environment.name === ASTRO_VITE_ENVIRONMENT_NAMES.prerender || this.environment.name === ASTRO_VITE_ENVIRONMENT_NAMES.ssr) ) { this.emitFile({ diff --git a/packages/astro/test/before-hydration.test.js b/packages/astro/test/before-hydration.test.js index 117fdeedddc9..c05da160644d 100644 --- a/packages/astro/test/before-hydration.test.js +++ b/packages/astro/test/before-hydration.test.js @@ -59,6 +59,16 @@ describe('Astro Scripts before-hydration', () => { let $ = cheerio.load(html); assert.equal($('astro-island[before-hydration-url]').length, 1); }); + + it('Emits the before-hydration chunk to the client output', async () => { + let html = await fixture.readFile('/index.html'); + let $ = cheerio.load(html); + let url = $('astro-island').attr('before-hydration-url'); + assert.ok(url, 'before-hydration-url attribute should have a value'); + // The URL should point to a file that exists in the build output + let content = await fixture.readFile(url); + assert.ok(content, 'before-hydration chunk should exist in the client build output'); + }); }); }); diff --git a/packages/astro/test/fixtures/page-format/src/pages/index.astro b/packages/astro/test/fixtures/page-format/src/pages/index.astro index bcd4c7539a7c..ac18ffc456fb 100644 --- a/packages/astro/test/fixtures/page-format/src/pages/index.astro +++ b/packages/astro/test/fixtures/page-format/src/pages/index.astro @@ -1,6 +1,10 @@ --- +const url = Astro.url; --- testing -

testing

+ +

testing

+

{url.pathname}

+ diff --git a/packages/astro/test/fixtures/page-format/src/pages/nested/page.astro b/packages/astro/test/fixtures/page-format/src/pages/nested/page.astro index eb67508a7365..8296fe339535 100644 --- a/packages/astro/test/fixtures/page-format/src/pages/nested/page.astro +++ b/packages/astro/test/fixtures/page-format/src/pages/nested/page.astro @@ -1,4 +1,6 @@ --- const another = new URL('./another/', Astro.url); +const url = Astro.url; --- +

{url.pathname}

diff --git a/packages/astro/test/page-format.test.js b/packages/astro/test/page-format.test.js index 3b12a79b1d58..125b90eacf74 100644 --- a/packages/astro/test/page-format.test.js +++ b/packages/astro/test/page-format.test.js @@ -43,6 +43,18 @@ describe('build.format', () => { await fixture.build(); }); + it('Astro.url pathname includes /index.html for root page in build', async () => { + let html = await fixture.readFile('/index.html'); + let $ = cheerio.load(html); + assert.equal($('#url').text(), '/index.html'); + }); + + it('Astro.url pathname includes .html for non-root pages in build', async () => { + let html = await fixture.readFile('/nested/page.html'); + let $ = cheerio.load(html); + assert.equal($('#url').text(), '/nested/page.html'); + }); + it('relative urls created point to sibling folders', async () => { let html = await fixture.readFile('/nested/page.html'); let $ = cheerio.load(html);