diff --git a/docs/guides/injecting-components.mdx b/docs/guides/injecting-components.mdx
new file mode 100644
index 000000000..bcd5fced8
--- /dev/null
+++ b/docs/guides/injecting-components.mdx
@@ -0,0 +1,120 @@
+export const info = {
+ author: [
+ {github: 'wooorm', name: 'Titus Wormer', twitter: 'wooorm'}
+ ],
+ modified: new Date('2023-10-24'),
+ published: new Date('2023-10-24')
+}
+export const navSortSelf = 7
+
+# Injecting components
+
+This guide shows how to inject arbitrary components into MDX when it
+runs. {/* more */}
+It shows how the underlying features used by our providers (`@mdx-js/react`,
+`@mdx-js/preact`) and the [`mdx-components.tsx`][next-mdx-components] file
+supported by Next.js work,
+and how you can take advantage of that functionality yourself.
+
+In many cases you do not need this,
+as you can pass components to MDX:
+
+```mdx path="example.mdx"
+# Hello **
+```
+
+You can pass `Planet` and say a component used instead of the `h1`:
+
+```tsx path="example.jsx"
+import Example from './example.mdx' // Assumes an integration is used to compile MDX -> JS.
+
+
+ }
+ }}
+/>
+```
+
+When you find yourself passing that `components` prop around a lot,
+you might want to look at an alternative.
+You might reach for our context based providers (`@mdx-js/react`,
+`@mdx-js/preact`),
+but context has performance downsides and context doesn’t always work (such as
+in RSC).
+
+But first,
+how does component passing work?
+That can be illustrated by looking at the code generated by MDX for the above
+`example.mdx`.
+Here is a diff that shows what the example normally compiles to and what
+changes when `providerImportSource: 'xxx'` is passed:
+
+```diff
+@@ -1,7 +1,13 @@
+ import {jsx as _jsx, jsxs as _jsxs} from 'react/jsx-runtime'
++import {useMDXComponents as _provideComponents} from 'xxx'
+
+ function _createMdxContent(props) {
+- const _components = {em: 'em', h1: 'h1', ...props.components}
++ const _components = {
++ em: 'em',
++ h1: 'h1',
++ ..._provideComponents(),
++ ...props.components
++ }
+ const {Planet} = _components
+ if (!Planet) _missingMdxReference('Planet', true)
+ return _jsxs(_components.h1, {
+@@ -10,7 +16,7 @@ function _createMdxContent(props) {
+ }
+
+ export default function MDXContent(props = {}) {
+- const {wrapper: MDXLayout} = props.components || {}
++ const {wrapper: MDXLayout} = {..._provideComponents(), ...props.components}
+ return MDXLayout
+ ? _jsx(MDXLayout, {...props, children: _jsx(_createMdxContent, {...props})})
+ : _createMdxContent(props)
+```
+
+Observe that components have defaults (such as that `h1` will use `'h1'`) and
+that components are taken from `props.components`.
+What changes is an added call to `_provideComponents`,
+which refers to an `useMDXComponents` export from the module we specified
+(`xxx`).
+
+We can use this interface to inject components from a file.
+In that file,
+we need a `useMDXComponents` function that returns our components.
+
+```tsx path="mdx-components.js"
+/** @returns {import('mdx/types.js').MDXComponents} */
+export function useMDXComponents() {
+ return {
+ Planet() {
+ return 'Pluto'
+ },
+ h1(props) {
+ return
+ }
+ }
+}
+```
+
+And now passing a file path or URL to that file as `providerImportSource`,
+such as with `import.meta.resolve('./mdx-components.js')`:
+
+```diff
+@@ -1,5 +1,5 @@
+ import {jsx as _jsx, jsxs as _jsxs} from 'react/jsx-runtime'
+-import {useMDXComponents as _provideComponents} from 'xxx'
++import {useMDXComponents as _provideComponents} from 'file:///Users/tilde/…/mdx-components.js'
+```
+
+Now our locally defined components will be used in all MDX files!
+
+[next-mdx-components]: https://nextjs.org/docs/pages/building-your-application/configuring/mdx