👀 Our most exciting product launch yet 🚀 Join us May 8th for Sanity Connect

How to render a table from Sanity using portabletext/react.

7 replies
Last updated: Aug 31, 2022
Hi everyone, I want to render a table from sanity using portabletext/react but I don't know how to do that. Please what do I do?
Aug 30, 2022, 10:14 PM
Hey there! Have you already added the table schema to your portable text?
Aug 30, 2022, 10:26 PM
The table is part of a sanity rich text field, I have already defined how to render the image, but I don't know how to render a table
user M
Aug 30, 2022, 10:29 PM
Got it. Let me see if I can find an example of a serializer for this.
Aug 30, 2022, 10:52 PM
user D
you can create a
Table
component like so:
const Table = ({value}) => {
    return (
      <table>
        {value.rows.map(row =>
          <TableRow row={row} />)}
      </table>
    )
  }
Then create a
TableRow
component:
const TableRow = ({row}) => {
    return (
      <tr>{row.cells.map(cell =>
        <td>{cell}</td>)}</tr>
    )
  }
Then add both of those to your
components
object:
const components = {
    types: {
      table: Table,
      tableRow: TableRow,
      // any other types you want to define
    },
  }
And finally pass that
components
object to your
PortableText
component like so:
<PortableText
  components={components}
  value={_rawField}        
/>
Aug 30, 2022, 10:53 PM
user X
Ok I'll try this now, thank you
Aug 30, 2022, 10:55 PM
One thing about Luke’s approach is that it’s not accessible at all. Someone using an assistive technology such as a screen-reader will not be able to navigate the content because this table doesn’t contain any header.
Aug 31, 2022, 7:04 AM
Maybe something like this:
function BlockTable(props) {
  const [head, ...rows] = props.value.rows
  const isBiDirectional = head.cells[0].length === 0

  return (
    <table>
      <thead>
        <tr>
          {head.cells.map(cell => (
            <th key={cell}>{cell}</th>
          ))}
        </tr>
      </thead>
      <tbody>
        {rows.map((row, index) => (
          <tr key={index}>
            {row.cells.map((cell, index) => {
              const Component = isBiDirectional && index === 0 ? 'th' : 'td'
              return <Component>{cell}</Component>
            })}
          </tr>
        ))}
      </tbody>
    </table>
  )
}
Aug 31, 2022, 7:05 AM

Sanity– build remarkable experiences at scale

Sanity is a modern headless CMS that treats content as data to power your digital business. Free to get started, and pay-as-you-go on all plans.

Was this answer helpful?