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

Prompt:

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" } ] }

Response:

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.


  1. Recommended — use MUI Link with react-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.

  1. 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.


Extra tips & gotchas

  • event.stopPropagation() in renderCell 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 on row.id by default.
  • If you want the whole row clickable (not just the title), you can use onRowClick with useNavigate, but then make sure clicking a link inside the row doesn’t double-navigate (use stopPropagation() 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

⚠️ **GitHub.com Fallback** ⚠️