MDX lets you use JSX in markdown content and with the help of rehype and remark plugins, you can create custom components and add additional functionality to your markdown content. This page shows some custom MDX components I created to add some custom visual elements to my mdx based blog posts.
Credits and thanks to countless sources for the inspiration and code snippets used to create these components.
I am using a vertical split layout to show the raw markdown content and the rendered content. The top section shows the raw markdown and the bottom section shows the rendered content.
Here is an example split layout:
Markdown content with inline code
.
h1 - h4 headings are supported. Like standard markdown, the number of #
characters at
the beginning of the line determines the heading level.
Unique slugs are automatically generated for each heading using the rehype-slug plugin.
Anchor tags are automatically generated and for each heading using the
rehype-autolink-headings plugin.
The unique slug is used as the anchor tag id
.
A custom rehype plugin is used to automatically generate the table of contents from the
headings. An IntersectionObserver
is used to highlight the current heading in the
table of contents.
Table of contents is only visible on screen / windows wider than 1280px. If you are reading this on a wider screen, you should see the table of contents on the right side of the page. -->
Code blocks, inline code, and code snippets are syntax highlighted using a combination of rehype-pretty-code and a custom rehype plugin, both powered by shiki.style.
Text with inline code
.
The language for syntax highlighting is detected from the code block meta information.
A copy button is automatically added to each code block. The button is only visible on hover. Code blocks usually take up full width, so the button rarely overlaps with the code. But in the sandbox split layout, the button may overlap with the code.
A code block header is automatically added to the code block if a file name is provided
using the fileName
attribute. An icon is also added to the header based on the language.
Footnotes in code blocks are supported using a custom shiki.style transformer.
Line highlighting, line ranges, and line numbers are supported by functionality provided by rehype-pretty-code. Line numbers are automatically hidden on small screens.
By default, the code snippet highlighting assumes the language is shell
. The language
can be changed by providing a lang
prop.
Code snippet by default also take up full width. The width can be changed by providing a
width
prop. A fit-content
value can also be provided to make the code snippet width
fit the content.
npm i lodash
Column A | Column B | Column C |
---|---|---|
A1 | B1 | C1 |
A2 | B2 | C2 |
A3 | B3 | C3 |
Standard markdown tables are supported. But we can also wrap the standard markdown table
in a Table
component to add additional functionality like custom column widths and
captions.
caption
and captionStyle
props can be provided to add a caption to the table. The
captionStyle
prop can be used to style the caption. The captionSide
property can be
used to set the position of the caption.
columnWidths
prop can be used to set the width of each column. The width of each column
is set as a percentage of the total table width. The columnWidths
prop takes a string
with space separated values. The number of values should match the number of columns in
the table.
Column A | Column B | Column C |
---|---|---|
A1 | B1 | C1 |
A2 | B2 | C2 |
A3 | B3 | C3 |