Capítulo 13 de 24
Location masking lets a route render at one path internally while the browser's address bar shows a different path. This is the standard TanStack Router pattern for modal routes (a photo detail overlay) that should look like they never left the underlying list page, while still being deep-linkable and shareable at their "real" URL.
createRoute / createRootRoute / createRouter, no file-based generation)@tanstack/react-router, @radix-ui/react-dialog (for the modal shell), @tanstack/react-router-devtoolssrc/main.tsx defines a photo list route (/photos), a real detail route (/photos/$photoId), and a nested modal route (/photos/$photoId/modal) mounted under the list layout. The modal route is masked so its URL displays as the plain detail route.const routeTree = rootRoute.addChildren([
photoRoute,
photosLayoutRoute.addChildren([photoModalRoute]),
indexRoute,
])
const photoModalToPhotoMask = createRouteMask({
routeTree,
from: '/photos/$photoId/modal',
to: '/photos/$photoId',
params: true,
})
// Set up a Router instance
const router = createRouter({
routeTree,
routeMasks: [photoModalToPhotoMask],
defaultPreload: 'intent',
scrollRestoration: true,
})
Linking into the masked route from the list page needs no special handling; the router applies the mask automatically because it is registered on routeMasks:
<Link
to={photoModalRoute.to}
params={{ photoId: photo.id }}
// If you want to use a mask, you can do so like this, but
// it's generally safer to set up a route mask instead.
// mask={{ to: photoRoute.to, params: { photoId: photo.id } }}
>
createRouteMask maps a "from" route to a "to" URL shape (with params: true forwarding params), registered globally via routeMasks on createRouter so every navigation to the masked route is masked consistently without per-Link configuration.routeMasks on createRouter) over a per-Link mask prop; it is applied uniformly and is harder to forget on a new link.photosLayoutRoute.addChildren).errorComponent/pendingComponent on the masked route (PhotoModalErrorComponent, PhotoModalPendingComponent) so failure and loading states also render inside the modal shell, not the page.