Open id view content from Tanstack Table with Tanstack Router

Anyone has any tip how I can render a new view in the current page of a selected item ? So im using tanstack table, query and router and if I want to open a new page when clicking an item and receiving that Item id, everything works wonderfully. But my idea is to have a table and open a view next to it instead of on a new url page.
<RouterLink
to="/page/$id"
params={{ id: props.id }}
<RouterLink
to="/page/$id"
params={{ id: props.id }}
This open a new page inside the id with the router perfectly. But what if I want just to open a new component or view inside the same page ? Anyone has a tip for this ? Any tip appreciated.
27 Replies
if err != nil
if err != nilOP16mo ago
@dan I want to do something like this. Like my code works great if I want to open a new page. But in this case I dont want a full page, I want a view that will overlap the maps component when I click on one item
function Column(props: { id: number; name: string }) {

return (
<RouterLink
to="/actions/$id"
params={{ id: props.id }}
onClick={(event: React.MouseEvent) => {
console.log("props.id", props.i);
}}
>
{props.name}
</RouterLink>
);
}
function Column(props: { id: number; name: string }) {

return (
<RouterLink
to="/actions/$id"
params={{ id: props.id }}
onClick={(event: React.MouseEvent) => {
console.log("props.id", props.i);
}}
>
{props.name}
</RouterLink>
);
}
So I would render the item settings component of the respective item id.
No description
dan
dan16mo ago
This has an example on how to do what you want https://tanstack.com/router/v1/docs/examples/react/basic-file-based You can see the _layout.tsx, this has the "main" page layout stuff, in your case the sensors, stations, last seen etc, elements. Inside the _layout folder it contains the "inner" sections, if you instead of having multiple routes there use a dynamic route ($whatever.tsx) then you can have that be loaded and fetch the data and render as needed.
React Router Basic File Based Example | TanStack Router Docs
An example showing how to implement Basic File Based in React Router
if err != nil
if err != nilOP16mo ago
Thank you so much. Ill take a look after lunch
dan
dan16mo ago
np, if you get stuck at all getting it working initally let me know.
if err != nil
if err != nilOP16mo ago
@dan so I have two folder. list.items and list.items.$id on the first folder I have a +component with just
<TwoPaneLayout header={<Header />} left={<Table />} right={<Outlet />} />
<TwoPaneLayout header={<Header />} left={<Table />} right={<Outlet />} />
right will display the map when no itemId or the settings view with the itemId. for now I just leave Outlet to test somethings. my +routefile inside list.items folder has:
export const listItemsRoute = new Route({
getParentRoute: () => itemsRoute,
path: "items",
export const listItemsRoute = new Route({
getParentRoute: () => itemsRoute,
path: "items",
This loads the inicial page. Table has the same
to="/actions/$id"
params={{ id: props.id }}
to="/actions/$id"
params={{ id: props.id }}
my list.item.$id folder has a similar structure but component has
function ItemSettings() {
return (
<ContentLayout
header={
<>
<Header />
<Meta />
</>
}
content={<div>hi</div>}
/>
);
}
function ItemSettings() {
return (
<ContentLayout
header={
<>
<Header />
<Meta />
</>
}
content={<div>hi</div>}
/>
);
}
And +route
export const itemListIdRoute = new Route({
getParentRoute: () => itemsRoute,
path: "items/$itemId",
component: ItemSettings
export const itemListIdRoute = new Route({
getParentRoute: () => itemsRoute,
path: "items/$itemId",
component: ItemSettings
Im guessing this route is the problem since I cloned the project example and testing on my machine, and Im failing to see how I still have a new page.
dan
dan16mo ago
on the rootRoute have you added the children (itemListIdRoute) to listItemsRoute?
if err != nil
if err != nilOP16mo ago
yes I did. itemRoute.addChildren([ itemListIndexRoute, itemListIdRoute, ]), Something like this
dan
dan16mo ago
oh uh try adding an index next to the dynamic route which would just be a default page when nothing is selected
if err != nil
if err != nilOP16mo ago
I had to come on the street I’ll try and report back later 🤝
dan
dan16mo ago
AbbySalute
if err != nil
if err != nilOP16mo ago
Aight just got home. Gonna continue to check the example and compare what im doing.
export const itemIndexRoute = new Route({
getParentRoute: () => ItemRoute,
path: "items",
validateSearch: searchSchema,
component: Item,
export const itemIndexRoute = new Route({
getParentRoute: () => ItemRoute,
path: "items",
validateSearch: searchSchema,
component: Item,
export const itemIdRoute = new Route({
getParentRoute: () => ItemRoute,
path: "items/$itemid",
component: ItemSettings,
parseParams(params) {
return {
itemId: z.number().int().parse(Number(params.itemId)),
};
},
export const itemIdRoute = new Route({
getParentRoute: () => ItemRoute,
path: "items/$itemid",
component: ItemSettings,
parseParams(params) {
return {
itemId: z.number().int().parse(Number(params.itemId)),
};
},
The only thing I can see me messing up are these +route.tsx files I have, other than that, im blind. But ill continue comparing with the folder and see what I have Ven the simple "layout A, B" should be enough to compare properly.
dan
dan16mo ago
if you have a repo I can take a look, I do remember it being a bit finicky to setup the first time.
if err != nil
if err != nilOP16mo ago
I think I see the problem.
export const itemsRoute = new Route({
getParentRoute: () => rootRoute,
path: "items",
component: RouteItem,
});
export const itemsRoute = new Route({
getParentRoute: () => rootRoute,
path: "items",
component: RouteItem,
});
This is the main route
import { Outlet } from "@tanstack/react-router";

import Header from "./Header";

export default function RouteItem() {
return (
<div
style={{
display: "grid",
height: "100vh",
gridTemplateAreas: "'header' 'content'",
gridTemplateRows: "auto 1fr",
gridTemplateColumns: "1fr",
}}
>
<div
style={{ gridArea: "header", borderBottom: "1px solid var(--gray-a5)" }}
>
<Header />
</div>

<div
style={{
gridArea: "content",
overflow: "hidden",
}}
>
<Outlet />
</div>
</div>
);
}
import { Outlet } from "@tanstack/react-router";

import Header from "./Header";

export default function RouteItem() {
return (
<div
style={{
display: "grid",
height: "100vh",
gridTemplateAreas: "'header' 'content'",
gridTemplateRows: "auto 1fr",
gridTemplateColumns: "1fr",
}}
>
<div
style={{ gridArea: "header", borderBottom: "1px solid var(--gray-a5)" }}
>
<Header />
</div>

<div
style={{
gridArea: "content",
overflow: "hidden",
}}
>
<Outlet />
</div>
</div>
);
}
So there is an Outlet for the main page where Im going to render my page and then inside that page I want to have another Outlet. @dan I can prepare a basic repo with the necessary files if you want to take a look, but the full project is a bit large.
dan
dan16mo ago
multiple outlets is fine idm, either works, up to you really
if err != nil
if err != nilOP16mo ago
Aight give me 5min I can wrap the files im working on together. Cant promise the code will run because probably wont but at least you can have a bigger picture
if err != nil
if err != nilOP16mo ago
GitHub
GitHub - FACorreiaa/tanstack-router-example: tanstack router exampl...
tanstack router example to render things. Contribute to FACorreiaa/tanstack-router-example development by creating an account on GitHub.
if err != nil
if err != nilOP16mo ago
Tell me if this would be enough to check out what im doing and not doing properly
dan
dan16mo ago
it might be the paths actually Not 100% sure but all mine are the full path, including the starting /
if err != nil
if err != nilOP16mo ago
I guess i'll just have to continue to try and catch around the files Cuz from the example, I dont seem to be doing anything wrong. But just dont get why with the <Outlet /> the the right property, I still open a new page.
dan
dan16mo ago
Try installing the router devtools and see what routes are matching
if err != nil
if err != nilOP16mo ago
Good idea!
if err != nil
if err != nilOP16mo ago
No description
if err != nil
if err != nilOP16mo ago
so /operations/sensors is the root where I see the left panel (table) and will conditionally render the right component based on the route Created a new folder just to test and changed the RouterLink to="settings" /operations/sensors/settings Open a new page And I think the base configuration is the culprit here
export const operationsRoute = new Route({
getParentRoute: () => rootRoute,
path: "operations",
component: Chrome,
});

export default function Chrome() {
return (
<div
style={{
display: "grid",
height: "100vh",
gridTemplateAreas: "'header' 'content'",
gridTemplateRows: "auto 1fr",
gridTemplateColumns: "1fr",
}}
>
<div
style={{ gridArea: "header", borderBottom: "1px solid var(--gray-a5)" }}
>
<Header />
</div>

<div
style={{
gridArea: "content",
overflow: "hidden",
}}
>
<Outlet />
<TanStackRouterDevtools />
</div>
</div>
);
}
export const operationsRoute = new Route({
getParentRoute: () => rootRoute,
path: "operations",
component: Chrome,
});

export default function Chrome() {
return (
<div
style={{
display: "grid",
height: "100vh",
gridTemplateAreas: "'header' 'content'",
gridTemplateRows: "auto 1fr",
gridTemplateColumns: "1fr",
}}
>
<div
style={{ gridArea: "header", borderBottom: "1px solid var(--gray-a5)" }}
>
<Header />
</div>

<div
style={{
gridArea: "content",
overflow: "hidden",
}}
>
<Outlet />
<TanStackRouterDevtools />
</div>
</div>
);
}
Everything is being rendered inside this <Outlet /> If I try to make something like
export const operationsRoute = new Route({
getParentRoute: () => rootRoute,
path: "operations",
component: OperationSensors,
});

export default function OperationSensors() {
return (
<MapProvider>
<TwoPaneLayout header={<Header />} left={<Table />} right={<Outlet />} />
<Outlet />
</MapProvider>
);
}
export const operationsRoute = new Route({
getParentRoute: () => rootRoute,
path: "operations",
component: OperationSensors,
});

export default function OperationSensors() {
return (
<MapProvider>
<TwoPaneLayout header={<Header />} left={<Table />} right={<Outlet />} />
<Outlet />
</MapProvider>
);
}
i'll get an error on the useQuery usage and const context = useRouteContext(routeOptions); etcetc
dan
dan16mo ago
Ah ok im starting to remember bits now Basically how I have it setup is my "layout" router (in your case operationsRoute) is using a pathless route https://avrg.dev/d3SoG.png https://avrg.dev/AvfNv.png https://avrg.dev/yaC0d.png Atm you have every router defining a path, the route you want as the layout should have an Id instead of a path.
Route Paths | TanStack Router Docs
Route paths are used to match parts of a URL's pathname to a route. At their core, route paths are just strings and can be defined using a variety of syntaxes, each with different behaviors. Before we get into those behaviors, let's look at a few important cross-cutting path concerns. Leading and Trailing Slashes
if err != nil
if err != nilOP16mo ago
Pathless route, damn. Let me try to implement somethings after lunch and see if it fixes or changes something

Did you find this page helpful?