# How to Add Custom MDX Components to Docusaurus Pages

> Learn how to add custom MDX components to Docusaurus. Easily integrate custom React components globally into your Docusaurus site by modifying MDXComponents.tsx.

- Repository: [Meta/docusaurus](https://github.com/facebook/docusaurus)
- Tags: how-to-guide
- Published: 2026-03-04

---

**You add custom MDX components to Docusaurus by creating a [`src/theme/MDXComponents.tsx`](https://github.com/facebook/docusaurus/blob/main/src/theme/MDXComponents.tsx) file that imports and wraps the default component map from `@theme-original/MDXComponents`, allowing you to register custom React components that become globally available in every MDX file without requiring imports.**

Docusaurus renders every `.mdx` file inside an `MDXProvider` that relies on a component mapping system to translate custom JSX tags into React components. According to the facebook/docusaurus source code, this mapping lives in `@theme/MDXComponents` and is implemented at [`packages/docusaurus-theme-classic/src/theme/MDXComponents/index.tsx`](https://github.com/facebook/docusaurus/blob/main/packages/docusaurus-theme-classic/src/theme/MDXComponents/index.tsx). By wrapping this default export rather than editing it directly, you can extend the global MDX scope with your own interactive elements while preserving upstream compatibility.

## Understanding the MDX Provider Architecture

The `MDXContent` component ([`packages/docusaurus-theme-classic/src/theme/MDXContent/index.tsx`](https://github.com/facebook/docusaurus/blob/main/packages/docusaurus-theme-classic/src/theme/MDXContent/index.tsx)) serves as the entry point for all MDX pages. It wraps content in an `MDXProvider` and passes a component map that tells MDX how to resolve tags like `<Highlight>` or `<Tabs>`.

The default component map resides in [`packages/docusaurus-theme-classic/src/theme/MDXComponents/index.tsx`](https://github.com/facebook/docusaurus/blob/main/packages/docusaurus-theme-classic/src/theme/MDXComponents/index.tsx). Docusaurus uses a theme-resolution algorithm that automatically prefers user-provided files over built-in theme files, meaning any file you create at `src/theme/MDXComponents.{js,tsx}` will override the default without modifying node_modules.

## Creating a Custom React Component

First, build the React component you want to expose to MDX. Store it in your project's `src/components` directory.

```tsx
import React from 'react';
import clsx from 'clsx';
import styles from './Highlight.module.css';

export default function Highlight({
  children,
  color = '#ff0',
}: {
  children: React.ReactNode;
  color?: string;
}) {
  return (
    <span className={clsx(styles.highlight)} style={{backgroundColor: color}}>
      {children}
    </span>
  );
}

```

Save this as [`src/components/Highlight.tsx`](https://github.com/facebook/docusaurus/blob/main/src/components/Highlight.tsx). This component accepts children and an optional color prop, rendering a styled span element.

## Wrapping the Default MDX Component Map

Instead of **swizzling** the theme (which copies the original file and risks divergence from future Docusaurus releases), you should **wrap** the default mapping. Create a new file at [`src/theme/MDXComponents.tsx`](https://github.com/facebook/docusaurus/blob/main/src/theme/MDXComponents.tsx):

```tsx
import React from 'react';
// Import the original mapping supplied by the classic theme
import MDXComponents from '@theme-original/MDXComponents';
// Import the custom component you just created
import Highlight from '@site/src/components/Highlight';

// Export a new map that merges the original with your additions
export default {
  // Keep all built-in mappings (Tabs, Details, etc.)
  ...MDXComponents,
  // Register the custom tag <Highlight>
  Highlight,
};

```

This pattern—explicitly documented in `website/docs/guides/markdown-features/markdown-features-react.mdx` at lines 68-82—preserves all default Docusaurus MDX components while adding your custom entries to the global scope.

## Using Custom Components in MDX Files

Once registered in [`MDXComponents.tsx`](https://github.com/facebook/docusaurus/blob/main/MDXComponents.tsx), your component is available in any `.mdx` file throughout your site without import statements:

```mdx

# My Awesome Page

Here is a highlighted word: <Highlight color="#25c2a0">Docusaurus green</Highlight>.

And here is default highlighting: <Highlight>Yellow highlight</Highlight>.

```

The MDX compiler automatically resolves the `<Highlight>` tag to your React component via the provider's component map.

## Advanced: Manual MDXProvider Usage

If you need to render MDX content inside a pure React page (for example, when importing an MDX file into a custom page component), wrap it with `MDXContent` to ensure the component map is available:

```tsx
import React from 'react';
import MDXContent from '@theme/MDXContent';
import MyMdxPage from './my-page.mdx';

export default function Wrapper() {
  return (
    <MDXContent>
      <MyMdxPage />
    </MDXContent>
  );
}

```

As noted in the official guide (lines 99-107 of `markdown-features-react.mdx`), this ensures your custom components and all default Docusaurus MDX components resolve correctly in non-standard rendering contexts.

## Summary

- **Create** [`src/theme/MDXComponents.tsx`](https://github.com/facebook/docusaurus/blob/main/src/theme/MDXComponents.tsx) in your project to extend the global MDX component map.
- **Import** the original mapping using `@theme-original/MDXComponents` to preserve default components like `Tabs` and `Details`.
- **Spread** the original components and append your custom React components to make them globally available.
- **Avoid swizzling** `@theme/MDXComponents` to prevent merge conflicts when upgrading Docusaurus versions.
- **Use** custom tags directly in any `.mdx` file without import statements once registered.

## Frequently Asked Questions

### What is the difference between wrapping and swizzling MDXComponents?

Swizzling copies the entire `MDXComponents` source from [`packages/docusaurus-theme-classic/src/theme/MDXComponents/index.tsx`](https://github.com/facebook/docusaurus/blob/main/packages/docusaurus-theme-classic/src/theme/MDXComponents/index.tsx) into your project, making you responsible for maintaining that code through Docusaurus updates. Wrapping imports the original via `@theme-original/MDXComponents` and exports a modified version, ensuring you receive upstream bug fixes and new features automatically while only managing your additive changes.

### Can I override default Docusaurus MDX components like Tabs or Details?

Yes. When you spread `...MDXComponents` into your exported object, you can overwrite specific keys. For example, adding `Details: MyCustomDetails` after the spread will replace the default collapsible details component with your implementation across all MDX files.

### Do I need to import custom components in every MDX file?

No. Once you register a component in [`src/theme/MDXComponents.tsx`](https://github.com/facebook/docusaurus/blob/main/src/theme/MDXComponents.tsx), it becomes part of the global MDX scope provided by the `MDXProvider`. You can use the component immediately in any `.mdx` file without import statements, as the tag is resolved automatically during the MDX compilation process.

### How do I use MDX components in pure React pages?

Import the `MDXContent` component from `@theme/MDXContent` and wrap your imported MDX content with it. This ensures the component map—including your custom registrations—is injected into the React tree, allowing MDX tags to resolve correctly even outside of standard documentation pages.