Loading .mdx (or other file extensions) as components in Nuxt - Image

Load .mdx(or other file extensions) as components in Nuxt.

Published on 2020-05-14

๐Ÿšจ This post is an unpolished thought

Today I learned that you can configure Nuxt to load different file extensions as both as pages and as components.

In order for this to work properly I needed to have Nuxt's builder load the files with extensions I wish to load. This is because, by default, Nuxt's builder will ignore any files that are not .vue files. This can be achieved by using a Nuxt module

In order for this to work properly you need to have the appropriate webpack loaders for the file extensions you wish to load.

In this example, I'll be importing .mdx files as routes under the pages directory. So that means I need to have a webpack loader installed for .mdx files.

This applies to any other file extension you wish to support. If you with to import Markdown (.md) files into your components, then you must have a .md file webpack loader installed as well.

๐Ÿ—‚pages
  ๐Ÿ“„index.vue
  ๐Ÿ“„test.mdx
  ๐Ÿ—‚foo
    ๐Ÿ“„contact.vue
    ๐Ÿ“„about.mdx
๐Ÿ“„nuxt.config.js

Using modules

Modules are like plugins for plugins in Nuxt. These can be used to extend Nuxt's functionality and add different integrations to your Nuxt application.

First we create a module file. We'll call this load-mdx-module.js.

// load-mdx-module.js

export default function (options = {}) {

  // Add 'mdx' to build extensions
  this.options.build.additionalExtensions = ['mdx']

  if (this.options.extensions) {

    // Add `mdx` to `extensions` option
    const extensions = this.options.extensions
    !extensions.includes('mdx') && extensions.push('mdx')

    // Add 'mdx' to `build.additionalExtensions`
    this.options.build.additionalExtensions = ['mdx']

    // Extend webpack config
    this.extendBuild((config) => {

      // Here we '.mdx' to webpack's `resolve.extensions` option.
      if (config.resolve.extensions) {
        config.resolve.extensions.push('.mdx')
      } else {
        config.resolve.extensions = ['.mdx']
      }

      // Use `@mdx-js/vue-loader` for `.mdx` files.
      config.module.rules.push({
        test: /\.mdx$/,
        use: [
          'babel-loader',
          '@mdx-js/vue-loader'
        ]
      })
    })
  }
}

Add module to Nuxt config

Add the path to the load-mdx-module.js file under the modules option in your nuxt.config.js

export default {
  // ...
  modules: [
    'path/to/load-mdx-module'
  ]
  // ...
}

Start server

yarn dev

You should be able to visit other routes with .mdx extension or import .mdx files in your Vue components.

Further reading