Contentful DevRel here ππΌ
There have been tickets submitted to wrap <code> tags in <pre> tags, so the feature may be available soonish, in the meantime, the way I've found around this is to create a separate content type for code blocks, and embed those as entries in the Rich Text field editor.
In the Code Block content type, I added the fields description (to help me identify it), language (for styling with e.g. Prism) and code (with type markdown).
Here's a screenshot of the Code Block content type in the Contentful UI
Then, using the @contentful/rich-text-react-renderer which comes with the gatsby-source-contentful/rich-text plugin, I create a bespoke options function that parses the linked entries to pass into the renderRichText function, that renders the code block as an embedded entry with the HTML I need.
Here is a screenshot of the embedded Code Block entries in the Contentful Rich Text editor
Here is the GraphQL query which fetches the Code Block as linked references:
query pageQuery($id: String!) {
contentfulBlogPost(id: { eq: $id }) {
title
slug
# This is the rich text field
bodyRichText {
raw
references {
... on ContentfulCodeBlock {
contentful_id
__typename
description
language
code
}
}
}
}
}
Here is the code that renders the Code Block inline with the HTML using the renderRichText function:
import { BLOCKS, INLINES, MARKS } from "@contentful/rich-text-types"
import { renderRichText } from "gatsby-source-contentful/rich-text"
const options = {
renderNode: {
[BLOCKS.EMBEDDED_ENTRY]: (node) => {
const { __typename } = node.data.target;
switch (__typename) {
case "ContentfulCodeBlock":
const { language, code } = node.data.target;
return (
// add your custom <pre> tags here
<pre className={language}}>
<code>{code}</code>
</pre>
);
default:
return null;
}
},
},
}
// render it
renderRichText(post.richText, options)