Getting Started
MDXTS is a collection of components and utilities for rendering MDX content, type documentation, and code examples in React.
Automated Setup
The CLI tool is the quickest way to get started using MDXTS.
Run the following command, optionally in the root of your Next.js project, to initialize the blog example or walk through configuring the plugin and rendering a source in an existing project:
npm create mdxts
Manual Setup
Alternatively, follow the manual setup guide below to learn how to configure the Next.js plugin and render a source.
Install
In your Next.js project, run the following command to install the mdxts
package:
npm install mdxts
pnpm add mdxts
bun add mdxts
yarn add mdxts
Configuring the Next.js Plugin
The Next.js plugin sets up everything needed for authoring MDX files and collecting type documentation from TypeScript source files throughout your projects.
The plugin includes default remark plugins, MDX components, and a Webpack loader for gathering collections of modules and their related metadata.
import { createMdxtsPlugin } from 'mdxts/next'
const withMdxts = createMdxtsPlugin({
theme: 'nord',
gitSource: 'https://github.com/souporserious/mdxts',
})
export default withMdxts({
// Next.js config options here...
})
The theme
option is used for syntax highlighting code blocks and is powered by Shiki. The theme
value should correspond to either a built-in theme or a source path to a custom JSON theme that adheres to the VS Code theme specification.
Defining a Data Source
Use the createSource
utility to generate helpers for gathering metadata about MDX and TypeScript source files. This can be used to build routes for rendering content, documentation, and examples.
Routing
The paths
helper provides a list of paths to generate static routes:
import { createSource } from 'mdxts'
export const allDocs = createSource('docs/**/*.mdx')
allDocs.paths() // => [['docs', 'getting-started'], ['docs, 'authoring']]
Visit the routing section for more information on how to use paths
to generate routes.
Rendering Content
Use the get
method from the allDocs
source we created above to retrieve the metadata for a specific document and render its content:
import { notFound } from 'next/navigation'
import { allDocs } from '../../../data'
type Props = { params: { slug: string[] } }
export default async function Page({ params }: Props) {
const doc = await allDocs.get(params.slug)
if (!doc) {
return notFound()
}
const { Content } = doc
return <Content />
}
Rendering Type Documentation
If the targeted source files are TypeScript files, the exported types will also be analyzed and included along with other metadata like associated MDX content and examples:
import { createSource } from 'mdxts'
import { notFound } from 'next/navigation'
type Props = { params: { slug: string[] } }
const allComponents = createSource('components/**/*.tsx')
export default async function Page({ params }: Props) {
const component = await allComponents.get(params.slug)
if (!component) {
return notFound()
}
const { Content, exportedTypes } = component
return (
<>
{Content ? <Content /> : null}
<ul>
{exportedTypes.map((type) => (
<li key={type.name}>
<h4>{type.name}</h4>
<p>{type.description}</p>
{type.types.map((type) =>
type.properties ? (
<ul>
{type.properties.map((property) => (
<li key={property.name}>
<h5>{property.name}</h5>
<p>{property.description}</p>
</li>
))}
</ul>
) : (
type.text
)
)}
</li>
))}
</ul>
</>
)
}
index
file will be used to infer public exports. If these
both fail, the entire directory will be analyzed.Type Checking Code Blocks
All code blocks will automatically be type-checked using the TypeScript compiler to ensure code works as expected.
Notice the following will throw a type error because b
is not defined:
const a = 1
a + b
This can be configured by passing allowErrors
to disable type checking like in the following example:
```tsx allowErrors
const a = 1
a + b
```
const a = 1
a + b
Alternatively, override the pre
component in a top-level mdx-components.tsx
file to allow errors by default in MDX content:
import { MDXComponents } from 'mdxts/components'
export function useMDXComponents() {
return {
...MDXComponents,
pre: (props) => <MDXComponents.pre allowErrors {...props} />,
} satisfies MDXComponents
}
Allowing type errors is useful to show incomplete or incorrect code examples in documentation for educational purposes. However, it’s highly encouraged to disallow errors if possible so code examples are always using code that can compile.
Read more about type checking to learn how the TypeScript compiler is used for providing type information for code blocks and validating front matter fields.
Examples
To associate examples with a source file, create a sibling file with the same name and a .examples.tsx
extension:
import { Button } from './Button'
export const Basic = () => <Button>Click Me</Button>
When collecting information about a TypeScript source file (Button.tsx
in this case), the examples will be included in the metadata. Read more about examples to learn how to generate interactive documentation and render them to a route.
Next Steps
Check out the routing section to learn how to generate routes for your content and documentation.