Link Column in Material UI DataGrid - DAV-1000/react-material GitHub Wiki
Created: 8/6/2025 15:05
Updated: 8/6/2025 15:07
Exported: 8/14/2025 14:16
Link: https://chatgpt.com/c/689360b8-5cec-832f-af13-1de9c7af31b5
I have implemented the Material UI Community DataGrid in my Typescript React app. The grid consumes an array of BlogPosts. I want to modify the title field of the grid such that when the user clicks on it, the site navigates to the post detail page via the react-router-dom. The route for the post detail page is configured like this: <Route path="/posts/:id" element={} />. Each entity in the grids datasource has the format: { "id": "1", "img": "https://picsum.photos/800/450?random=1", "tag": "Engineering, Company", "title": "Revolutionizing software development with cutting-edge tools", "description": "Our latest engineering tools are designed to streamline workflows and boost productivity. Discover how these innovations are transforming the software development landscape.", "authors": [ { "name": "Remy Sharp", "avatar": "/static/images/avatar/1.jpg" }, { "name": "Travis Howard", "avatar": "/static/images/avatar/2.jpg" } ] }
Thought for a few seconds
The user wants to make a title cell clickable to navigate to a post detail route. In a React app using MUI DataGrid, with react-router-dom v6, I can use the useNavigate
hook. I’ll define the column like this: renderCell: (params) => <Link to={
/posts/${params.row.id}}>{params.value}</Link>
. I need to properly type it with GridColDef
or GridRenderCellParams
in TypeScript. Also, I'll ensure row selection doesn't interfere by using event.stopPropagation
in the onClick
handler.
Done
Nice — that’s a common pattern. Below are two clean TypeScript + React Router v6 approaches you can drop into your MUI DataGrid. Both navigate to /posts/:id
when the title cell is clicked and avoid interfering with row selection or row click handlers.
- Recommended — use MUI
Link
withreact-router-dom
Link
(declarative)
This is straightforward and keeps semantics (an anchor) correct. We stop the cell click from propagating so DataGrid row selection/handlers don’t also fire.
// PostsGrid.tsx
import React from "react";
import { DataGrid, GridColDef, GridRenderCellParams } from "@mui/x-data-grid";
import Link from "@mui/material/Link";
import { Link as RouterLink } from "react-router-dom";
interface Author { name: string; avatar?: string; }
interface BlogPost {
id: string;
img: string;
tag: string;
title: string;
description: string;
authors: Author[];
}
interface Props { posts: BlogPost[]; }
export default function PostsGrid({ posts }: Props) {
const columns: GridColDef[] = [
{ field: "id", headerName: "ID", width: 80 },
{
field: "title",
headerName: "Title",
flex: 1,
renderCell: (params: GridRenderCellParams<string, BlogPost>) => {
// stopPropagation prevents DataGrid row click/selection from also being triggered
const handleClick = (event: React.MouseEvent) => {
event.stopPropagation();
};
return (
<Link
component={RouterLink}
to={`/posts/${params.row.id}`}
underline="hover"
onClick={handleClick}
// optional: style or typography props here
>
{params.value}
</Link>
);
},
},
{ field: "tag", headerName: "Tags", width: 200 },
{ field: "description", headerName: "Description", flex: 2 },
// ...other columns
];
return (
<div style={{ height: 600, width: "100%" }}>
<DataGrid
rows={posts}
columns={columns}
getRowId={(row) => row.id}
pageSize={10}
rowsPerPageOptions={[10, 25]}
disableSelectionOnClick // optional: also helpful to avoid selection when clicking cells
/>
</div>
);
}
Why use this?
- Declarative (SEO/semantics friendly).
- Works with right-click / open-in-new-tab (browser default) if user uses modifier keys.
- Easy to style via MUI
Link
.
- Programmatic navigation with
useNavigate
If you prefer to run logic before navigation (analytics, checks), use useNavigate
. Don’t forget stopPropagation()
.
import React from "react";
import { DataGrid, GridColDef, GridRenderCellParams } from "@mui/x-data-grid";
import { useNavigate } from "react-router-dom";
export default function PostsGrid({ posts }: { posts: BlogPost[] }) {
const navigate = useNavigate();
const columns: GridColDef[] = [
{
field: "title",
headerName: "Title",
flex: 1,
renderCell: (params: GridRenderCellParams<string, BlogPost>) => {
const onClick = (e: React.MouseEvent) => {
e.stopPropagation();
// optionally run analytics/logic here
navigate(`/posts/${params.row.id}`);
};
return (
<button
onClick={onClick}
style={{
background: "none",
border: "none",
padding: 0,
margin: 0,
cursor: "pointer",
textDecoration: "underline",
color: "inherit",
font: "inherit",
}}
>
{params.value}
</button>
);
},
},
// ...other columns
];
return (
<div style={{ height: 600, width: "100%" }}>
<DataGrid rows={posts} columns={columns} getRowId={(r) => r.id} />
</div>
);
}
Note: Using a <button>
loses native anchor behaviors (open in new tab), so prefer approach #1 if you want normal browser link behavior.
-
event.stopPropagation()
inrenderCell
is essential if you have row-level click handlers or want to avoid row selection when clicking the link. -
getRowId={(r) => r.id}
is useful if your id is a string or not located onrow.id
by default. - If you want the whole row clickable (not just the title), you can use
onRowClick
withuseNavigate
, but then make sure clicking a link inside the row doesn’t double-navigate (usestopPropagation()
on the link). - Types:
renderCell: (params: GridRenderCellParams<string, BlogPost>) => JSX.Element
gives good TS typing.
If you want, I can adapt the example to:
- Use MUI
Typography
+Link
styling, - Add right-click/open-in-new-tab support (the declarative Link approach does this automatically),
- Or show how to make the entire row navigate while still allowing the title link to open in a new tab. Which would you like?
Powered by ChatGPT Exporter