MDX and VueJS/NuxtJS

Jonathan Bakebwa introduces MDX support for VueJS and NuxtJS while also using Chakra UI Vue for MDX components

Transcript

Jonathan Bakebwa: [0:01] Hey, everyone. My name is Jonathan Bakebwa. I am from Uganda, and I live in Beijing, China. I'm really happy to be here today. I've had the privilege of working with Scott and John with all of Vue projects with the MDX and Vue.js community, so I'm humbled to be here.

[0:24] I'm happy to share with everyone and also to learn from everyone. I've enjoyed the event so far. The events leading up to today, so that's exciting. Today, I'm going to be talking about MDX and Vue.js and Nuxt. If you didn't already know, you can start using MDX inside your Vue projects.

[0:48] If your Vue develop on, your watching this for the very first time, you shouldn't worry, "Will I be able to use MDX in my Vue projects?" Yes, now you can. It's simple to get started. Today, I'm hoping that this talk will encourage you to get started with it.

[1:07] First of all, for those of us that do not know what is MDX, so MDX is an authorable format that lets you write JSX in your Markdown documents. It allows you to write JavaScript Vue components as well in your Markdown documents.

[1:27] This definition, of course, I stole shamelessly from the official MDX documentation site because I needed slides, [laughs] but it is true. What this allows us to do is to write long-form content like documentation in a manner that also closely follows concepts like component-driven design.

[1:50] What MDX allows us to do is to turn our Markdown files into Vue components that you can import in your project wherever you need them, which is cool. It exposes a lot of capabilities. To get started with a Vue.js project, you can get started by installing the @mdx-js/vue-loader using NPM or yarn.

[2:16] After you install it, we then include the MDX loader inside your project's webpack config. If you're using the Vue CLI, you'd need to create a vue.config.js file and on the configure webpack property, you need to include the mdx-js/vue-loader under the module rules. It's the exact same thing when using the webpack config.js, if you scaffolded your project yourself.

[2:50] After you have done that, straight away, you're ready to start using MDX files in your project. You can start by creating a basic hello world MDX file, and inside it, you can put some hello Vue, some Markdown component to Markdown text inside it.

[3:11] In your project root inside your main.js file, you can Vue import your helloworld.mdx file as a Vue component, and you can provide it inside your root instances render function as the root component. This allows us to treat MDX files as Vue components, which is cool and which I will also show us a little bit later on. I'm going to do a live demo.

[3:41] Another cool feature that comes out of the box with MDX is the MDXProvider. What it allows us to do is to map HTML elements that are being passed from our Markdown to actual Vue components that we can define at build time. That's what the mdx-js/vue-loader is doing.

[4:00] With the MDXProvider, we can provide it an object of components that we want to map, and we can replace them. I'll show us how that works in a live demo in a moment. I know what you're thinking. You're probably thinking, "But Jonas, does this work? Is it that simple?"

[4:18] I'm here to give us a very fat thumbs up and say, yes, it is. Let's see it in action. Let's see it work right now. To get started, we can create a new Vue project. I'm going to do that using the Vue CLI because it's the simplest way to get started, so I'm going to do vue create mdxonvue.

[4:52] I'm going to go ahead and manually select the features that I want. I'd like to use Babel. I'd like to use a Linter, blah, blah blah. This is for a barebone setup, that's all that I need. Yeah, I need ESLint. I'll just use the standard config. Yeah, Lint on save. I'll do the dedicated config files, and I do not want this to be a preset. Awesome.

[5:23] After your vue project has been scaffolded out, now going to CD into that directory. I'm going to open it up in VS Code. I already had it open, this directory inside here. All right. That's perfect. Great.

[5:40] What I will do now is I want to start the server just to make sure that it's actually working. It's actually running. It's now starting the development server. Great. Local host 8080. Cool. There it is. We now have a working vue application. That's really awesome. Cool.

[6:17] The next thing that we want to do is in order for us to start writing the actual MDX components, we need to include our mdx vue-loader inside our project. In order to do that, we run yarn ad mdx vue, mdx js vue-loader. Great.

[6:37] After installing our loader, now we need to create a webpack, extend our project's webpack config so we can actually process the MDX files. Since I'm using a vue CLI project, I want to create a vue.config.js file here. Here, module.exports and then I know I'm going to do configure webpack.

[7:12] Then I'm going to go to the mdx js vue-loader documentation just to be sure. I'll now include the module option. Great. Now, finally, we have finally installed mdx vue-loader. Our vue project is now aware that we would like to process all MDX files using the mdx vue-loader. We can now start a dev server. Great.

[8:25] Our development server is now started and a local host 8080. Everything's running. There's no problem there. Now, let's start creating our MDX components. I want to start by creating a helloworld@mdx to MDX file Hello World, their MDX file inside the helloworld@mdx file. I would like to create an H1.

[8:45] I would say this is hello vue mdx and vue mdx conf. Awesome. I will also then create...I'll write a section in here as always. I'd like to add a section with a background color of tomato. We all love the color tomato. I will also give it a color of white, the text color of white.

[9:21] Perfect. We have a nice section. They can now say, "I am a happy JSX section in MDX." Awesome. Maybe I should give it a padding as well of maybe about two rems. Awesome. Let's also add a black quoting here. Let's give this black quote here toast.

[9:54] I recently learned this and I like it. I'll find me some bread. That's not bread. That's not a bread emoji, but it will suffice. Cool. All right. Now, in our main JS file -- I might have opened something I should not open -- we would now like to import our helloworld.mdx file as a vue component.

[10:30] I'll say Hello World from helloworld.mdx. We are good to go. Perfect. With any luck, our vue application should now render our JSX. That's amazing, right? That's really amazing. There we have our yeah toast, that's our block quote there. That's our header.

[11:03] That's our heading element. Now, we have here the section with the tomato, which is really cool. Now, we have a really awesome feature, that MDX provides is the element mapping. Now, let's say I'm writing my documentation site.

[11:20] I would like to turn all block quotes into a large component or something else that I would like to use. I could replace this with an element from another component library or something else that I could develop locally.

[11:39] In my case, I like Chakra UI. I'm going to go ahead and install Chakra UI so I can import the alert component and use it to replace this using the MDX provider component. To do that, I'm going to do vue add Chakra UI. Great.

[12:05] Now, Chakra UI has now been installed in our project. I can now start by importing a few components from Chakra UI, as well as the Vue.js plugin. I want to start by importing the Chakra and the C theme provider. I'll say vue.use chakra.

[12:32] In order to make this a little bit more readable, what I will do is I will use JSX so that it's a lot clearer here. For this, I would like to use the theme provider. Inside the theme provider, I would like to include our component, our Hello World component.

[13:05] With any luck, our application should still run. We start our dev server. Great. Our project is now running again as normal. In order for us to start mapping these HTML elements to components that we would like to replace, we need to import the MDX provider from mdx js vue.

[13:33] We can see how that works from the mdx js vue package documentation on GitHub. Here from the documentation, I'm just going to copy this code. We import the MDXProvider component from @mdx-js/vue. We then wrap our application inside the MDXProvider. Great.

[14:00] I'm just going to come up here and I will then wrap the rest of all of this inside the MDXProvider component. Awesome. Now, let's define our component map. Let's create a file. I'm going to create a file called mdx-components.js. Inside the mdx-components.js, I'm going to export default an object.

[14:40] Inside this object, I would like to replace all blockquotes with a component from say, it can be a component that you've written yourself or it can also be a component from a library that you're using. In my case, I would like to use a component from Chakra UI, which is why I installed it. I don't have to rewrite everything again.

[15:09] In this case, I'd like to use the alert component from Chakra UI. I'll import it from @chakra-ui/vue. There we go. The next thing we want to put inside the alert is the default slot content. I'll say {this.$slots.default}. I would also like to include in here, the props. I'd like to spread the props in there.

[15:49] We need to return this. Great, and I would like to maybe make all toast of a status="warning" and I would like to give them a variant="left-accent". Amazing. If we go back to our main.js, I'm not going to import our components. I'll call this MDXComponents from './mdx-components' directory.

[16:32] Hopefully this is...Yeah, it's the right path. The MDXProvider requires a prop called components, as we can see here in the documentation. I'll give it the objects that we'd like to replace. Here I'd like to say components and the value is these MDXComponents.

[16:56] With any luck, our blockquote should have been replaced with the alert from Chakra UI. Looks like there's an error. One of the challenges we encounter with live coding. Just to be sure, I'm going to check this to make sure that everything is working.

[17:38] Yes, here's a typo. It's blockquote not blockquotes. Great, that's brilliant. That was funny, but everything should work now. Hooray. Now our toast is working just fine. That's all that it takes for us to do that. This could work for anything. You could replace your headers. You could replace code blocks. You could replace anything.

[18:01] What's amazing is that you keep this beautiful, simple, and readable Markdown syntax that you've always loved. That's the beauty that MDX gives us out of the box. Going back to my talk, at the end of my demo now. What about Nuxt.js? This capability also comes out of the box with Nuxt.js.

[18:27] In order to use it, you can install the @nuxtjs/mdx module and add it to your buildModules option inside your Nuxt configuration file, and you'll be good to go. You can also learn more from the documentation at mdxnuxtjs.org.

[18:43] With that, I'd like to say thank you to everybody, for listening to me and for watching me throughout the demos as well. I hope that you can enjoy using MDX in your Vue projects. Ciao.