Managing payload cms lexical tables in a content-heavy site means enabling EXPERIMENTAL_TableFeature — but the real trap is the markdown import that strips tables without warning. We lost a whole batch of production blog posts to this exact hole before we found the fix. Here’s why it happens and the step-by-step configuration that keeps your tables intact.
The Silent Table Eater: Payload CMS Lexical Tables and Markdown Conversion
The default markdown-to-Lexical conversion helper completely ignores your editor’s feature list. So even when you’ve added the table feature to your editor config, every GFM table in imported markdown is silently dropped.
Here’s the code that ate our data:
import { editorConfigFactory, defaultFeatures } from '@payloadcms/richtext-lexical'
// ❌ This uses a plain config that doesn’t know about tables
const mdConverter = editorConfigFactory.default({
features: defaultFeatures,
})
const lexicalData = mdConverter.parse('# Hellonn| A | B |n|---|---|n| 1 | 2 |')
// result: { root: … } — no table node anywhere
Enter fullscreen mode Exit fullscreen mode
The problem: editorConfigFactory.default builds a conversion pipeline from a static feature set, not from your actual editor config. Any experimental or custom feature you’ve wired into the editor simply isn’t there during markdown parsing.
Fix It: Wire EXPERIMENTAL_TableFeature Into the Conversion Config
Switch to editorConfigFactory.fromFeatures, which actually reads the feature array you provide. Include the table feature alongside the defaults, and the markdown converter will start producing proper Lexical table nodes.
import {
editorConfigFactory,
defaultFeatures,
EXPERIMENTAL_TableFeature,
} from '@payloadcms/richtext-lexical'
const mdConverter = editorConfigFactory.fromFeatures({
features: [...defaultFeatures, EXPERIMENTAL_TableFeature()],
})
Enter fullscreen mode Exit fullscreen mode
Takeaway: You must add EXPERIMENTAL_TableFeature() to both your editor’s features array and to every markdown conversion config. Missing one side silently eats your data.
Render Tables in Your RichText Component
Once the nodes are saved correctly, you still need to decide how they show up on the frontend. We use custom JSX converters so that table, table row, and table cell nodes render as real <table> elements.
// A minimal table converter for Payload’s Lexical RichText serialiser
const TableNode = ({ nodeKey, children }) => (
<table key={nodeKey}>
<tbody>{children}</tbody>
</table>
)
const converters = {
table: TableNode,
tablerow: ({ children }) => <tr>{children}</tr>,
tablecell: ({ children }) => <td>{children}</td>,
}
Enter fullscreen mode Exit fullscreen mode
Plug these into your RichText component’s converters prop. If you’re building a production frontend that needs to handle every Lexical node type — blocks, uploads, and relational data — our web development services can help craft a rendering pipeline that doesn’t break.
Salvage: Repair Posts That Already Lost Their Tables
If you imported markdown before applying the fix, the original table data is gone from Lexical’s state. But if you still have the source markdown, you can repair the posts.
We wrote a one-off Node script that:
- Queries posts missing table nodes but containing the raw markdown in a separate field.
- Re-runs the markdown through the corrected
editorConfigFactory.fromFeaturesconverter. - Writes the now-table-aware Lexical JSON back to the document.
It’s not a pretty process, but it recovered every lost table for us. Platform services that handle complex content migrations often need this kind of surgical repair, and having the right conversion config from day one saves a lot of pain.
FAQ
Why do my Payload Lexical tables disappear when I import markdown?
The default markdown-to-Lexical conversion helper ignores your editor features. Without EXPERIMENTAL_TableFeature explicitly included in the editorConfigFactory.fromFeatures call, every table node is silently dropped during parsing.
How do I add GFM table support to Payload’s Lexical editor?
Enable EXPERIMENTAL_TableFeature in both the editor’s features array and the markdown conversion config (using editorConfigFactory.fromFeatures). Then add custom JSX converters to your RichText component to render <table> elements on the frontend.
Can I recover tables that were lost from earlier markdown imports?
Yes, if the original markdown source is still stored. A one-off repair script can loop through affected posts, re-convert the markdown with the fixed config, and save the resulting Lexical JSON that now includes table nodes.
답글 남기기