Skip to content

Commit 5ce936f

Browse files
authored
fix: support usage of a prefixed a base path (#4258)
Fixes #4221
1 parent e95834e commit 5ce936f

File tree

98 files changed

+4783
-544
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

98 files changed

+4783
-544
lines changed
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
node_modules
2+
package-lock.json
3+
yarn.lock
4+
5+
.DS_Store
6+
.cache
7+
.env
8+
.vercel
9+
.output
10+
11+
/build/
12+
/api/
13+
/server/build
14+
/public/build
15+
# Sentry Config File
16+
.env.sentry-build-plugin
17+
/test-results/
18+
/playwright-report/
19+
/blob-report/
20+
/playwright/.cache/
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
**/build
2+
**/public
3+
pnpm-lock.yaml
4+
routeTree.gen.ts
Lines changed: 155 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,155 @@
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 Routes
12+
13+
import type {
14+
FileRoutesByPath,
15+
CreateServerFileRoute,
16+
} from '@tanstack/react-start/server'
17+
import {
18+
createServerRoute,
19+
createServerFileRoute,
20+
} from '@tanstack/react-start/server'
21+
22+
import { ServerRoute as ApiUsersRouteImport } from './../../src/routes/api.users'
23+
import { ServerRoute as ApiUsersIdRouteImport } from './../../src/routes/api/users.$id'
24+
25+
// Create/Update Routes
26+
27+
const rootRoute = createServerRoute()
28+
29+
const ApiUsersRoute = ApiUsersRouteImport.update({
30+
id: '/api/users',
31+
path: '/api/users',
32+
getParentRoute: () => rootRoute,
33+
} as any)
34+
35+
const ApiUsersIdRoute = ApiUsersIdRouteImport.update({
36+
id: '/$id',
37+
path: '/$id',
38+
getParentRoute: () => ApiUsersRoute,
39+
} as any)
40+
41+
// Populate the FileRoutesByPath interface
42+
43+
declare module '@tanstack/react-start/server' {
44+
interface FileRoutesByPath {
45+
'/api/users': {
46+
id: '/api/users'
47+
path: '/api/users'
48+
fullPath: '/api/users'
49+
preLoaderRoute: typeof ApiUsersRouteImport
50+
parentRoute: typeof rootRoute
51+
}
52+
'/api/users/$id': {
53+
id: '/api/users/$id'
54+
path: '/$id'
55+
fullPath: '/api/users/$id'
56+
preLoaderRoute: typeof ApiUsersIdRouteImport
57+
parentRoute: typeof ApiUsersRouteImport
58+
}
59+
}
60+
}
61+
62+
// Add type-safety to the createFileRoute function across the route tree
63+
64+
declare module './../../src/routes/api.users' {
65+
const createServerFileRoute: CreateServerFileRoute<
66+
FileRoutesByPath['/api/users']['parentRoute'],
67+
FileRoutesByPath['/api/users']['id'],
68+
FileRoutesByPath['/api/users']['path'],
69+
FileRoutesByPath['/api/users']['fullPath'],
70+
ApiUsersRouteChildren
71+
>
72+
}
73+
declare module './../../src/routes/api/users.$id' {
74+
const createServerFileRoute: CreateServerFileRoute<
75+
FileRoutesByPath['/api/users/$id']['parentRoute'],
76+
FileRoutesByPath['/api/users/$id']['id'],
77+
FileRoutesByPath['/api/users/$id']['path'],
78+
FileRoutesByPath['/api/users/$id']['fullPath'],
79+
unknown
80+
>
81+
}
82+
83+
// Create and export the route tree
84+
85+
interface ApiUsersRouteChildren {
86+
ApiUsersIdRoute: typeof ApiUsersIdRoute
87+
}
88+
89+
const ApiUsersRouteChildren: ApiUsersRouteChildren = {
90+
ApiUsersIdRoute: ApiUsersIdRoute,
91+
}
92+
93+
const ApiUsersRouteWithChildren = ApiUsersRoute._addFileChildren(
94+
ApiUsersRouteChildren,
95+
)
96+
97+
export interface FileRoutesByFullPath {
98+
'/api/users': typeof ApiUsersRouteWithChildren
99+
'/api/users/$id': typeof ApiUsersIdRoute
100+
}
101+
102+
export interface FileRoutesByTo {
103+
'/api/users': typeof ApiUsersRouteWithChildren
104+
'/api/users/$id': typeof ApiUsersIdRoute
105+
}
106+
107+
export interface FileRoutesById {
108+
__root__: typeof rootRoute
109+
'/api/users': typeof ApiUsersRouteWithChildren
110+
'/api/users/$id': typeof ApiUsersIdRoute
111+
}
112+
113+
export interface FileRouteTypes {
114+
fileRoutesByFullPath: FileRoutesByFullPath
115+
fullPaths: '/api/users' | '/api/users/$id'
116+
fileRoutesByTo: FileRoutesByTo
117+
to: '/api/users' | '/api/users/$id'
118+
id: '__root__' | '/api/users' | '/api/users/$id'
119+
fileRoutesById: FileRoutesById
120+
}
121+
122+
export interface RootRouteChildren {
123+
ApiUsersRoute: typeof ApiUsersRouteWithChildren
124+
}
125+
126+
const rootRouteChildren: RootRouteChildren = {
127+
ApiUsersRoute: ApiUsersRouteWithChildren,
128+
}
129+
130+
export const routeTree = rootRoute
131+
._addFileChildren(rootRouteChildren)
132+
._addFileTypes<FileRouteTypes>()
133+
134+
/* ROUTE_MANIFEST_START
135+
{
136+
"routes": {
137+
"__root__": {
138+
"filePath": "__root.tsx",
139+
"children": [
140+
"/api/users"
141+
]
142+
},
143+
"/api/users": {
144+
"filePath": "api.users.ts",
145+
"children": [
146+
"/api/users/$id"
147+
]
148+
},
149+
"/api/users/$id": {
150+
"filePath": "api/users.$id.ts",
151+
"parent": "/api/users"
152+
}
153+
}
154+
}
155+
ROUTE_MANIFEST_END */
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
{
2+
"name": "tanstack-react-start-e2e-custom-basepath",
3+
"private": true,
4+
"sideEffects": false,
5+
"type": "module",
6+
"scripts": {
7+
"dev": "vite dev --port 3000",
8+
"dev:e2e": "vite dev",
9+
"build": "vite build && tsc --noEmit",
10+
"start": "node .output/server/index.mjs",
11+
"test:e2e": "playwright test --project=chromium"
12+
},
13+
"dependencies": {
14+
"@tanstack/react-router": "workspace:^",
15+
"@tanstack/react-router-devtools": "workspace:^",
16+
"@tanstack/react-start": "workspace:^",
17+
"react": "^19.0.0",
18+
"react-dom": "^19.0.0",
19+
"redaxios": "^0.5.1",
20+
"tailwind-merge": "^2.6.0",
21+
"vite": "6.3.5",
22+
"zod": "^3.24.2"
23+
},
24+
"devDependencies": {
25+
"@playwright/test": "^1.50.1",
26+
"@tanstack/router-e2e-utils": "workspace:^",
27+
"@types/node": "^22.10.2",
28+
"@types/react": "^19.0.8",
29+
"@types/react-dom": "^19.0.3",
30+
"@vitejs/plugin-react": "^4.3.4",
31+
"autoprefixer": "^10.4.20",
32+
"combinate": "^1.1.11",
33+
"postcss": "^8.5.1",
34+
"tailwindcss": "^3.4.17",
35+
"typescript": "^5.7.2",
36+
"vite-tsconfig-paths": "^5.1.4"
37+
}
38+
}
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
import { defineConfig, devices } from '@playwright/test'
2+
import { derivePort } from '@tanstack/router-e2e-utils'
3+
import packageJson from './package.json' with { type: 'json' }
4+
5+
const PORT = derivePort(packageJson.name)
6+
const baseURL = `http://localhost:${PORT}/custom/basepath`
7+
8+
/**
9+
* See https://playwright.dev/docs/test-configuration.
10+
*/
11+
export default defineConfig({
12+
testDir: './tests',
13+
workers: 1,
14+
15+
reporter: [['line']],
16+
17+
use: {
18+
/* Base URL to use in actions like `await page.goto('/')`. */
19+
baseURL,
20+
},
21+
22+
webServer: {
23+
command: `pnpm build && VITE_SERVER_PORT=${PORT} PORT=${PORT} pnpm start`,
24+
url: baseURL,
25+
reuseExistingServer: !process.env.CI,
26+
stdout: 'pipe',
27+
},
28+
29+
projects: [
30+
{
31+
name: 'chromium',
32+
use: { ...devices['Desktop Chrome'] },
33+
},
34+
],
35+
})
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
export default {
2+
plugins: {
3+
tailwindcss: {},
4+
autoprefixer: {},
5+
},
6+
}
Loading
Loading
Loading
Loading
Loading
Binary file not shown.
Loading
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
console.log('SCRIPT_1 loaded')
2+
window.SCRIPT_1 = true
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
console.log('SCRIPT_2 loaded')
2+
window.SCRIPT_2 = true
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
{
2+
"name": "",
3+
"short_name": "",
4+
"icons": [
5+
{
6+
"src": "/android-chrome-192x192.png",
7+
"sizes": "192x192",
8+
"type": "image/png"
9+
},
10+
{
11+
"src": "/android-chrome-512x512.png",
12+
"sizes": "512x512",
13+
"type": "image/png"
14+
}
15+
],
16+
"theme_color": "#ffffff",
17+
"background_color": "#ffffff",
18+
"display": "standalone"
19+
}
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
import * as React from 'react'
2+
3+
export function CustomMessage({ message }: { message: string }) {
4+
return (
5+
<div className="py-2">
6+
<div className="italic">This is a custom message:</div>
7+
<p>{message}</p>
8+
</div>
9+
)
10+
}
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
import {
2+
ErrorComponent,
3+
Link,
4+
rootRouteId,
5+
useMatch,
6+
useRouter,
7+
} from '@tanstack/react-router'
8+
import type { ErrorComponentProps } from '@tanstack/react-router'
9+
10+
export function DefaultCatchBoundary({ error }: ErrorComponentProps) {
11+
const router = useRouter()
12+
const isRoot = useMatch({
13+
strict: false,
14+
select: (state) => state.id === rootRouteId,
15+
})
16+
17+
console.error(error)
18+
19+
return (
20+
<div className="min-w-0 flex-1 p-4 flex flex-col items-center justify-center gap-6">
21+
<ErrorComponent error={error} />
22+
<div className="flex gap-2 items-center flex-wrap">
23+
<button
24+
onClick={() => {
25+
router.invalidate()
26+
}}
27+
className={`px-2 py-1 bg-gray-600 dark:bg-gray-700 rounded text-white uppercase font-extrabold`}
28+
>
29+
Try Again
30+
</button>
31+
{isRoot ? (
32+
<Link
33+
to="/"
34+
className={`px-2 py-1 bg-gray-600 dark:bg-gray-700 rounded text-white uppercase font-extrabold`}
35+
>
36+
Home
37+
</Link>
38+
) : (
39+
<Link
40+
to="/"
41+
className={`px-2 py-1 bg-gray-600 dark:bg-gray-700 rounded text-white uppercase font-extrabold`}
42+
onClick={(e) => {
43+
e.preventDefault()
44+
window.history.back()
45+
}}
46+
>
47+
Go Back
48+
</Link>
49+
)}
50+
</div>
51+
</div>
52+
)
53+
}
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
import { Link } from '@tanstack/react-router'
2+
3+
export function NotFound({ children }: { children?: any }) {
4+
return (
5+
<div className="space-y-2 p-2" data-testid="default-not-found-component">
6+
<div className="text-gray-600 dark:text-gray-400">
7+
{children || <p>The page you are looking for does not exist.</p>}
8+
</div>
9+
<p className="flex items-center gap-2 flex-wrap">
10+
<button
11+
onClick={() => window.history.back()}
12+
className="bg-emerald-500 text-white px-2 py-1 rounded uppercase font-black text-sm"
13+
>
14+
Go back
15+
</button>
16+
<Link
17+
to="/"
18+
className="bg-cyan-600 text-white px-2 py-1 rounded uppercase font-black text-sm"
19+
>
20+
Start Over
21+
</Link>
22+
</p>
23+
</div>
24+
)
25+
}

0 commit comments

Comments
 (0)