
Removing p Tags from Contentful List Items

The combination of Gatsby and Contentful together makes for a very powerful development toolset: a very fast, static, website built on top of a modern and future‑proof(ish) framework, with content management that a client can easily understand and familiarise themselves with.
I've written about some of the more nuanced issues that can arise when integrating with Contentful before, but today I'd like to share one of my personal pet peeves: superfluous elements and non‑standard markup structure.
Specifically: the way that Contentful likes to wrap the content of list items, inside of a <p>, resulting in generated markup that looks like this:
<ul> <li> <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit.</p> </li> <li> <p>Nulla viverra est vel cursus facilisis.</p> </li> <li> <p>Nam a tempor dolor, commodo sodales felis.</p> </li></ul>Yuck.
I feel that this likely relates back to something I've said before about Contentful: they provide rich content as an object, where each node roughly correlates to a block‑level element (e.g., a <p>), so more often than not, items which you would generally expect to be block‑level themselves (e.g., an <li>) are not.
Fortunately, they do provide LIST_ITEM as a BLOCK type within @contentful/rich‑text‑types, which at least means we can target list items specifically when it comes to rendering them.
Sergio Pellegrini on the GitHub issue provides the answer, which I have modified a little here:
[BLOCKS.LIST_ITEM]: (node, children) => { const transformedChildren = documentToReactComponents(node, { renderMark: options.renderMark, renderNode: { [BLOCKS.PARAGRAPH]: (node, children) => children, [BLOCKS.LIST_ITEM]: (node, children) => children, }, }); return <li>{transformedChildren}</li>;}Fundamentally what this is doing is within renderNode, where we come across a LIST_ITEM, it transforms the children by passing them back through documentToReactComponents(). Where it finds a child of type PARAGRAPH, it returns the children of that, without any wrapping markup.
Where I've edited this compared to the original solution on GitHub is to also option renderMark, which points back to the original options variable. This means that any marks that appear within the list item (inline items: bold, underline, inline code, etc) will still get rendered as I've defined. If you have not defined any special handling of marks, you should omit this line.
Related Articles

Rendering Contentful Rich Code Snippets in Gatsby. 
How to Use grid in CSS. How to Use
gridin CSS
Implementing a Trie in TypeScript: Solving 'Implement Trie (Prefix Tree)'. Implementing a Trie in TypeScript: Solving 'Implement Trie (Prefix Tree)'

Will AI Replace Front‑End Developers? Will AI Replace Front‑End Developers?

Understanding File‑System Routing in Next.js. Understanding File‑System Routing in Next.js

Creating and Dispatching Custom Events in JavaScript. Creating and Dispatching Custom Events in JavaScript

The Difference Between == and === in JavaScript. The Difference Between
==and===in JavaScript
Object.assign() in JavaScript: Merging and Shallow Copies. Object.assign()in JavaScript: Merging and Shallow Copies
Creating Interactive User Interfaces with HTML, CSS, and JavaScript. Creating Interactive User Interfaces with HTML, CSS, and JavaScript

Sorting Objects in JavaScript. Sorting Objects in JavaScript

Browser vs. Node.js in JavaScript: Why Code Works in One and Fails in the Other. Browser vs. Node.js in JavaScript: Why Code Works in One and Fails in the Other

The Palindrome Number Problem: Strings vs. Maths in JavaScript. The Palindrome Number Problem: Strings vs. Maths in JavaScript