Skip to content

Commit 2db746c

Browse files
fix: navigate() respects rewrites when reloadDocument=true (#5389)
1 parent 42500ce commit 2db746c

File tree

16 files changed

+348
-14
lines changed

16 files changed

+348
-14
lines changed
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
node_modules
2+
.DS_Store
3+
dist
4+
dist-hash
5+
dist-ssr
6+
*.local
7+
8+
/test-results/
9+
/playwright-report/
10+
/blob-report/
11+
/playwright/.cache/
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
<!doctype html>
2+
<html lang="en">
3+
<head>
4+
<meta charset="UTF-8" />
5+
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
6+
</head>
7+
<body>
8+
<div id="app"></div>
9+
<script type="module" src="/src/main.tsx"></script>
10+
</body>
11+
</html>
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
{
2+
"name": "tanstack-router-e2e-react-basepath-file-based",
3+
"private": true,
4+
"type": "module",
5+
"scripts": {
6+
"dev": "vite --port 3000",
7+
"dev:e2e": "vite",
8+
"build": "vite build && tsc --noEmit",
9+
"serve": "vite preview",
10+
"start": "vite",
11+
"test:e2e": "rm -rf port*.txt; playwright test --project=chromium"
12+
},
13+
"dependencies": {
14+
"@tanstack/react-router": "workspace:^",
15+
"@tanstack/react-router-devtools": "workspace:^",
16+
"@tanstack/router-plugin": "workspace:^",
17+
"react": "^19.0.0",
18+
"react-dom": "^19.0.0"
19+
},
20+
"devDependencies": {
21+
"@playwright/test": "^1.50.1",
22+
"@tanstack/router-e2e-utils": "workspace:^",
23+
"@types/react": "^19.0.8",
24+
"@types/react-dom": "^19.0.3",
25+
"@vitejs/plugin-react": "^4.3.4",
26+
"vite": "^7.1.7"
27+
}
28+
}
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
import { defineConfig, devices } from '@playwright/test'
2+
import {
3+
getDummyServerPort,
4+
getTestServerPort,
5+
} from '@tanstack/router-e2e-utils'
6+
import packageJson from './package.json' with { type: 'json' }
7+
8+
const PORT = await getTestServerPort(packageJson.name)
9+
const EXTERNAL_PORT = await getDummyServerPort(packageJson.name)
10+
const baseURL = `http://localhost:${PORT}`
11+
/**
12+
* See https://playwright.dev/docs/test-configuration.
13+
*/
14+
export default defineConfig({
15+
testDir: './tests',
16+
workers: 1,
17+
18+
reporter: [['line']],
19+
20+
globalSetup: './tests/setup/global.setup.ts',
21+
globalTeardown: './tests/setup/global.teardown.ts',
22+
23+
use: {
24+
/* Base URL to use in actions like `await page.goto('/')`. */
25+
baseURL,
26+
},
27+
28+
webServer: {
29+
command: `VITE_NODE_ENV="test" VITE_SERVER_PORT=${PORT} VITE_EXTERNAL_PORT=${EXTERNAL_PORT} pnpm build && VITE_SERVER_PORT=${PORT} pnpm serve --port ${PORT}`,
30+
url: baseURL,
31+
reuseExistingServer: !process.env.CI,
32+
stdout: 'pipe',
33+
},
34+
35+
projects: [
36+
{
37+
name: 'chromium',
38+
use: { ...devices['Desktop Chrome'] },
39+
},
40+
],
41+
})
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
import React from 'react'
2+
import ReactDOM from 'react-dom/client'
3+
import { RouterProvider, createRouter } from '@tanstack/react-router'
4+
import { routeTree } from './routeTree.gen'
5+
6+
// Set up a Router instance
7+
const router = createRouter({
8+
routeTree,
9+
defaultPreload: 'intent',
10+
defaultStaleTime: 5000,
11+
scrollRestoration: true,
12+
basepath: '/app',
13+
})
14+
15+
// Register things for typesafety
16+
declare module '@tanstack/react-router' {
17+
interface Register {
18+
router: typeof router
19+
}
20+
}
21+
22+
const rootElement = document.getElementById('app')!
23+
24+
if (!rootElement.innerHTML) {
25+
const root = ReactDOM.createRoot(rootElement)
26+
root.render(<RouterProvider router={router} />)
27+
}
Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
/* eslint-disable */
2+
3+
// @ts-nocheck
4+
5+
// noinspection JSUnusedGlobalSymbols
6+
7+
// This file was automatically generated by TanStack Router.
8+
// You should NOT make any changes in this file as it will be overwritten.
9+
// Additionally, you should also exclude this file from your linter and/or formatter to prevent it from being checked or modified.
10+
11+
import { Route as rootRouteImport } from './routes/__root'
12+
import { Route as AboutRouteImport } from './routes/about'
13+
import { Route as IndexRouteImport } from './routes/index'
14+
15+
const AboutRoute = AboutRouteImport.update({
16+
id: '/about',
17+
path: '/about',
18+
getParentRoute: () => rootRouteImport,
19+
} as any)
20+
const IndexRoute = IndexRouteImport.update({
21+
id: '/',
22+
path: '/',
23+
getParentRoute: () => rootRouteImport,
24+
} as any)
25+
26+
export interface FileRoutesByFullPath {
27+
'/': typeof IndexRoute
28+
'/about': typeof AboutRoute
29+
}
30+
export interface FileRoutesByTo {
31+
'/': typeof IndexRoute
32+
'/about': typeof AboutRoute
33+
}
34+
export interface FileRoutesById {
35+
__root__: typeof rootRouteImport
36+
'/': typeof IndexRoute
37+
'/about': typeof AboutRoute
38+
}
39+
export interface FileRouteTypes {
40+
fileRoutesByFullPath: FileRoutesByFullPath
41+
fullPaths: '/' | '/about'
42+
fileRoutesByTo: FileRoutesByTo
43+
to: '/' | '/about'
44+
id: '__root__' | '/' | '/about'
45+
fileRoutesById: FileRoutesById
46+
}
47+
export interface RootRouteChildren {
48+
IndexRoute: typeof IndexRoute
49+
AboutRoute: typeof AboutRoute
50+
}
51+
52+
declare module '@tanstack/react-router' {
53+
interface FileRoutesByPath {
54+
'/about': {
55+
id: '/about'
56+
path: '/about'
57+
fullPath: '/about'
58+
preLoaderRoute: typeof AboutRouteImport
59+
parentRoute: typeof rootRouteImport
60+
}
61+
'/': {
62+
id: '/'
63+
path: '/'
64+
fullPath: '/'
65+
preLoaderRoute: typeof IndexRouteImport
66+
parentRoute: typeof rootRouteImport
67+
}
68+
}
69+
}
70+
71+
const rootRouteChildren: RootRouteChildren = {
72+
IndexRoute: IndexRoute,
73+
AboutRoute: AboutRoute,
74+
}
75+
export const routeTree = rootRouteImport
76+
._addFileChildren(rootRouteChildren)
77+
._addFileTypes<FileRouteTypes>()
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
import { createRootRoute } from '@tanstack/react-router'
2+
3+
export const Route = createRootRoute()
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
import { createFileRoute } from '@tanstack/react-router'
2+
3+
export const Route = createFileRoute('/about')({
4+
component: RouteComponent,
5+
})
6+
7+
function RouteComponent() {
8+
const navigate = Route.useNavigate()
9+
10+
return (
11+
<div data-testid="about-component">
12+
<button
13+
onClick={() => navigate({ to: '/', reloadDocument: true })}
14+
data-testid="to-home-btn"
15+
>
16+
Navigate to / with document reload
17+
</button>
18+
</div>
19+
)
20+
}
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
import { createFileRoute } from '@tanstack/react-router'
2+
3+
export const Route = createFileRoute('/')({
4+
component: App,
5+
})
6+
7+
function App() {
8+
const navigate = Route.useNavigate()
9+
10+
return (
11+
<div data-testid="home-component">
12+
<button
13+
data-testid="to-about-btn"
14+
onClick={() =>
15+
navigate({
16+
to: '/about',
17+
reloadDocument: true,
18+
})
19+
}
20+
>
21+
Navigate to /about with document reload
22+
</button>
23+
</div>
24+
)
25+
}
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
import { expect, test } from '@playwright/test'
2+
3+
test('navigate() respects basepath for when reloadDocument=true', async ({
4+
page,
5+
}) => {
6+
await page.goto(`/app/`)
7+
await expect(page.getByTestId(`home-component`)).toBeInViewport()
8+
9+
const aboutBtn = page.getByTestId(`to-about-btn`)
10+
await aboutBtn.click()
11+
await page.waitForURL('/app/about')
12+
await expect(page.getByTestId(`about-component`)).toBeInViewport()
13+
14+
const homeBtn = page.getByTestId(`to-home-btn`)
15+
await homeBtn.click()
16+
await page.waitForURL('/app/')
17+
await expect(page.getByTestId(`home-component`)).toBeInViewport()
18+
})

0 commit comments

Comments
 (0)