From edb0fc7485f311e888e6d41b824e2b35192a8116 Mon Sep 17 00:00:00 2001 From: Pascal Baljet Date: Tue, 15 Jul 2025 12:31:42 +0200 Subject: [PATCH 1/5] WIP failing test --- packages/react/test-app/Pages/LongPage.jsx | 97 ++++++++++++++++++++++ tests/app/server.js | 8 ++ tests/links.spec.ts | 18 ++++ 3 files changed, 123 insertions(+) create mode 100644 packages/react/test-app/Pages/LongPage.jsx diff --git a/packages/react/test-app/Pages/LongPage.jsx b/packages/react/test-app/Pages/LongPage.jsx new file mode 100644 index 000000000..2d97361bb --- /dev/null +++ b/packages/react/test-app/Pages/LongPage.jsx @@ -0,0 +1,97 @@ +import { Link } from '@inertiajs/react' +import { useEffect, useState } from 'react' + +export default ({ page }) => { + const [documentScrollTop, setDocumentScrollTop] = useState(0) + + const handleScrollEvent = () => { + setDocumentScrollTop(document.documentElement.scrollTop) + } + + useEffect(() => { + document.addEventListener('scroll', handleScrollEvent) + return () => document.removeEventListener('scroll', handleScrollEvent) + }) + + return Array.from({ length: 3000 }, (_, i) => ( + <> + {i === 0 && ( +

Page {page}

+ )} +

Article Header

+
+

+ Sunt culpa sit sunt enim aliquip. Esse ea ea quis voluptate. Enim consectetur aliqua ex ex magna cupidatat id + minim sit elit. Amet pariatur occaecat pariatur duis eiusmod dolore magna. Et commodo cupidatat in commodo + elit cupidatat minim qui id non enim ad. Culpa aliquip ad Lorem sit consectetur ullamco culpa duis nisi et + fugiat mollit eiusmod. Laboris voluptate veniam consequat proident in nulla irure velit. +

+

+ Sit sint laboris sunt eiusmod ipsum laborum eiusmod amet commodo exercitation in duis magna. Proident sunt + minim in elit qui. Id pariatur commodo fugiat excepteur in deserunt Lorem ipsum occaecat est. Excepteur sit + tempor ipsum ex officia veniam enim amet velit fugiat mollit cillum. Incididunt aliqua nulla id occaecat + nulla. Non ea ad est occaecat deserunt officia qui commodo exercitation. +

+

+ Voluptate laborum quis aliqua ullamco magna amet ullamco laborum qui cillum eu. Dolore dolore aliqua proident + proident sunt ipsum in. Enim velit dolore labore dolor quis incididunt duis culpa Lorem. Eu adipisicing non + elit fugiat voluptate labore ipsum dolore consectetur commodo. Et in et cillum duis consequat quis ex eu + commodo. Eiusmod aliqua excepteur consectetur eiusmod aute et consectetur sit pariatur dolore qui officia + pariatur. +

+

+ Non sunt eu mollit qui reprehenderit. Aute culpa anim voluptate do in esse duis laborum ad dolore. Ullamco + nisi in nostrud officia do. Duis pariatur officia id duis. Deserunt ad incididunt est sint consectetur + reprehenderit mollit est Lorem ea pariatur anim dolor adipisicing. Nostrud irure magna nostrud laboris aute + sunt veniam laboris veniam incididunt sit. Nulla proident ad aliqua fugiat culpa sunt est in dolor velit ad + irure nulla. +

+

+ Do aute laborum deserunt non laborum voluptate voluptate. Anim ut laborum magna sunt cupidatat irure. + Cupidatat fugiat minim sint cillum laborum excepteur irure id est irure ad occaecat adipisicing enim. Deserunt + nulla anim proident velit irure nostrud est est reprehenderit consequat pariatur qui. Fugiat Lorem sint eu + laborum minim pariatur cillum mollit nulla consequat ullamco ex. Ex consectetur ad ut irure fugiat occaecat + aliqua exercitation cillum ipsum anim dolore tempor. +

+

+ Adipisicing consequat irure fugiat Lorem deserunt aliquip do cupidatat. Lorem labore elit ex qui nostrud qui + cillum sunt adipisicing occaecat. Sunt nostrud amet amet cupidatat fugiat Lorem quis nulla id cillum esse eu. + Ullamco aliqua dolore irure amet mollit anim velit dolore. +

+

+ Veniam cupidatat ipsum ea officia ipsum nisi laborum culpa qui dolore. Aliqua Lorem nisi labore ea velit + aliquip irure excepteur eu. Laboris proident duis non labore sunt quis aute tempor laboris enim anim eiusmod. +

+

+ Minim proident ut aliqua ea ut culpa fugiat ullamco nisi esse nostrud reprehenderit id. Id id ullamco velit + anim nisi magna Lorem tempor. Et veniam occaecat ut labore consequat fugiat duis. +

+

+ Adipisicing ea consectetur adipisicing aute eu pariatur enim labore consequat occaecat consectetur minim nisi. + Cillum commodo sunt labore reprehenderit. Duis esse excepteur magna tempor eiusmod exercitation Lorem + reprehenderit excepteur pariatur. Esse cupidatat occaecat magna do aliquip Lorem. Consectetur adipisicing + consequat dolore nostrud esse eu cillum id commodo duis. Aliquip dolor cillum cupidatat fugiat. +

+

+ Ex eiusmod id est laborum sunt ex ea aute adipisicing ad magna deserunt duis. Nostrud velit dolore id commodo + quis enim fugiat. Sint non quis consectetur voluptate aliqua dolore ad voluptate nulla. Irure sit + reprehenderit sint laboris non elit. Duis minim nisi esse dolor. Sit ex in consequat non occaecat commodo + irure et. Commodo qui ipsum Lorem magna consequat consequat et minim eiusmod Lorem eiusmod cupidatat + voluptate. +

+ + {i === 0 && ( + <> +
+ Document scroll top position is {documentScrollTop} +
+ + + Go to page {parseInt(page) + 1} + + + )} +
+ + )) +} \ No newline at end of file diff --git a/tests/app/server.js b/tests/app/server.js index 957043bd4..e3e6a89bf 100644 --- a/tests/app/server.js +++ b/tests/app/server.js @@ -57,6 +57,14 @@ app.get('/article', (req, res) => }), ) +app.get('/long-page/:page', (req, res) => + inertia.render(req, res, { + component: 'LongPage', + props: { page: req.params.page }, + encryptHistory: true, + }), +) + app.get('/links/partial-reloads', (req, res) => inertia.render(req, res, { component: 'Links/PartialReloads', diff --git a/tests/links.spec.ts b/tests/links.spec.ts index 229ecb32f..3b725df5c 100644 --- a/tests/links.spec.ts +++ b/tests/links.spec.ts @@ -671,6 +671,24 @@ test('does not scroll when clicking the same fragment link', async ({ page }) => await expect(page.getByText('Scroll log: []')).toBeVisible() }) +test('does not scroll to top until page is rendered', async ({ page }) => { + /** @see https://github.com/inertiajs/inertia/issues/2125 */ + await page.goto('/long-page/1') + await expect(page.getByText('Page 1')).toBeVisible() + + await scrollElementTo( + page, + page.evaluate(() => window.scrollTo(0, 1500)), + ) + + await expect(page.getByText('Document scroll top position is 1500')).toBeVisible() + + await page.getByRole('link', { name: 'Go to page 2' }).click() + + await expect(page.getByText('Document scroll top position is 0')).toBeVisible() + await expect(page.getByText('Page 2')).toBeVisible() +}) + test.describe('partial reloads', () => { test.beforeEach(async ({ page }) => { pageLoads.watch(page) From d347232262baf7bec2d39dc08837c7ea0af0a0f2 Mon Sep 17 00:00:00 2001 From: Pascal Baljet Date: Tue, 15 Jul 2025 13:33:30 +0200 Subject: [PATCH 2/5] WIP --- packages/react/test-app/Pages/LongPage.jsx | 32 ++++++---------------- packages/vue3/src/app.ts | 3 ++ 2 files changed, 11 insertions(+), 24 deletions(-) diff --git a/packages/react/test-app/Pages/LongPage.jsx b/packages/react/test-app/Pages/LongPage.jsx index 2d97361bb..cdb2b3166 100644 --- a/packages/react/test-app/Pages/LongPage.jsx +++ b/packages/react/test-app/Pages/LongPage.jsx @@ -2,23 +2,14 @@ import { Link } from '@inertiajs/react' import { useEffect, useState } from 'react' export default ({ page }) => { - const [documentScrollTop, setDocumentScrollTop] = useState(0) - - const handleScrollEvent = () => { - setDocumentScrollTop(document.documentElement.scrollTop) - } - useEffect(() => { - document.addEventListener('scroll', handleScrollEvent) - return () => document.removeEventListener('scroll', handleScrollEvent) - }) + console.log('LongPage mounted!' + Date.now()) + }, []); return Array.from({ length: 3000 }, (_, i) => ( <> - {i === 0 && ( -

Page {page}

- )}

Article Header

+ {i === 0 && (

Page {page}

)}

Sunt culpa sit sunt enim aliquip. Esse ea ea quis voluptate. Enim consectetur aliqua ex ex magna cupidatat id @@ -26,6 +17,11 @@ export default ({ page }) => { elit cupidatat minim qui id non enim ad. Culpa aliquip ad Lorem sit consectetur ullamco culpa duis nisi et fugiat mollit eiusmod. Laboris voluptate veniam consequat proident in nulla irure velit.

+ {i === 0 && ( + + Go to page {parseInt(page) + 1} + + )}

Sit sint laboris sunt eiusmod ipsum laborum eiusmod amet commodo exercitation in duis magna. Proident sunt minim in elit qui. Id pariatur commodo fugiat excepteur in deserunt Lorem ipsum occaecat est. Excepteur sit @@ -79,18 +75,6 @@ export default ({ page }) => { irure et. Commodo qui ipsum Lorem magna consequat consequat et minim eiusmod Lorem eiusmod cupidatat voluptate.

- - {i === 0 && ( - <> -
- Document scroll top position is {documentScrollTop} -
- - - Go to page {parseInt(page) + 1} - - - )}
)) diff --git a/packages/vue3/src/app.ts b/packages/vue3/src/app.ts index 51340187a..cff487cfe 100755 --- a/packages/vue3/src/app.ts +++ b/packages/vue3/src/app.ts @@ -5,6 +5,7 @@ import { defineComponent, h, markRaw, + nextTick, Plugin, PropType, reactive, @@ -73,6 +74,8 @@ const App: InertiaApp = defineComponent({ component.value = markRaw(args.component) page.value = args.page key.value = args.preserveState ? key.value : Date.now() + + return nextTick() }, }) From ff16a98b632c63d61af2de84f773c9bc11554607 Mon Sep 17 00:00:00 2001 From: Pascal Baljet Date: Tue, 15 Jul 2025 13:35:30 +0200 Subject: [PATCH 3/5] Update App.ts --- packages/react/src/App.ts | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/packages/react/src/App.ts b/packages/react/src/App.ts index fcf14ab80..e841dbfce 100755 --- a/packages/react/src/App.ts +++ b/packages/react/src/App.ts @@ -5,6 +5,7 @@ import PageContext from './PageContext' let currentIsInitialPage = true let routerIsInitialized = false +let swapPromise = null let swapComponent: PageHandler = async () => { // Dummy function so we can init the router outside of the useEffect hook. This is // needed so `router.reload()` works right away (on mount) in any of the user's @@ -58,11 +59,20 @@ export default function App({ page, key: preserveState ? current.key : Date.now(), })) + + return new Promise((resolve) => { + swapPromise = resolve + }) } router.on('navigate', () => headManager.forceUpdate()) }, []) + useEffect(() => { + swapPromise?.() + swapPromise = null + }, [swapPromise]) + if (!current.component) { return createElement( HeadContext.Provider, From e245e2a2cdb0332c27418c001ac423d97de0abeb Mon Sep 17 00:00:00 2001 From: Pascal Baljet Date: Tue, 15 Jul 2025 13:41:34 +0200 Subject: [PATCH 4/5] WIP --- tests/app/server.js | 1 - tests/links.spec.ts | 18 ------------------ 2 files changed, 19 deletions(-) diff --git a/tests/app/server.js b/tests/app/server.js index e3e6a89bf..bf5238254 100644 --- a/tests/app/server.js +++ b/tests/app/server.js @@ -61,7 +61,6 @@ app.get('/long-page/:page', (req, res) => inertia.render(req, res, { component: 'LongPage', props: { page: req.params.page }, - encryptHistory: true, }), ) diff --git a/tests/links.spec.ts b/tests/links.spec.ts index 3b725df5c..229ecb32f 100644 --- a/tests/links.spec.ts +++ b/tests/links.spec.ts @@ -671,24 +671,6 @@ test('does not scroll when clicking the same fragment link', async ({ page }) => await expect(page.getByText('Scroll log: []')).toBeVisible() }) -test('does not scroll to top until page is rendered', async ({ page }) => { - /** @see https://github.com/inertiajs/inertia/issues/2125 */ - await page.goto('/long-page/1') - await expect(page.getByText('Page 1')).toBeVisible() - - await scrollElementTo( - page, - page.evaluate(() => window.scrollTo(0, 1500)), - ) - - await expect(page.getByText('Document scroll top position is 1500')).toBeVisible() - - await page.getByRole('link', { name: 'Go to page 2' }).click() - - await expect(page.getByText('Document scroll top position is 0')).toBeVisible() - await expect(page.getByText('Page 2')).toBeVisible() -}) - test.describe('partial reloads', () => { test.beforeEach(async ({ page }) => { pageLoads.watch(page) From 69e9490a30b3c718b87e73c7ad3b104ffb211b82 Mon Sep 17 00:00:00 2001 From: pascalbaljet <8403149+pascalbaljet@users.noreply.github.com> Date: Tue, 30 Sep 2025 14:44:58 +0000 Subject: [PATCH 5/5] Fix code style --- packages/react/test-app/Pages/LongPage.jsx | 154 ++++++++++----------- 1 file changed, 77 insertions(+), 77 deletions(-) diff --git a/packages/react/test-app/Pages/LongPage.jsx b/packages/react/test-app/Pages/LongPage.jsx index cdb2b3166..7512db13d 100644 --- a/packages/react/test-app/Pages/LongPage.jsx +++ b/packages/react/test-app/Pages/LongPage.jsx @@ -1,81 +1,81 @@ import { Link } from '@inertiajs/react' -import { useEffect, useState } from 'react' +import { useEffect } from 'react' export default ({ page }) => { - useEffect(() => { - console.log('LongPage mounted!' + Date.now()) - }, []); + useEffect(() => { + console.log('LongPage mounted!' + Date.now()) + }, []) - return Array.from({ length: 3000 }, (_, i) => ( - <> -

Article Header

- {i === 0 && (

Page {page}

)} -
-

- Sunt culpa sit sunt enim aliquip. Esse ea ea quis voluptate. Enim consectetur aliqua ex ex magna cupidatat id - minim sit elit. Amet pariatur occaecat pariatur duis eiusmod dolore magna. Et commodo cupidatat in commodo - elit cupidatat minim qui id non enim ad. Culpa aliquip ad Lorem sit consectetur ullamco culpa duis nisi et - fugiat mollit eiusmod. Laboris voluptate veniam consequat proident in nulla irure velit. -

- {i === 0 && ( - - Go to page {parseInt(page) + 1} - - )} -

- Sit sint laboris sunt eiusmod ipsum laborum eiusmod amet commodo exercitation in duis magna. Proident sunt - minim in elit qui. Id pariatur commodo fugiat excepteur in deserunt Lorem ipsum occaecat est. Excepteur sit - tempor ipsum ex officia veniam enim amet velit fugiat mollit cillum. Incididunt aliqua nulla id occaecat - nulla. Non ea ad est occaecat deserunt officia qui commodo exercitation. -

-

- Voluptate laborum quis aliqua ullamco magna amet ullamco laborum qui cillum eu. Dolore dolore aliqua proident - proident sunt ipsum in. Enim velit dolore labore dolor quis incididunt duis culpa Lorem. Eu adipisicing non - elit fugiat voluptate labore ipsum dolore consectetur commodo. Et in et cillum duis consequat quis ex eu - commodo. Eiusmod aliqua excepteur consectetur eiusmod aute et consectetur sit pariatur dolore qui officia - pariatur. -

-

- Non sunt eu mollit qui reprehenderit. Aute culpa anim voluptate do in esse duis laborum ad dolore. Ullamco - nisi in nostrud officia do. Duis pariatur officia id duis. Deserunt ad incididunt est sint consectetur - reprehenderit mollit est Lorem ea pariatur anim dolor adipisicing. Nostrud irure magna nostrud laboris aute - sunt veniam laboris veniam incididunt sit. Nulla proident ad aliqua fugiat culpa sunt est in dolor velit ad - irure nulla. -

-

- Do aute laborum deserunt non laborum voluptate voluptate. Anim ut laborum magna sunt cupidatat irure. - Cupidatat fugiat minim sint cillum laborum excepteur irure id est irure ad occaecat adipisicing enim. Deserunt - nulla anim proident velit irure nostrud est est reprehenderit consequat pariatur qui. Fugiat Lorem sint eu - laborum minim pariatur cillum mollit nulla consequat ullamco ex. Ex consectetur ad ut irure fugiat occaecat - aliqua exercitation cillum ipsum anim dolore tempor. -

-

- Adipisicing consequat irure fugiat Lorem deserunt aliquip do cupidatat. Lorem labore elit ex qui nostrud qui - cillum sunt adipisicing occaecat. Sunt nostrud amet amet cupidatat fugiat Lorem quis nulla id cillum esse eu. - Ullamco aliqua dolore irure amet mollit anim velit dolore. -

-

- Veniam cupidatat ipsum ea officia ipsum nisi laborum culpa qui dolore. Aliqua Lorem nisi labore ea velit - aliquip irure excepteur eu. Laboris proident duis non labore sunt quis aute tempor laboris enim anim eiusmod. -

-

- Minim proident ut aliqua ea ut culpa fugiat ullamco nisi esse nostrud reprehenderit id. Id id ullamco velit - anim nisi magna Lorem tempor. Et veniam occaecat ut labore consequat fugiat duis. -

-

- Adipisicing ea consectetur adipisicing aute eu pariatur enim labore consequat occaecat consectetur minim nisi. - Cillum commodo sunt labore reprehenderit. Duis esse excepteur magna tempor eiusmod exercitation Lorem - reprehenderit excepteur pariatur. Esse cupidatat occaecat magna do aliquip Lorem. Consectetur adipisicing - consequat dolore nostrud esse eu cillum id commodo duis. Aliquip dolor cillum cupidatat fugiat. -

-

- Ex eiusmod id est laborum sunt ex ea aute adipisicing ad magna deserunt duis. Nostrud velit dolore id commodo - quis enim fugiat. Sint non quis consectetur voluptate aliqua dolore ad voluptate nulla. Irure sit - reprehenderit sint laboris non elit. Duis minim nisi esse dolor. Sit ex in consequat non occaecat commodo - irure et. Commodo qui ipsum Lorem magna consequat consequat et minim eiusmod Lorem eiusmod cupidatat - voluptate. -

-
- - )) -} \ No newline at end of file + return Array.from({ length: 3000 }, (_, i) => ( + <> +

Article Header

+ {i === 0 &&

Page {page}

} +
+

+ Sunt culpa sit sunt enim aliquip. Esse ea ea quis voluptate. Enim consectetur aliqua ex ex magna cupidatat id + minim sit elit. Amet pariatur occaecat pariatur duis eiusmod dolore magna. Et commodo cupidatat in commodo + elit cupidatat minim qui id non enim ad. Culpa aliquip ad Lorem sit consectetur ullamco culpa duis nisi et + fugiat mollit eiusmod. Laboris voluptate veniam consequat proident in nulla irure velit. +

+ {i === 0 && ( + + Go to page {parseInt(page) + 1} + + )} +

+ Sit sint laboris sunt eiusmod ipsum laborum eiusmod amet commodo exercitation in duis magna. Proident sunt + minim in elit qui. Id pariatur commodo fugiat excepteur in deserunt Lorem ipsum occaecat est. Excepteur sit + tempor ipsum ex officia veniam enim amet velit fugiat mollit cillum. Incididunt aliqua nulla id occaecat + nulla. Non ea ad est occaecat deserunt officia qui commodo exercitation. +

+

+ Voluptate laborum quis aliqua ullamco magna amet ullamco laborum qui cillum eu. Dolore dolore aliqua proident + proident sunt ipsum in. Enim velit dolore labore dolor quis incididunt duis culpa Lorem. Eu adipisicing non + elit fugiat voluptate labore ipsum dolore consectetur commodo. Et in et cillum duis consequat quis ex eu + commodo. Eiusmod aliqua excepteur consectetur eiusmod aute et consectetur sit pariatur dolore qui officia + pariatur. +

+

+ Non sunt eu mollit qui reprehenderit. Aute culpa anim voluptate do in esse duis laborum ad dolore. Ullamco + nisi in nostrud officia do. Duis pariatur officia id duis. Deserunt ad incididunt est sint consectetur + reprehenderit mollit est Lorem ea pariatur anim dolor adipisicing. Nostrud irure magna nostrud laboris aute + sunt veniam laboris veniam incididunt sit. Nulla proident ad aliqua fugiat culpa sunt est in dolor velit ad + irure nulla. +

+

+ Do aute laborum deserunt non laborum voluptate voluptate. Anim ut laborum magna sunt cupidatat irure. + Cupidatat fugiat minim sint cillum laborum excepteur irure id est irure ad occaecat adipisicing enim. Deserunt + nulla anim proident velit irure nostrud est est reprehenderit consequat pariatur qui. Fugiat Lorem sint eu + laborum minim pariatur cillum mollit nulla consequat ullamco ex. Ex consectetur ad ut irure fugiat occaecat + aliqua exercitation cillum ipsum anim dolore tempor. +

+

+ Adipisicing consequat irure fugiat Lorem deserunt aliquip do cupidatat. Lorem labore elit ex qui nostrud qui + cillum sunt adipisicing occaecat. Sunt nostrud amet amet cupidatat fugiat Lorem quis nulla id cillum esse eu. + Ullamco aliqua dolore irure amet mollit anim velit dolore. +

+

+ Veniam cupidatat ipsum ea officia ipsum nisi laborum culpa qui dolore. Aliqua Lorem nisi labore ea velit + aliquip irure excepteur eu. Laboris proident duis non labore sunt quis aute tempor laboris enim anim eiusmod. +

+

+ Minim proident ut aliqua ea ut culpa fugiat ullamco nisi esse nostrud reprehenderit id. Id id ullamco velit + anim nisi magna Lorem tempor. Et veniam occaecat ut labore consequat fugiat duis. +

+

+ Adipisicing ea consectetur adipisicing aute eu pariatur enim labore consequat occaecat consectetur minim nisi. + Cillum commodo sunt labore reprehenderit. Duis esse excepteur magna tempor eiusmod exercitation Lorem + reprehenderit excepteur pariatur. Esse cupidatat occaecat magna do aliquip Lorem. Consectetur adipisicing + consequat dolore nostrud esse eu cillum id commodo duis. Aliquip dolor cillum cupidatat fugiat. +

+

+ Ex eiusmod id est laborum sunt ex ea aute adipisicing ad magna deserunt duis. Nostrud velit dolore id commodo + quis enim fugiat. Sint non quis consectetur voluptate aliqua dolore ad voluptate nulla. Irure sit + reprehenderit sint laboris non elit. Duis minim nisi esse dolor. Sit ex in consequat non occaecat commodo + irure et. Commodo qui ipsum Lorem magna consequat consequat et minim eiusmod Lorem eiusmod cupidatat + voluptate. +

+
+ + )) +}