Sanity Datatable serializer for 11ty sites

Katie - Sep 10 '20 - - Dev Community

Playing with the 11ty (Eleventy) code from Bryan Robinson's sanity-eleventy-blog repo (from Sanity's official tutorial on 11ty) and a Sanity project started using the built-in "blog" dataset, I got stuck adding Fred Jens's sanity-datatable Sanity Studio plugin to the body rich-text editor of Sanity because 11ty threw an error: "Unknown block type 'table', please specify a serializer for it in the serializers.types prop."

The solution was to edit the object exported from Bryan's utils/serializers.js as module.exports, adding the following to it:

,
    table: ({node}) => `
<table>
  <thead>
    <tr><th scope="col">${node.rows[0].cells.join('</th><th scope="col">')}</th></tr>
  </thead>
  <tbody>
    ${node.rows.slice(1).map(row => '<tr><td>' + row.cells.join('</td><td>') + '</td></tr>').join('\r\n    ')}
  </tbody>
</table>
      `

This is because the datatable plugin returns data that looks like this:

{
  "_key": "abc123",
  "_type": "table",
  "rows": [
    {
      "_key": "def456",
      "_type": "column",
      "cells": ["Row 1 Cell 1 Value Here", "Row 1 Cell 2 Value Here"]
    },
    {
      "_key": "ghi789",
      "_type": "column",
      "cells": ["Row 2 Cell 1 Value Here", "Row 2 Cell 2 Value Here"]
    },
    {
      "_key": "zyx987",
      "_type": "column",
      "cells": ["Row 3 Cell 1 Value Here", "Row 3 Cell 2 Value Here"]
    }
  ]
}

What my JavaScript transforms Sanity's output into is this snippet of (hopefully accessible) HTML-formatted text:

<table>
  <thead>
    <tr><th scope="col">Row 1 Cell 1 Value Here</th><th scope="col">Row 1 Cell 2 Value Here</th></tr>
  </thead>
  <tbody>
    <tr><td>Row 2 Cell 1 Value Here</td><td>Row 2 Cell 2 Value Here</td></tr>
    <tr><td>Row 3 Cell 1 Value Here</td><td>Row 3 Cell 2 Value Here</td></tr>
  </tbody>
</table>

If you didn't want to treat your first row as a table header, the "serializer" would be a bit shorter:

,
    table: ({node}) => `
<table>
  ${node.rows.map(row => '<tr><td>' + row.cells.join('</td><td>') + '</td></tr>').join('\r\n  ')}
</table>
      `

I'm sure there're more elegant ways to do this if you actually know modern JavaScript, but I'm proud of myself for getting this working at all without asking a friend, so here stands my code in all its clunkiness.

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .