Skip to content
Merged
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
16 changes: 15 additions & 1 deletion e2e/react-router/basic-file-based/src/main.tsx
Original file line number Diff line number Diff line change
@@ -1,15 +1,29 @@
import React from 'react'
import ReactDOM from 'react-dom/client'
import { RouterProvider, createRouter } from '@tanstack/react-router'
import {
RouterProvider,
createRouteMask,
createRouter,
} from '@tanstack/react-router'
import { routeTree } from './routeTree.gen'
import './styles.css'

const mask = createRouteMask({
routeTree,
from: '/masks/admin/$userId',
to: '/masks/public/$username',
params: (prev) => ({
username: `user-${prev.userId}`,
}),
})

// Set up a Router instance
const router = createRouter({
routeTree,
defaultPreload: 'intent',
defaultStaleTime: 5000,
scrollRestoration: true,
routeMasks: [mask],
})

// Register things for typesafety
Expand Down
71 changes: 71 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 @@ -12,6 +12,7 @@ import { Route as rootRouteImport } from './routes/__root'
import { Route as RemountDepsRouteImport } from './routes/remountDeps'
import { Route as PostsRouteImport } from './routes/posts'
import { Route as NotRemountDepsRouteImport } from './routes/notRemountDeps'
import { Route as MasksRouteImport } from './routes/masks'
import { Route as HoverPreloadHashRouteImport } from './routes/hover-preload-hash'
import { Route as EditingBRouteImport } from './routes/editing-b'
import { Route as EditingARouteImport } from './routes/editing-a'
Expand Down Expand Up @@ -67,6 +68,8 @@ import { Route as ParamsPsWildcardPrefixAtChar45824Char123Char125RouteImport } f
import { Route as ParamsPsWildcardSplatRouteImport } from './routes/params-ps/wildcard/$'
import { Route as ParamsPsNamedChar123fooChar125suffixRouteImport } from './routes/params-ps/named/{$foo}suffix'
import { Route as ParamsPsNamedPrefixChar123fooChar125RouteImport } from './routes/params-ps/named/prefix{$foo}'
import { Route as MasksPublicUsernameRouteImport } from './routes/masks.public.$username'
import { Route as MasksAdminUserIdRouteImport } from './routes/masks.admin.$userId'
import { Route as LayoutLayout2LayoutBRouteImport } from './routes/_layout/_layout-2/layout-b'
import { Route as LayoutLayout2LayoutARouteImport } from './routes/_layout/_layout-2/layout-a'
import { Route as groupSubfolderInsideRouteImport } from './routes/(group)/subfolder/inside'
Expand Down Expand Up @@ -126,6 +129,11 @@ const NotRemountDepsRoute = NotRemountDepsRouteImport.update({
path: '/notRemountDeps',
getParentRoute: () => rootRouteImport,
} as any)
const MasksRoute = MasksRouteImport.update({
id: '/masks',
path: '/masks',
getParentRoute: () => rootRouteImport,
} as any)
const HoverPreloadHashRoute = HoverPreloadHashRouteImport.update({
id: '/hover-preload-hash',
path: '/hover-preload-hash',
Expand Down Expand Up @@ -417,6 +425,16 @@ const ParamsPsNamedPrefixChar123fooChar125Route =
path: '/params-ps/named/prefix{$foo}',
getParentRoute: () => rootRouteImport,
} as any)
const MasksPublicUsernameRoute = MasksPublicUsernameRouteImport.update({
id: '/public/$username',
path: '/public/$username',
getParentRoute: () => MasksRoute,
} as any)
const MasksAdminUserIdRoute = MasksAdminUserIdRouteImport.update({
id: '/admin/$userId',
path: '/admin/$userId',
getParentRoute: () => MasksRoute,
} as any)
const LayoutLayout2LayoutBRoute = LayoutLayout2LayoutBRouteImport.update({
id: '/layout-b',
path: '/layout-b',
Expand Down Expand Up @@ -666,6 +684,7 @@ export interface FileRoutesByFullPath {
'/editing-a': typeof EditingARoute
'/editing-b': typeof EditingBRoute
'/hover-preload-hash': typeof HoverPreloadHashRoute
'/masks': typeof MasksRouteWithChildren
'/notRemountDeps': typeof NotRemountDepsRoute
'/posts': typeof PostsRouteWithChildren
'/remountDeps': typeof RemountDepsRoute
Expand Down Expand Up @@ -700,6 +719,8 @@ export interface FileRoutesByFullPath {
'/subfolder/inside': typeof groupSubfolderInsideRoute
'/layout-a': typeof LayoutLayout2LayoutARoute
'/layout-b': typeof LayoutLayout2LayoutBRoute
'/masks/admin/$userId': typeof MasksAdminUserIdRoute
'/masks/public/$username': typeof MasksPublicUsernameRoute
'/params-ps/named/prefix{$foo}': typeof ParamsPsNamedPrefixChar123fooChar125Route
'/params-ps/named/{$foo}suffix': typeof ParamsPsNamedChar123fooChar125suffixRoute
'/params-ps/wildcard/$': typeof ParamsPsWildcardSplatRoute
Expand Down Expand Up @@ -765,6 +786,7 @@ export interface FileRoutesByTo {
'/editing-a': typeof EditingARoute
'/editing-b': typeof EditingBRoute
'/hover-preload-hash': typeof HoverPreloadHashRoute
'/masks': typeof MasksRouteWithChildren
'/notRemountDeps': typeof NotRemountDepsRoute
'/remountDeps': typeof RemountDepsRoute
'/non-nested/deep': typeof NonNestedDeepRouteRouteWithChildren
Expand Down Expand Up @@ -792,6 +814,8 @@ export interface FileRoutesByTo {
'/subfolder/inside': typeof groupSubfolderInsideRoute
'/layout-a': typeof LayoutLayout2LayoutARoute
'/layout-b': typeof LayoutLayout2LayoutBRoute
'/masks/admin/$userId': typeof MasksAdminUserIdRoute
'/masks/public/$username': typeof MasksPublicUsernameRoute
'/params-ps/named/prefix{$foo}': typeof ParamsPsNamedPrefixChar123fooChar125Route
'/params-ps/named/{$foo}suffix': typeof ParamsPsNamedChar123fooChar125suffixRoute
'/params-ps/wildcard/$': typeof ParamsPsWildcardSplatRoute
Expand Down Expand Up @@ -858,6 +882,7 @@ export interface FileRoutesById {
'/editing-a': typeof EditingARoute
'/editing-b': typeof EditingBRoute
'/hover-preload-hash': typeof HoverPreloadHashRoute
'/masks': typeof MasksRouteWithChildren
'/notRemountDeps': typeof NotRemountDepsRoute
'/posts': typeof PostsRouteWithChildren
'/remountDeps': typeof RemountDepsRoute
Expand Down Expand Up @@ -894,6 +919,8 @@ export interface FileRoutesById {
'/(group)/subfolder/inside': typeof groupSubfolderInsideRoute
'/_layout/_layout-2/layout-a': typeof LayoutLayout2LayoutARoute
'/_layout/_layout-2/layout-b': typeof LayoutLayout2LayoutBRoute
'/masks/admin/$userId': typeof MasksAdminUserIdRoute
'/masks/public/$username': typeof MasksPublicUsernameRoute
'/params-ps/named/prefix{$foo}': typeof ParamsPsNamedPrefixChar123fooChar125Route
'/params-ps/named/{$foo}suffix': typeof ParamsPsNamedChar123fooChar125suffixRoute
'/params-ps/wildcard/$': typeof ParamsPsWildcardSplatRoute
Expand Down Expand Up @@ -962,6 +989,7 @@ export interface FileRouteTypes {
| '/editing-a'
| '/editing-b'
| '/hover-preload-hash'
| '/masks'
| '/notRemountDeps'
| '/posts'
| '/remountDeps'
Expand Down Expand Up @@ -996,6 +1024,8 @@ export interface FileRouteTypes {
| '/subfolder/inside'
| '/layout-a'
| '/layout-b'
| '/masks/admin/$userId'
| '/masks/public/$username'
| '/params-ps/named/prefix{$foo}'
| '/params-ps/named/{$foo}suffix'
| '/params-ps/wildcard/$'
Expand Down Expand Up @@ -1061,6 +1091,7 @@ export interface FileRouteTypes {
| '/editing-a'
| '/editing-b'
| '/hover-preload-hash'
| '/masks'
| '/notRemountDeps'
| '/remountDeps'
| '/non-nested/deep'
Expand Down Expand Up @@ -1088,6 +1119,8 @@ export interface FileRouteTypes {
| '/subfolder/inside'
| '/layout-a'
| '/layout-b'
| '/masks/admin/$userId'
| '/masks/public/$username'
| '/params-ps/named/prefix{$foo}'
| '/params-ps/named/{$foo}suffix'
| '/params-ps/wildcard/$'
Expand Down Expand Up @@ -1153,6 +1186,7 @@ export interface FileRouteTypes {
| '/editing-a'
| '/editing-b'
| '/hover-preload-hash'
| '/masks'
| '/notRemountDeps'
| '/posts'
| '/remountDeps'
Expand Down Expand Up @@ -1189,6 +1223,8 @@ export interface FileRouteTypes {
| '/(group)/subfolder/inside'
| '/_layout/_layout-2/layout-a'
| '/_layout/_layout-2/layout-b'
| '/masks/admin/$userId'
| '/masks/public/$username'
| '/params-ps/named/prefix{$foo}'
| '/params-ps/named/{$foo}suffix'
| '/params-ps/wildcard/$'
Expand Down Expand Up @@ -1257,6 +1293,7 @@ export interface RootRouteChildren {
EditingARoute: typeof EditingARoute
EditingBRoute: typeof EditingBRoute
HoverPreloadHashRoute: typeof HoverPreloadHashRoute
MasksRoute: typeof MasksRouteWithChildren
NotRemountDepsRoute: typeof NotRemountDepsRoute
PostsRoute: typeof PostsRouteWithChildren
RemountDepsRoute: typeof RemountDepsRoute
Expand Down Expand Up @@ -1313,6 +1350,13 @@ declare module '@tanstack/react-router' {
preLoaderRoute: typeof NotRemountDepsRouteImport
parentRoute: typeof rootRouteImport
}
'/masks': {
id: '/masks'
path: '/masks'
fullPath: '/masks'
preLoaderRoute: typeof MasksRouteImport
parentRoute: typeof rootRouteImport
}
'/hover-preload-hash': {
id: '/hover-preload-hash'
path: '/hover-preload-hash'
Expand Down Expand Up @@ -1698,6 +1742,20 @@ declare module '@tanstack/react-router' {
preLoaderRoute: typeof ParamsPsNamedPrefixChar123fooChar125RouteImport
parentRoute: typeof rootRouteImport
}
'/masks/public/$username': {
id: '/masks/public/$username'
path: '/public/$username'
fullPath: '/masks/public/$username'
preLoaderRoute: typeof MasksPublicUsernameRouteImport
parentRoute: typeof MasksRoute
}
'/masks/admin/$userId': {
id: '/masks/admin/$userId'
path: '/admin/$userId'
fullPath: '/masks/admin/$userId'
preLoaderRoute: typeof MasksAdminUserIdRouteImport
parentRoute: typeof MasksRoute
}
'/_layout/_layout-2/layout-b': {
id: '/_layout/_layout-2/layout-b'
path: '/layout-b'
Expand Down Expand Up @@ -2262,6 +2320,18 @@ const LayoutRouteChildren: LayoutRouteChildren = {
const LayoutRouteWithChildren =
LayoutRoute._addFileChildren(LayoutRouteChildren)

interface MasksRouteChildren {
MasksAdminUserIdRoute: typeof MasksAdminUserIdRoute
MasksPublicUsernameRoute: typeof MasksPublicUsernameRoute
}

const MasksRouteChildren: MasksRouteChildren = {
MasksAdminUserIdRoute: MasksAdminUserIdRoute,
MasksPublicUsernameRoute: MasksPublicUsernameRoute,
}

const MasksRouteWithChildren = MasksRoute._addFileChildren(MasksRouteChildren)

interface PostsRouteChildren {
PostsPostIdRoute: typeof PostsPostIdRoute
PostsIndexRoute: typeof PostsIndexRoute
Expand Down Expand Up @@ -2423,6 +2493,7 @@ const rootRouteChildren: RootRouteChildren = {
EditingARoute: EditingARoute,
EditingBRoute: EditingBRoute,
HoverPreloadHashRoute: HoverPreloadHashRoute,
MasksRoute: MasksRouteWithChildren,
NotRemountDepsRoute: NotRemountDepsRoute,
PostsRoute: PostsRouteWithChildren,
RemountDepsRoute: RemountDepsRoute,
Expand Down
9 changes: 9 additions & 0 deletions e2e/react-router/basic-file-based/src/routes/__root.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -146,6 +146,15 @@ function RootComponent() {
}}
>
This Route Does Not Exist
</Link>{' '}
<Link
to="/masks"
data-testid="link-to-masks"
activeProps={{
className: 'font-bold',
}}
>
Masks
</Link>
</div>
<hr />
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import { createFileRoute } from '@tanstack/react-router'

export const Route = createFileRoute('/masks/admin/$userId')({
component: AdminUserRoute,
})

function AdminUserRoute() {
const params = Route.useParams()

return (
<div data-testid="admin-user-component">
<div data-testid="admin-user-id">{params.userId}</div>
</div>
)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import { createFileRoute } from '@tanstack/react-router'

export const Route = createFileRoute('/masks/public/$username')({
component: PublicUserRoute,
})

function PublicUserRoute() {
const params = Route.useParams()

return (
<div data-testid="public-user-component">
<div data-testid="public-username">{params.username}</div>
</div>
)
}
38 changes: 38 additions & 0 deletions e2e/react-router/basic-file-based/src/routes/masks.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
import {
Link,
Outlet,
createFileRoute,
useRouterState,
} from '@tanstack/react-router'

export const Route = createFileRoute('/masks')({
component: MasksLayout,
})

function MasksLayout() {
const location = useRouterState({
select: (state) => state.location,
})

return (
<div>
<h2>Route Masks</h2>
<nav>
<Link
to="/masks/admin/$userId"
params={{ userId: '42' }}
data-testid="link-to-admin-mask"
>
Go to admin user
</Link>
</nav>
<div>
<div data-testid="router-pathname">{location.pathname}</div>
<div data-testid="router-masked-pathname">
{location.maskedLocation?.pathname ?? ''}
</div>
</div>
<Outlet />
</div>
)
}
26 changes: 26 additions & 0 deletions e2e/react-router/basic-file-based/tests/mask.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import { expect, test } from '@playwright/test'

test('route masks transform params and expose masked pathname in the browser (react)', async ({
page,
}) => {
await page.goto('/')

await page.getByTestId('link-to-masks').click()
await expect(page.getByText('Route Masks')).toBeVisible()

const link = page.getByTestId('link-to-admin-mask')
await link.click()

await page.waitForURL('/masks/public/user-42')

await expect(page.getByTestId('admin-user-component')).toBeInViewport()
await expect(page.getByTestId('admin-user-id')).toHaveText('42')

await expect(page.getByTestId('router-pathname')).toHaveText(
'/masks/admin/42',
)

await expect(page.getByTestId('router-masked-pathname')).toHaveText(
'/masks/public/user-42',
)
})
16 changes: 15 additions & 1 deletion e2e/solid-router/basic-file-based/src/main.tsx
Original file line number Diff line number Diff line change
@@ -1,14 +1,28 @@
import { RouterProvider, createRouter } from '@tanstack/solid-router'
import {
RouterProvider,
createRouteMask,
createRouter,
} from '@tanstack/solid-router'
import { render } from 'solid-js/web'
import { routeTree } from './routeTree.gen'
import './styles.css'

const mask = createRouteMask({
routeTree,
from: '/masks/admin/$userId',
to: '/masks/public/$username',
params: (prev) => ({
username: `user-${prev.userId}`,
}),
})

// Set up a Router instance
const router = createRouter({
routeTree,
defaultPreload: 'intent',
defaultStaleTime: 5000,
scrollRestoration: true,
routeMasks: [mask],
})

// Register things for typesafety
Expand Down
Loading
Loading