Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 21 additions & 0 deletions e2e/react-router/basic-file-based/src/routeTree.gen.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
// Additionally, you should also exclude this file from your linter and/or formatter to prevent it from being checked or modified.

import { Route as rootRouteImport } from './routes/__root'
import { Route as SpecialChar124pipeRouteImport } from './routes/special|pipe'
import { Route as RemountDepsRouteImport } from './routes/remountDeps'
import { Route as PostsRouteImport } from './routes/posts'
import { Route as NotRemountDepsRouteImport } from './routes/notRemountDeps'
Expand Down Expand Up @@ -118,6 +119,11 @@ import { Route as NonNestedDeepBazBarFooRouteRouteImport } from './routes/non-ne
import { Route as NonNestedDeepBazBarFooIndexRouteImport } from './routes/non-nested/deep/$baz_.bar.$foo.index'
import { Route as NonNestedDeepBazBarFooQuxRouteImport } from './routes/non-nested/deep/$baz_.bar.$foo_.qux'

const SpecialChar124pipeRoute = SpecialChar124pipeRouteImport.update({
id: '/special|pipe',
path: '/special|pipe',
getParentRoute: () => rootRouteImport,
} as any)
const RemountDepsRoute = RemountDepsRouteImport.update({
id: '/remountDeps',
path: '/remountDeps',
Expand Down Expand Up @@ -715,6 +721,7 @@ export interface FileRoutesByFullPath {
'/notRemountDeps': typeof NotRemountDepsRoute
'/posts': typeof PostsRouteWithChildren
'/remountDeps': typeof RemountDepsRoute
'/special|pipe': typeof SpecialChar124pipeRoute
'/non-nested/deep': typeof NonNestedDeepRouteRouteWithChildren
'/non-nested/named': typeof NonNestedNamedRouteRouteWithChildren
'/non-nested/path': typeof NonNestedPathRouteRouteWithChildren
Expand Down Expand Up @@ -819,6 +826,7 @@ export interface FileRoutesByTo {
'/masks': typeof MasksRouteWithChildren
'/notRemountDeps': typeof NotRemountDepsRoute
'/remountDeps': typeof RemountDepsRoute
'/special|pipe': typeof SpecialChar124pipeRoute
'/non-nested/deep': typeof NonNestedDeepRouteRouteWithChildren
'/non-nested/named': typeof NonNestedNamedRouteRouteWithChildren
'/non-nested/path': typeof NonNestedPathRouteRouteWithChildren
Expand Down Expand Up @@ -918,6 +926,7 @@ export interface FileRoutesById {
'/notRemountDeps': typeof NotRemountDepsRoute
'/posts': typeof PostsRouteWithChildren
'/remountDeps': typeof RemountDepsRoute
'/special|pipe': typeof SpecialChar124pipeRoute
'/non-nested/deep': typeof NonNestedDeepRouteRouteWithChildren
'/non-nested/named': typeof NonNestedNamedRouteRouteWithChildren
'/non-nested/path': typeof NonNestedPathRouteRouteWithChildren
Expand Down Expand Up @@ -1029,6 +1038,7 @@ export interface FileRouteTypes {
| '/notRemountDeps'
| '/posts'
| '/remountDeps'
| '/special|pipe'
| '/non-nested/deep'
| '/non-nested/named'
| '/non-nested/path'
Expand Down Expand Up @@ -1133,6 +1143,7 @@ export interface FileRouteTypes {
| '/masks'
| '/notRemountDeps'
| '/remountDeps'
| '/special|pipe'
| '/non-nested/deep'
| '/non-nested/named'
| '/non-nested/path'
Expand Down Expand Up @@ -1231,6 +1242,7 @@ export interface FileRouteTypes {
| '/notRemountDeps'
| '/posts'
| '/remountDeps'
| '/special|pipe'
| '/non-nested/deep'
| '/non-nested/named'
| '/non-nested/path'
Expand Down Expand Up @@ -1342,6 +1354,7 @@ export interface RootRouteChildren {
NotRemountDepsRoute: typeof NotRemountDepsRoute
PostsRoute: typeof PostsRouteWithChildren
RemountDepsRoute: typeof RemountDepsRoute
SpecialChar124pipeRoute: typeof SpecialChar124pipeRoute
ParamsPsNonNestedRouteRoute: typeof ParamsPsNonNestedRouteRouteWithChildren
RelativeLinkRouteRoute: typeof RelativeLinkRouteRouteWithChildren
RelativeUseNavigateRouteRoute: typeof RelativeUseNavigateRouteRouteWithChildren
Expand Down Expand Up @@ -1374,6 +1387,13 @@ export interface RootRouteChildren {

declare module '@tanstack/react-router' {
interface FileRoutesByPath {
'/special|pipe': {
id: '/special|pipe'
path: '/special|pipe'
fullPath: '/special|pipe'
preLoaderRoute: typeof SpecialChar124pipeRouteImport
parentRoute: typeof rootRouteImport
}
'/remountDeps': {
id: '/remountDeps'
path: '/remountDeps'
Expand Down Expand Up @@ -2598,6 +2618,7 @@ const rootRouteChildren: RootRouteChildren = {
NotRemountDepsRoute: NotRemountDepsRoute,
PostsRoute: PostsRouteWithChildren,
RemountDepsRoute: RemountDepsRoute,
SpecialChar124pipeRoute: SpecialChar124pipeRoute,
ParamsPsNonNestedRouteRoute: ParamsPsNonNestedRouteRouteWithChildren,
RelativeLinkRouteRoute: RelativeLinkRouteRouteWithChildren,
RelativeUseNavigateRouteRoute: RelativeUseNavigateRouteRouteWithChildren,
Expand Down
5 changes: 5 additions & 0 deletions e2e/react-router/basic-file-based/src/routes/special|pipe.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import { createFileRoute } from '@tanstack/react-router'

export const Route = createFileRoute('/special|pipe')({
component: () => <div>Hello /special|pipe!</div>,
})
13 changes: 13 additions & 0 deletions e2e/react-router/basic-file-based/tests/app.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -394,3 +394,16 @@ test.describe('Pathless layout routes', () => {
await expect(page.locator('body')).toContainText('Not Found')
})
})

test.describe('Special characters in route paths', () => {
test('should render route with pipe character in path', async ({
page,
baseURL,
}) => {
await page.goto('/special|pipe')

await expect(page.locator('body')).toContainText('Hello /special|pipe!')

expect(page.url()).toBe(`${baseURL}/special%7Cpipe`)
})
})
2 changes: 1 addition & 1 deletion packages/router-core/src/path.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ export function joinPaths(paths: Array<string | undefined>) {
/** Remove repeated slashes from a path string. */
export function cleanPath(path: string) {
// remove double slashes
return path.replace(/\/{2,}/g, '/')
return path.replace(/\/{2,}/g, '/').replace(/\|/g, '%7C')
}

/** Trim leading slashes (except preserving root '/'). */
Expand Down