sanity-plugin-stl-table
v0.3.0
Published
Sanity Studio plugin for creating Advance table with Structured Table Language (STL).
Maintainers
Readme
Sanity Plugin: Structured Table (STL)
A Sanity Studio plugin for creating advanced, structured tables using the Structured Table Language (STL).

This plugin empowers your content creators to build complex tables with features like row/column spanning, headers, and rich styling, effectively overcoming the limitations of standard portable text tables.
Full documentation: stl-table.vercel.app — covers STL syntax, renderer setup, frontend integration, and Sanity Studio usage.
🆕 Updates/Changelog
Check our change log file for version-based updates and more details Check Change Log File
✨ Features
- STL Editor: A dedicated input component for writing and managing Structured Table Language (STL).
- Live Preview: Real-time preview of your table within the Sanity Studio.
- Dual Storage: Stores both the raw STL string (
stlString) and a pre-parsed JSON snapshot (stlParsed) — enabling faster frontend rendering without re-parsing. - Advanced Layouts: Support for colspans, rowspans, and complex header structures.
- SSR Friendly: Designed to work seamlessly with Server-Side Rendering (especially Next.js) via the core
structured-tablepackage.
📦 Installation
1. Install the Plugin
npm install sanity-plugin-stl-table
# or
yarn add sanity-plugin-stl-table
# or
pnpm add sanity-plugin-stl-tableNote: This plugin requires
react>= 18 andsanity>= 3.0.0 (Supports Sanity v3, v4, and v5).
2. Setup Table Render Components (Required for Studio Preview)
To enable the interactive table preview within Sanity Studio, install the CLI and add the React renderer components using structured-table-cli.
npm install structured-table-cliThen run the following command to download the pre-built React table components:
npx stl-cli add reactOptional: Specify a custom path for the components:
npx stl-cli add react --path ./schemaTypes/components3. Register Components in Sanity Config
After generating the components, register them in your sanity.config.ts. Import the register file (found in the folder where components were installed) at the top of your config.
For example, if installed in schemaTypes/components:
// sanity.config.ts
import './schemaTypes/components/register' // Base path depends on where you installed it
import { defineConfig } from 'sanity'
import { stlTableBlock } from 'sanity-plugin-stl-table'
export default defineConfig({
// ... configuration
})🚀 Sanity Studio Implementation
1. Import the Schema
Import the stlTableBlock schema definition and add it to your Sanity Studio configuration types array.
// sanity.config.ts
import { defineConfig } from 'sanity'
import { stlTableBlock } from 'sanity-plugin-stl-table'
export default defineConfig({
// ...
schema: {
types: [
// ... other types
stlTableBlock,
],
},
})2. Use in Portable Text or as a Field
In Portable Text:
// schemas/blockContent.ts (or similar)
export default {
title: 'Block Content',
name: 'blockContent',
type: 'array',
of: [
{ type: 'block' },
{ type: 'stlTableBlock' },
],
}As a Field:
export default {
name: 'productSpecification',
title: 'Product Specification',
type: 'document',
fields: [
{
name: 'title',
type: 'string',
},
{
name: 'specsTable',
title: 'Specifications Table',
type: 'stlTableBlock',
},
],
}3. Studio Usage
Restart your Sanity dev server. You will now see an input field where you can paste or write your STL code.
Check the following video to learn how to use the block inside Sanity Studio.
The table preview updates automatically as you type, giving you immediate feedback on your table structure and content.
4. Create a Table in STL Language
Use our interactive live table editor at stl-table.vercel.app/playground to build your entire table visually and export it in STL format.
💻 Frontend Implementation
To render the structured tables on your frontend (e.g., Next.js, Remix), follow these steps.
Full integration guide: stl-table.vercel.app/docs
1. Install Dependencies
npm install structured-table
npm install structured-table-cliAdd the React renderer to your project (replace react with vue for Vue projects):
npx stl-cli add react2. Render in Portable Text
The plugin stores two fields in Sanity for each table block:
| Field | Type | Purpose |
|-------|------|---------|
| stlString | string | Raw STL source written by the editor |
| stlParsed | string (JSON) | Pre-parsed SanityTable object — use JSON.parse() to consume |
| caption | string | Optional table caption |
Recommended pattern — use stlParsed when available (no re-parsing), fall back to STL.parse(stlString) for older documents:
import * as STLReact from './components/react' // Path to your generated components
import { STL, SanityTable } from 'structured-table'
const myPortableTextComponents = {
types: {
stlTableBlock: ({ value }: {
value: {
_key: string;
_type: string;
stlString?: string;
stlParsed?: string; // JSON.stringify(SanityTable) — use JSON.parse() to consume
caption?: string;
}
}) => {
// Fast path: use pre-parsed JSON snapshot; fall back to parsing stlString
let tableData: SanityTable | null = null;
try {
if (value.stlParsed) {
tableData = JSON.parse(value.stlParsed) as SanityTable;
} else if (value.stlString) {
tableData = STL.parse(value.stlString);
}
} catch {
return null;
}
if (!tableData) return null;
// Override caption if set in Sanity
if (value.caption) {
tableData.caption = value.caption;
}
return <STLReact.Table data={tableData} className='border' />
}
}
}
// Usage in your PortableText component
// <PortableText value={data.body} components={myPortableTextComponents} />
stlParsedis available on documents saved with plugin version > 0.3.0. For older documents it will beundefined, and the fallbackSTL.parse(stlString)handles them transparently.
🛠 How it Works
- Dual Storage: When an editor types STL, the plugin stores the raw string in
stlStringand simultaneously stores a pre-parsed JSON snapshot instlParsed. This means your frontend never needs to run the parser at request time. - Input Component: The custom
TableInputinterface lets editors write STL directly, with a live preview updating in real time. Caption is managed inline as a separate text field. - Migration Layer: The input reads
stlParsedfirst (fast path). If absent (older documents), it falls back toSTL.parse(stlString). No manual migration is required. - Preview: Inside the Studio, a
TablePreviewcomponent renders the table so editors see exactly what it will look like without leaving the CMS. - Frontend Rendering: On your frontend, consume
stlParseddirectly withJSON.parse(). This avoids the parsing step entirely and works with SSR.
💡 What is it used for?
Standard Sanity tables are great for simple key-value pairs or basic grids. However, they often struggle with:
- Merged Cells: Row spans and column spans.
- Complex Headers: Multi-level headers, column headers, or non-standard grid layouts.
- Rich Styling: Specific alignment, button cells, or complex formatting.
Sanity Plugin Structured Table solves this by leveraging STL, letting you define table structures as flexibly as HTML tables but with a syntax designed for data entry and maintainability.
For the full STL syntax reference and more integration examples, visit stl-table.vercel.app/docs.
📄 License
MIT © Yashraj Yadav

