Skip to content

Commit faf6c7e

Browse files
Fryuninatemoo-re
andauthoredDec 19, 2023
Fix transitions with non-recommended headers (#9464)
* Reproduce edge case in test * Fix edge case * Add changeset * Update .changeset/khaki-ducks-give.md Co-authored-by: Nate Moore <natemoo-re@users.noreply.github.com> --------- Co-authored-by: Nate Moore <natemoo-re@users.noreply.github.com>
1 parent f515b14 commit faf6c7e

File tree

5 files changed

+37
-1
lines changed

5 files changed

+37
-1
lines changed
 

‎.changeset/khaki-ducks-give.md

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'astro': patch
3+
---
4+
5+
Fixes an edge case with view transitions where some spec-compliant `Content-Type` headers would cause a valid HTML response to be ignored.

‎packages/astro/e2e/fixtures/view-transitions/src/pages/one.astro

+1
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import Layout from '../components/Layout.astro';
66
<a id="click-one" href="#test">test</a>
77
<a id="click-two" href="/two">go to 2</a>
88
<a id="click-three" href="/three">go to 3</a>
9+
<a id="click-seven" href="/seven">go to 7</a>
910
<a id="click-longpage" href="/long-page">go to long page</a>
1011
<a id="click-self" href="">go to top</a>
1112
<a id="click-redirect-two" href="/redirect-two">go to redirect 2</a>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
---
2+
import Layout from '../components/Layout.astro';
3+
4+
Astro.response.headers.set('Content-Type', 'text/html ; charset=utf-8');
5+
---
6+
<Layout link="/one.css">
7+
<p id="seven">Page 7</p>
8+
9+
<div id="test">test content</div>
10+
</Layout>

‎packages/astro/e2e/view-transitions.test.js

+19
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,25 @@ test.describe('View Transitions', () => {
9797
expect(loads.length, 'There should only be 1 page load').toEqual(1);
9898
});
9999

100+
test('Clicking on a link to a page with non-recommended headers', async ({page, astro}) => {
101+
const loads = [];
102+
page.addListener('load', (p) => {
103+
loads.push(p.title());
104+
});
105+
106+
// Go to page 4
107+
await page.goto(astro.resolveUrl('/one'));
108+
let p = page.locator('#one');
109+
await expect(p, 'should have content').toHaveText('Page 1');
110+
111+
// Go to page 1
112+
await page.click('#click-seven');
113+
p = page.locator('#seven');
114+
await expect(p, 'should have content').toHaveText('Page 7');
115+
116+
expect(loads.length, 'There should only be 1 page load').toEqual(1);
117+
});
118+
100119
test('Moving to a page without ViewTransitions triggers a full page navigation', async ({
101120
page,
102121
astro,

‎packages/astro/src/transitions/router.ts

+2-1
Original file line numberDiff line numberDiff line change
@@ -119,8 +119,9 @@ async function fetchHTML(
119119
): Promise<null | { html: string; redirected?: string; mediaType: DOMParserSupportedType }> {
120120
try {
121121
const res = await fetch(href, init);
122+
const contentType = res.headers.get('content-type') ?? '';
122123
// drop potential charset (+ other name/value pairs) as parser needs the mediaType
123-
const mediaType = res.headers.get('content-type')?.replace(/;.*$/, '');
124+
const mediaType = contentType.split(';', 1)[0].trim();
124125
// the DOMParser can handle two types of HTML
125126
if (mediaType !== 'text/html' && mediaType !== 'application/xhtml+xml') {
126127
// everything else (e.g. audio/mp3) will be handled by the browser but not by us

0 commit comments

Comments
 (0)
Please sign in to comment.