Mapping HTML to Vue
@nuxtjs/mdx
installs @mdx/vue
and @mdx/vue-loader
as dependencies in your project. Together they allow you to map Vue components to HTML elements based on the Markdown syntax.
@mdx/vue
exports the MDXProvider
component that accepts an object with a map of all HTML elements you wish to be replaced with the corresponding component during rendering.
Usage
Suppose we have an helloworld.mdx
file with a header element that we would like to replace with a component with it's own styles/interactions.
<!-- helloworld.mdx -->
# Hello, Vue!
Defining components map
First we create a map of components we would like to replace. This instructs the @mdx/vue-loader
to replace all defined keys with the values in the object.
Note the value is a function that provides all properties about the h1
element from the .mdx
file and returns a Vue component. You can also use the regular render function syntax if you prefer that to JSX.
// In `components.js` file
export default {
h1: props => ({
render(h) {
return (
<h1 style={{ color: 'tomato' }} {...props} >
{this.$slots.default}
</h1>
)
}
})
}
// In `components.js` file
export default {
h1: props => ({
render(h) {
return h('h1', {
style: {
color: 'tomato'
},
...props
}, this.$slots.default)
}
})
}
MDXProvider
Providing components map to Wrap your helloworld.mdx
file component inside the MDXProvider
from @mdxjs/vue
and provide it your components map as a prop.
We recommend doing it inside your Nuxt.js layout.
<template>
<MDXProvider :components="components">
<HelloWorld />
</MDXProvider>
</template>
<script>
import { MDXProvider } from '@mdx-js/vue'
import HelloWorld from 'helloworld.mdx'
import components from './components.js'
export default {
components: {
MDXProvider,
HelloWorld
},
data: () => ({
components
})
}
</script>
Yields:
<h1 style="color:tomato">Hello, Vue!</h1>
Examples
An good example of this use case are the Code blocks in the Chakra UI Vue documentation. It uses the MDXProvider
to replace regular codeblocks with live code snippets.