From 0d093bdcaa7c581bf95f55eb07cc0815fd8b8d04 Mon Sep 17 00:00:00 2001 From: Matthew Phillips Date: Thu, 15 Feb 2024 13:37:39 -0500 Subject: [PATCH 01/12] Allow islands to be re-rendered with new props on page transition --- .../view-transitions/src/components/Island.jsx | 4 ++-- .../view-transitions/src/pages/island-one.astro | 2 +- .../view-transitions/src/pages/island-two.astro | 2 +- packages/astro/e2e/view-transitions.test.js | 4 ++++ packages/astro/src/transitions/router.ts | 5 +++++ packages/integrations/react/client.js | 15 +++++++++++++-- 6 files changed, 26 insertions(+), 6 deletions(-) diff --git a/packages/astro/e2e/fixtures/view-transitions/src/components/Island.jsx b/packages/astro/e2e/fixtures/view-transitions/src/components/Island.jsx index 734e2011b25b..21c9f1e381bf 100644 --- a/packages/astro/e2e/fixtures/view-transitions/src/components/Island.jsx +++ b/packages/astro/e2e/fixtures/view-transitions/src/components/Island.jsx @@ -1,8 +1,7 @@ import React, { useState } from 'react'; import './Island.css'; -import { indirect} from './css.js'; -export default function Counter({ children, count: initialCount, id }) { +export default function Counter({ children, count: initialCount, id, page }) { const [count, setCount] = useState(initialCount); const add = () => setCount((i) => i + 1); const subtract = () => setCount((i) => i - 1); @@ -10,6 +9,7 @@ export default function Counter({ children, count: initialCount, id }) { return ( <>
+

{page}

{count}
diff --git a/packages/astro/e2e/fixtures/view-transitions/src/pages/island-one.astro b/packages/astro/e2e/fixtures/view-transitions/src/pages/island-one.astro index 89822a01be93..f79a60f73621 100644 --- a/packages/astro/e2e/fixtures/view-transitions/src/pages/island-one.astro +++ b/packages/astro/e2e/fixtures/view-transitions/src/pages/island-one.astro @@ -5,5 +5,5 @@ import Island from '../components/Island.jsx';

Page 1

go to 2 - +
diff --git a/packages/astro/e2e/fixtures/view-transitions/src/pages/island-two.astro b/packages/astro/e2e/fixtures/view-transitions/src/pages/island-two.astro index 3841ca8970c3..37912591cb57 100644 --- a/packages/astro/e2e/fixtures/view-transitions/src/pages/island-two.astro +++ b/packages/astro/e2e/fixtures/view-transitions/src/pages/island-two.astro @@ -5,5 +5,5 @@ import Island from '../components/Island.jsx';

Page 2

go to 1 - +
diff --git a/packages/astro/e2e/view-transitions.test.js b/packages/astro/e2e/view-transitions.test.js index d90575c52286..9083cdb015cc 100644 --- a/packages/astro/e2e/view-transitions.test.js +++ b/packages/astro/e2e/view-transitions.test.js @@ -543,6 +543,10 @@ test.describe('View Transitions', () => { cnt = page.locator('.counter pre'); // Count should remain await expect(cnt).toHaveText('6'); + + // Props should have changed + const pageTitle = page.locator('.page'); + await expect(pageTitle).toHaveText('Island 2'); }); test('Scripts are only executed once', async ({ page, astro }) => { diff --git a/packages/astro/src/transitions/router.ts b/packages/astro/src/transitions/router.ts index 6ca3f666a871..92586202eb1b 100644 --- a/packages/astro/src/transitions/router.ts +++ b/packages/astro/src/transitions/router.ts @@ -388,6 +388,11 @@ async function updateDOM( // The element exists in the new page, replace it with the element // from the old page so that state is preserved. newEl.replaceWith(el); + // For islands, copy over the props to allow them to re-render + if(newEl.localName === 'astro-island') { + el.setAttribute('ssr', ''); + el.setAttribute('props', newEl.getAttribute('props')!); + } } } restoreFocus(savedFocus); diff --git a/packages/integrations/react/client.js b/packages/integrations/react/client.js index 90e4ceb837b5..cd1b4a227c91 100644 --- a/packages/integrations/react/client.js +++ b/packages/integrations/react/client.js @@ -53,6 +53,9 @@ function getChildren(childString, experimentalReactChildren) { } } +// Keep a map of roots so we can reuse them on re-renders +let rootMap = new WeakMap(); + export default (element) => (Component, props, { default: children, ...slotted }, { client }) => { if (!element.hasAttribute('ssr')) return; @@ -75,13 +78,21 @@ export default (element) => } if (client === 'only') { return startTransition(() => { - const root = createRoot(element); + let root = rootMap.get(element); + if(!root) { + root = createRoot(element); + rootMap.set(element, root); + } root.render(componentEl); element.addEventListener('astro:unmount', () => root.unmount(), { once: true }); }); } startTransition(() => { - const root = hydrateRoot(element, componentEl, renderOptions); + let root = rootMap.get(element); + if(!root) { + root = hydrateRoot(element, componentEl, renderOptions); + rootMap.set(element, root); + } root.render(componentEl); element.addEventListener('astro:unmount', () => root.unmount(), { once: true }); }); From ef52e571db8fdb0729f496af6744779ec144d9af Mon Sep 17 00:00:00 2001 From: Matthew Phillips Date: Thu, 15 Feb 2024 14:17:08 -0500 Subject: [PATCH 02/12] Adjust the expected styles --- packages/astro/e2e/view-transitions.test.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/astro/e2e/view-transitions.test.js b/packages/astro/e2e/view-transitions.test.js index 9083cdb015cc..b6e3e67d5963 100644 --- a/packages/astro/e2e/view-transitions.test.js +++ b/packages/astro/e2e/view-transitions.test.js @@ -786,7 +786,7 @@ test.describe('View Transitions', () => { }); test('client:only styles are retained on transition (1/2)', async ({ page, astro }) => { - const totalExpectedStyles = 9; + const totalExpectedStyles = 8; await page.goto(astro.resolveUrl('/client-only-one')); let msg = page.locator('.counter-message'); @@ -805,7 +805,7 @@ test.describe('View Transitions', () => { }); test('client:only styles are retained on transition (2/2)', async ({ page, astro }) => { - const totalExpectedStyles_page_three = 11; + const totalExpectedStyles_page_three = 10; const totalExpectedStyles_page_four = 9; await page.goto(astro.resolveUrl('/client-only-three')); From cd3fb04af636c92f93b257946ab35535a5ba0b6c Mon Sep 17 00:00:00 2001 From: Matthew Phillips Date: Fri, 16 Feb 2024 08:26:12 -0500 Subject: [PATCH 03/12] Restore test expectation --- .../e2e/fixtures/view-transitions/src/components/Island.jsx | 1 + packages/astro/e2e/view-transitions.test.js | 4 ++-- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/packages/astro/e2e/fixtures/view-transitions/src/components/Island.jsx b/packages/astro/e2e/fixtures/view-transitions/src/components/Island.jsx index 21c9f1e381bf..541ca6026e19 100644 --- a/packages/astro/e2e/fixtures/view-transitions/src/components/Island.jsx +++ b/packages/astro/e2e/fixtures/view-transitions/src/components/Island.jsx @@ -1,5 +1,6 @@ import React, { useState } from 'react'; import './Island.css'; +import { indirect} from './css.js'; export default function Counter({ children, count: initialCount, id, page }) { const [count, setCount] = useState(initialCount); diff --git a/packages/astro/e2e/view-transitions.test.js b/packages/astro/e2e/view-transitions.test.js index b6e3e67d5963..9083cdb015cc 100644 --- a/packages/astro/e2e/view-transitions.test.js +++ b/packages/astro/e2e/view-transitions.test.js @@ -786,7 +786,7 @@ test.describe('View Transitions', () => { }); test('client:only styles are retained on transition (1/2)', async ({ page, astro }) => { - const totalExpectedStyles = 8; + const totalExpectedStyles = 9; await page.goto(astro.resolveUrl('/client-only-one')); let msg = page.locator('.counter-message'); @@ -805,7 +805,7 @@ test.describe('View Transitions', () => { }); test('client:only styles are retained on transition (2/2)', async ({ page, astro }) => { - const totalExpectedStyles_page_three = 10; + const totalExpectedStyles_page_three = 11; const totalExpectedStyles_page_four = 9; await page.goto(astro.resolveUrl('/client-only-three')); From 163944830157a67522262a4fb0ccbc720234b08e Mon Sep 17 00:00:00 2001 From: Matthew Phillips Date: Fri, 16 Feb 2024 08:53:29 -0500 Subject: [PATCH 04/12] Add changeset and final change --- .changeset/lovely-nails-cough.md | 18 ++++++++++++++++ packages/integrations/react/client.js | 30 ++++++++++++++++----------- 2 files changed, 36 insertions(+), 12 deletions(-) create mode 100644 .changeset/lovely-nails-cough.md diff --git a/.changeset/lovely-nails-cough.md b/.changeset/lovely-nails-cough.md new file mode 100644 index 000000000000..7024b293e21a --- /dev/null +++ b/.changeset/lovely-nails-cough.md @@ -0,0 +1,18 @@ +--- +"@astrojs/react": minor +"astro": minor +--- + +Update props on persisted islands upon navigation + +Islands which have the `transition:persist` property to keep state in `` will now have their props updated upon navigation. For example, if you have a component: + +```astro + +``` + +This component might have some internal state, such as which filters are applied. Upon navigation, this component persists, but the underlying `products` might change, for example if you are visiting a category of products, or you are performing a search. + +Previously the props will not change on navigation, and your island would have to handle updating them externally, such as with API calls. + +With this change the props are now updated, while still preserving state. diff --git a/packages/integrations/react/client.js b/packages/integrations/react/client.js index cd1b4a227c91..3fa8b28c698a 100644 --- a/packages/integrations/react/client.js +++ b/packages/integrations/react/client.js @@ -55,6 +55,14 @@ function getChildren(childString, experimentalReactChildren) { // Keep a map of roots so we can reuse them on re-renders let rootMap = new WeakMap(); +const getOrCreateRoot = (element, creator) => { + let root = rootMap.get(element); + if(!root) { + root = creator(); + rootMap.set(element, root); + } + return root; +}; export default (element) => (Component, props, { default: children, ...slotted }, { client }) => { @@ -78,22 +86,20 @@ export default (element) => } if (client === 'only') { return startTransition(() => { - let root = rootMap.get(element); - if(!root) { - root = createRoot(element); - rootMap.set(element, root); - } + const root = getOrCreateRoot(element, () => { + const root = createRoot(element); + element.addEventListener('astro:unmount', () => root.unmount(), { once: true }); + return root; + }); root.render(componentEl); - element.addEventListener('astro:unmount', () => root.unmount(), { once: true }); }); } startTransition(() => { - let root = rootMap.get(element); - if(!root) { - root = hydrateRoot(element, componentEl, renderOptions); - rootMap.set(element, root); - } + const root = getOrCreateRoot(element, () => { + const root = hydrateRoot(element, componentEl, renderOptions); + element.addEventListener('astro:unmount', () => root.unmount(), { once: true }); + return root; + }); root.render(componentEl); - element.addEventListener('astro:unmount', () => root.unmount(), { once: true }); }); }; From 385f7173dd23f58d455feec9d6f9afac51702c4b Mon Sep 17 00:00:00 2001 From: Matthew Phillips Date: Fri, 16 Feb 2024 09:53:35 -0500 Subject: [PATCH 05/12] linting --- packages/integrations/react/client.js | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/packages/integrations/react/client.js b/packages/integrations/react/client.js index 3fa8b28c698a..cfe46a919223 100644 --- a/packages/integrations/react/client.js +++ b/packages/integrations/react/client.js @@ -87,18 +87,18 @@ export default (element) => if (client === 'only') { return startTransition(() => { const root = getOrCreateRoot(element, () => { - const root = createRoot(element); - element.addEventListener('astro:unmount', () => root.unmount(), { once: true }); - return root; + const r = createRoot(element); + element.addEventListener('astro:unmount', () => r.unmount(), { once: true }); + return r; }); root.render(componentEl); }); } startTransition(() => { const root = getOrCreateRoot(element, () => { - const root = hydrateRoot(element, componentEl, renderOptions); - element.addEventListener('astro:unmount', () => root.unmount(), { once: true }); - return root; + const r = hydrateRoot(element, componentEl, renderOptions); + element.addEventListener('astro:unmount', () => r.unmount(), { once: true }); + return r; }); root.render(componentEl); }); From 0abaf4eee2402affa5e882a7130ec4e16ab022d4 Mon Sep 17 00:00:00 2001 From: Matthew Phillips Date: Tue, 5 Mar 2024 12:33:27 -0500 Subject: [PATCH 06/12] Implement transition:persist-props behavior --- .../src/pages/island-one.astro | 5 +++- packages/astro/e2e/view-transitions.test.js | 28 +++++++++++++++++++ packages/astro/package.json | 2 +- .../astro/src/runtime/server/hydration.ts | 3 +- packages/astro/src/transitions/router.ts | 7 ++++- pnpm-lock.yaml | 10 +++---- 6 files changed, 46 insertions(+), 9 deletions(-) diff --git a/packages/astro/e2e/fixtures/view-transitions/src/pages/island-one.astro b/packages/astro/e2e/fixtures/view-transitions/src/pages/island-one.astro index f79a60f73621..51ed9ec995d8 100644 --- a/packages/astro/e2e/fixtures/view-transitions/src/pages/island-one.astro +++ b/packages/astro/e2e/fixtures/view-transitions/src/pages/island-one.astro @@ -1,9 +1,12 @@ --- import Layout from '../components/Layout.astro'; import Island from '../components/Island.jsx'; + +const persistProps = true; ---

Page 1

go to 2 - +
diff --git a/packages/astro/e2e/view-transitions.test.js b/packages/astro/e2e/view-transitions.test.js index 9083cdb015cc..d9472280e3ae 100644 --- a/packages/astro/e2e/view-transitions.test.js +++ b/packages/astro/e2e/view-transitions.test.js @@ -549,6 +549,34 @@ test.describe('View Transitions', () => { await expect(pageTitle).toHaveText('Island 2'); }); + test('transition:persist-props prevents props from changing', async ({ page, astro }) => { + // Go to page 1 + await page.goto(astro.resolveUrl('/island-one')); + + // Navigate to page 2 + await page.click('#click-two'); + const p = page.locator('#island-two'); + await expect(p).toBeVisible(); + + // Props should have changed + const pageTitle = page.locator('.page'); + await expect(pageTitle).toHaveText('Island 1'); + }); + + test('transition:persist-props=false makes props update', async ({ page, astro }) => { + // Go to page 2 + await page.goto(astro.resolveUrl('/island-two')); + + // Navigate to page 1 + await page.click('#click-one'); + const p = page.locator('#island-one'); + await expect(p).toBeVisible(); + + // Props should have changed + const pageTitle = page.locator('.page'); + await expect(pageTitle).toHaveText('Island 1'); + }); + test('Scripts are only executed once', async ({ page, astro }) => { // Go to page 1 await page.goto(astro.resolveUrl('/one')); diff --git a/packages/astro/package.json b/packages/astro/package.json index 2399ed3e14da..2fd8d2657546 100644 --- a/packages/astro/package.json +++ b/packages/astro/package.json @@ -114,7 +114,7 @@ "test:node": "astro-scripts test \"test/**/*.nodetest.js\"" }, "dependencies": { - "@astrojs/compiler": "^2.5.3", + "@astrojs/compiler": "^2.7.0", "@astrojs/internal-helpers": "workspace:*", "@astrojs/markdown-remark": "workspace:*", "@astrojs/telemetry": "workspace:*", diff --git a/packages/astro/src/runtime/server/hydration.ts b/packages/astro/src/runtime/server/hydration.ts index 4c8b71ba8843..28b5ff674e19 100644 --- a/packages/astro/src/runtime/server/hydration.ts +++ b/packages/astro/src/runtime/server/hydration.ts @@ -27,6 +27,7 @@ interface ExtractedProps { const transitionDirectivesToCopyOnIsland = Object.freeze([ 'data-astro-transition-scope', 'data-astro-transition-persist', + 'data-astro-transition-persist-props', ]); // Used to extract the directives, aka `client:load` information about a component. @@ -175,7 +176,7 @@ export async function generateHydrateScript( ); transitionDirectivesToCopyOnIsland.forEach((name) => { - if (props[name]) { + if (typeof props[name] !== 'undefined') { island.props[name] = props[name]; } }); diff --git a/packages/astro/src/transitions/router.ts b/packages/astro/src/transitions/router.ts index 92586202eb1b..7882a913d1e8 100644 --- a/packages/astro/src/transitions/router.ts +++ b/packages/astro/src/transitions/router.ts @@ -328,6 +328,11 @@ async function updateDOM( } }; + const shouldCopyProps = (el: HTMLElement): boolean => { + const persistProps = el.dataset.astroTransitionPersistProps; + return persistProps == null || persistProps === 'false'; + } + const defaultSwap = (beforeSwapEvent: TransitionBeforeSwapEvent) => { // swap attributes of the html element // - delete all attributes from the current document @@ -389,7 +394,7 @@ async function updateDOM( // from the old page so that state is preserved. newEl.replaceWith(el); // For islands, copy over the props to allow them to re-render - if(newEl.localName === 'astro-island') { + if(newEl.localName === 'astro-island' && shouldCopyProps(el as HTMLElement)) { el.setAttribute('ssr', ''); el.setAttribute('props', newEl.getAttribute('props')!); } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index b264f122d93a..e6c1393c7bf6 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -495,8 +495,8 @@ importers: packages/astro: dependencies: '@astrojs/compiler': - specifier: ^2.5.3 - version: 2.5.3 + specifier: ^2.7.0 + version: 2.7.0 '@astrojs/internal-helpers': specifier: workspace:* version: link:../internal-helpers @@ -5341,8 +5341,8 @@ packages: resolution: {integrity: sha512-o/ObKgtMzl8SlpIdzaxFnt7SATKPxu4oIP/1NL+HDJRzxfJcAkOTAb/ZKMRyULbz4q+1t2/DAebs2Z1QairkZw==} dev: true - /@astrojs/compiler@2.5.3: - resolution: {integrity: sha512-jzj01BRv/fmo+9Mr2FhocywGzEYiyiP2GVHje1ziGNU6c97kwhYGsnvwMkHrncAy9T9Vi54cjaMK7UE4ClX4vA==} + /@astrojs/compiler@2.7.0: + resolution: {integrity: sha512-XpC8MAaWjD1ff6/IfkRq/5k1EFj6zhCNqXRd5J43SVJEBj/Bsmizkm8N0xOYscGcDFQkRgEw6/eKnI5x/1l6aA==} /@astrojs/language-server@2.5.5(prettier-plugin-astro@0.12.3)(prettier@3.1.1)(typescript@5.2.2): resolution: {integrity: sha512-hk7a8S7bpf//BOA6mMjiYqi/eiYtGPfUfw59eVXdutdRFdwDHtu4jcsLu43ZaId56pAcE8qFjIvJxySvzcxiUA==} @@ -5356,7 +5356,7 @@ packages: prettier-plugin-astro: optional: true dependencies: - '@astrojs/compiler': 2.5.3 + '@astrojs/compiler': 2.7.0 '@jridgewell/sourcemap-codec': 1.4.15 '@volar/kit': 1.10.10(typescript@5.2.2) '@volar/language-core': 1.10.10 From d0a7bb03e735592812716a5b6b0ef46637261b19 Mon Sep 17 00:00:00 2001 From: Matthew Phillips Date: Tue, 5 Mar 2024 12:41:22 -0500 Subject: [PATCH 07/12] Fix lockfile --- pnpm-lock.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 25df4dc92aab..f4ae20969d01 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -5556,7 +5556,7 @@ packages: prettier-plugin-astro: optional: true dependencies: - '@astrojs/compiler': 2.5.3 + '@astrojs/compiler': 2.7.0 '@jridgewell/sourcemap-codec': 1.4.15 '@volar/kit': 2.0.4(typescript@5.3.2) '@volar/language-core': 2.0.4 From b4b742de2d76a0233bf7c9dd26ee7c0ea65061a2 Mon Sep 17 00:00:00 2001 From: Matthew Phillips Date: Tue, 5 Mar 2024 13:05:12 -0500 Subject: [PATCH 08/12] Fix expectations --- .../e2e/fixtures/view-transitions/src/pages/island-one.astro | 2 +- packages/astro/e2e/view-transitions.test.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/astro/e2e/fixtures/view-transitions/src/pages/island-one.astro b/packages/astro/e2e/fixtures/view-transitions/src/pages/island-one.astro index 51ed9ec995d8..80e4572a777d 100644 --- a/packages/astro/e2e/fixtures/view-transitions/src/pages/island-one.astro +++ b/packages/astro/e2e/fixtures/view-transitions/src/pages/island-one.astro @@ -2,7 +2,7 @@ import Layout from '../components/Layout.astro'; import Island from '../components/Island.jsx'; -const persistProps = true; +const persistProps = Astro.url.searchParams.has('persist'); ---

Page 1

diff --git a/packages/astro/e2e/view-transitions.test.js b/packages/astro/e2e/view-transitions.test.js index d9472280e3ae..b963bf2fd7f4 100644 --- a/packages/astro/e2e/view-transitions.test.js +++ b/packages/astro/e2e/view-transitions.test.js @@ -551,7 +551,7 @@ test.describe('View Transitions', () => { test('transition:persist-props prevents props from changing', async ({ page, astro }) => { // Go to page 1 - await page.goto(astro.resolveUrl('/island-one')); + await page.goto(astro.resolveUrl('/island-one?persist')); // Navigate to page 2 await page.click('#click-two'); From dce12fcfc73f2cb464718ec11726affdeafb0583 Mon Sep 17 00:00:00 2001 From: Matthew Phillips Date: Tue, 5 Mar 2024 14:33:02 -0500 Subject: [PATCH 09/12] App is hyrid --- .../e2e/fixtures/view-transitions/src/pages/island-one.astro | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/astro/e2e/fixtures/view-transitions/src/pages/island-one.astro b/packages/astro/e2e/fixtures/view-transitions/src/pages/island-one.astro index 80e4572a777d..883d567a118f 100644 --- a/packages/astro/e2e/fixtures/view-transitions/src/pages/island-one.astro +++ b/packages/astro/e2e/fixtures/view-transitions/src/pages/island-one.astro @@ -1,6 +1,7 @@ --- import Layout from '../components/Layout.astro'; import Island from '../components/Island.jsx'; +export const prerender = false; const persistProps = Astro.url.searchParams.has('persist'); --- From 78259db91c88033334141dc8f4fdeea335532c9e Mon Sep 17 00:00:00 2001 From: Matthew Phillips Date: Thu, 7 Mar 2024 13:03:12 -0500 Subject: [PATCH 10/12] Update .changeset/lovely-nails-cough.md Co-authored-by: Sarah Rainsberger --- .changeset/lovely-nails-cough.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.changeset/lovely-nails-cough.md b/.changeset/lovely-nails-cough.md index 7024b293e21a..e073bccbf53e 100644 --- a/.changeset/lovely-nails-cough.md +++ b/.changeset/lovely-nails-cough.md @@ -3,7 +3,7 @@ "astro": minor --- -Update props on persisted islands upon navigation +Changes the default behavior of `transition:persist` to update the props of persisted islands upon navigation. Also adds a new view transitions option `transition:persist-props` (default: `false`) to prevent props from updating as needed. Islands which have the `transition:persist` property to keep state in `` will now have their props updated upon navigation. For example, if you have a component: From 583aefc4560418bc881af1282490366ac53ad1ac Mon Sep 17 00:00:00 2001 From: Matthew Phillips Date: Thu, 7 Mar 2024 13:03:26 -0500 Subject: [PATCH 11/12] Update .changeset/lovely-nails-cough.md Co-authored-by: Sarah Rainsberger --- .changeset/lovely-nails-cough.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/.changeset/lovely-nails-cough.md b/.changeset/lovely-nails-cough.md index e073bccbf53e..dc4145a28b97 100644 --- a/.changeset/lovely-nails-cough.md +++ b/.changeset/lovely-nails-cough.md @@ -5,7 +5,9 @@ Changes the default behavior of `transition:persist` to update the props of persisted islands upon navigation. Also adds a new view transitions option `transition:persist-props` (default: `false`) to prevent props from updating as needed. -Islands which have the `transition:persist` property to keep state in `` will now have their props updated upon navigation. For example, if you have a component: +Islands which have the `transition:persist` property to keep their state when using the `` router will now have their props updated upon navigation. This is useful in cases where the component relies on page-specific props, such as the current page title, which should update upon navigation. + +For example, the component below is set to persist across navigation. This component receives a `products` props and might have some internal state, such as which filters are applied: ```astro From 4a99bab58c22f18e68c6c70bd17cfca0145003cd Mon Sep 17 00:00:00 2001 From: Matthew Phillips Date: Thu, 7 Mar 2024 13:04:18 -0500 Subject: [PATCH 12/12] Update .changeset/lovely-nails-cough.md Co-authored-by: Sarah Rainsberger --- .changeset/lovely-nails-cough.md | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/.changeset/lovely-nails-cough.md b/.changeset/lovely-nails-cough.md index dc4145a28b97..4aecb48d141d 100644 --- a/.changeset/lovely-nails-cough.md +++ b/.changeset/lovely-nails-cough.md @@ -13,8 +13,14 @@ For example, the component below is set to persist across navigation. This compo ``` -This component might have some internal state, such as which filters are applied. Upon navigation, this component persists, but the underlying `products` might change, for example if you are visiting a category of products, or you are performing a search. +Upon navigation, this component persists, but the desired `products` might change, for example if you are visiting a category of products, or you are performing a search. -Previously the props will not change on navigation, and your island would have to handle updating them externally, such as with API calls. +Previously the props would not change on navigation, and your island would have to handle updating them externally, such as with API calls. With this change the props are now updated, while still preserving state. + +You can override this new default behavior on a per-component basis using `transition:persist-props=true` to persist both props and state during navigation: + +```astro + +```