Skip to content

Commit

Permalink
Fix transitions with non-recommended headers (#9464)
Browse files Browse the repository at this point in the history
* 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>
  • Loading branch information
Fryuni and natemoo-re committed Dec 19, 2023
1 parent f515b14 commit faf6c7e
Show file tree
Hide file tree
Showing 5 changed files with 37 additions and 1 deletion.
5 changes: 5 additions & 0 deletions .changeset/khaki-ducks-give.md
@@ -0,0 +1,5 @@
---
'astro': patch
---

Fixes an edge case with view transitions where some spec-compliant `Content-Type` headers would cause a valid HTML response to be ignored.
Expand Up @@ -6,6 +6,7 @@ import Layout from '../components/Layout.astro';
<a id="click-one" href="#test">test</a>
<a id="click-two" href="/two">go to 2</a>
<a id="click-three" href="/three">go to 3</a>
<a id="click-seven" href="/seven">go to 7</a>
<a id="click-longpage" href="/long-page">go to long page</a>
<a id="click-self" href="">go to top</a>
<a id="click-redirect-two" href="/redirect-two">go to redirect 2</a>
Expand Down
10 changes: 10 additions & 0 deletions packages/astro/e2e/fixtures/view-transitions/src/pages/seven.astro
@@ -0,0 +1,10 @@
---
import Layout from '../components/Layout.astro';
Astro.response.headers.set('Content-Type', 'text/html ; charset=utf-8');
---
<Layout link="/one.css">
<p id="seven">Page 7</p>

<div id="test">test content</div>
</Layout>
19 changes: 19 additions & 0 deletions packages/astro/e2e/view-transitions.test.js
Expand Up @@ -97,6 +97,25 @@ test.describe('View Transitions', () => {
expect(loads.length, 'There should only be 1 page load').toEqual(1);
});

test('Clicking on a link to a page with non-recommended headers', async ({page, astro}) => {
const loads = [];
page.addListener('load', (p) => {
loads.push(p.title());
});

// Go to page 4
await page.goto(astro.resolveUrl('/one'));
let p = page.locator('#one');
await expect(p, 'should have content').toHaveText('Page 1');

// Go to page 1
await page.click('#click-seven');
p = page.locator('#seven');
await expect(p, 'should have content').toHaveText('Page 7');

expect(loads.length, 'There should only be 1 page load').toEqual(1);
});

test('Moving to a page without ViewTransitions triggers a full page navigation', async ({
page,
astro,
Expand Down
3 changes: 2 additions & 1 deletion packages/astro/src/transitions/router.ts
Expand Up @@ -119,8 +119,9 @@ async function fetchHTML(
): Promise<null | { html: string; redirected?: string; mediaType: DOMParserSupportedType }> {
try {
const res = await fetch(href, init);
const contentType = res.headers.get('content-type') ?? '';
// drop potential charset (+ other name/value pairs) as parser needs the mediaType
const mediaType = res.headers.get('content-type')?.replace(/;.*$/, '');
const mediaType = contentType.split(';', 1)[0].trim();
// the DOMParser can handle two types of HTML
if (mediaType !== 'text/html' && mediaType !== 'application/xhtml+xml') {
// everything else (e.g. audio/mp3) will be handled by the browser but not by us
Expand Down

0 comments on commit faf6c7e

Please sign in to comment.