Skip to content

Commit

Permalink
Vt follow redirects (#8522)
Browse files Browse the repository at this point in the history
* View Transitions redirects WIP

* transition across redirects

* added changeset

---------

Co-authored-by: Matthew Phillips <[email protected]>
  • Loading branch information
martrapp and matthewp authored Sep 12, 2023
1 parent 2db9762 commit 43bc5f2
Show file tree
Hide file tree
Showing 5 changed files with 78 additions and 6 deletions.
5 changes: 5 additions & 0 deletions .changeset/warm-windows-occur.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'astro': patch
---

let view transitions handle same origin redirects
23 changes: 18 additions & 5 deletions packages/astro/components/ViewTransitions.astro
Original file line number Diff line number Diff line change
Expand Up @@ -65,9 +65,19 @@ const { fallback = 'animate' } = Astro.props as Props;
};

async function getHTML(href: string) {
const res = await fetch(href);
let res;
try {
res = await fetch(href);
} catch (err) {
return { ok: false };
}
const html = await res.text();
return { ok: res.ok, html };
return {
ok: res.ok,
html,
redirected: res.redirected ? res.url : undefined,
contentType: res.headers.get('content-type'),
};
}

function getFallback(): Fallback {
Expand Down Expand Up @@ -280,13 +290,16 @@ const { fallback = 'animate' } = Astro.props as Props;
async function navigate(dir: Direction, loc: URL, state?: State) {
let finished: Promise<void>;
const href = loc.href;
const { html, ok } = await getHTML(href);
const { html, ok, contentType, redirected } = await getHTML(href);
// if there was a redirection, show the final URL in the browser's address bar
redirected && (loc = new URL(redirected));
// If there is a problem fetching the new page, just do an MPA navigation to it.
if (!ok) {
if (!ok || contentType !== 'text/html') {
location.href = href;
return;
}
const doc = parser.parseFromString(html, 'text/html');

const doc = parser.parseFromString(html, contentType);
if (!doc.querySelector('[name="astro-view-transitions-enabled"]')) {
location.href = href;
return;
Expand Down
4 changes: 4 additions & 0 deletions packages/astro/e2e/fixtures/view-transitions/astro.config.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,10 @@ export default defineConfig({
output: 'server',
adapter: nodejs({ mode: 'standalone' }),
integrations: [react()],
redirects: {
'/redirect-two': '/two',
'/redirect-external': 'http://example.com/',
},
vite: {
build: {
assetsInlineLimit: 0,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ import Layout from '../components/Layout.astro';
<a id="click-three" href="/three">go to 3</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>
<a id="click-redirect-external" href="/redirect-external">go to a redirect external</a>

<div id="test">test content</div>
</Layout>
50 changes: 49 additions & 1 deletion packages/astro/e2e/view-transitions.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -566,7 +566,55 @@ test.describe('View Transitions', () => {
await expect(p, 'should have content').toHaveText('Page 1');
});

test('client:only styles are retained on transition', async ({ page, astro }) => {
test('Moving to a page which redirects to another', async ({ page, astro }) => {
const loads = [];
page.addListener('load', (p) => {
loads.push(p.title());
});

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

// go to page 2
await page.click('#click-redirect-two');
p = page.locator('#two');
await expect(p, 'should have content').toHaveText('Page 2');

// go back
await page.goBack();
p = page.locator('#one');
await expect(p, 'should have content').toHaveText('Page 1');

expect(
loads.length,
'There should only be the initial page load and two normal transitions'
).toEqual(1);
});

test('Redirect to external site causes page load', async ({ page, astro }) => {
const loads = [];
page.addListener('load', (p) => {
loads.push(p.title());
});

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

// go to external page
await page.click('#click-redirect-external');
// doesn't work for playwright when we are too fast
await page.waitForTimeout(1000);
p = page.locator('h1');
await expect(p, 'should have content').toBeVisible();

expect(loads.length, 'There should be 2 page loads').toEqual(2);
});

test('client:only styles are retained on transition', async ({ page, astro }) => {
const totalExpectedStyles = 8;

// Go to page 1
Expand Down

0 comments on commit 43bc5f2

Please sign in to comment.