8000 GitHub - runyasak/unplugin-vue-markdown at feat/frontmatter-props
[go: up one dir, main page]

Skip to content

runyasak/unplugin-vue-markdown

 
 

Repository files navigation

unplugin-vue-markdown

NPM version

Compile Markdown to Vue component.

  • 📚 Use Markdown as Vue components.
  • 💚 Use Vue components in Markdown.
  • 🔌 Supports Vite, Webpack, Vue CLI and more, powered by unplugin.
  • ⚡️ The same transformation as VitePress.

Install

npm i unplugin-vue-markdown
Vite
// vite.config.ts
import Vue from '@vitejs/plugin-vue'
import Markdown from 'unplugin-vue-markdown/vite'

export default defineConfig({
  plugins: [
    Vue({
      include: [/\.vue$/, /\.md$/], // <-- allows Vue to compile Markdown files
    }),
    Markdown({ /* options */ }),
  ],
})

Example: examples/vite


Webpack
// webpack.config.js
const Markdown = require('unplugin-vue-markdown/webpack')
const { VueLoaderPlugin } = require('vue-loader')

module.exports = {
  /* ... */
  module: {
    rules: [
      // ... other rules
      {
        test: /\.(vue|md)$/,
        loader: 'vue-loader'
      }
    ]
  },
  plugins: [
    new VueLoaderPlugin(),
    Markdown({ /* options */ })
  ]
}

Vue CLI
// vue.config.js
const Markdown = require('unplugin-vue-markdown/webpack')

module.exports = {
  parallel: false, // Disable thread-loader which will cause errors, we are still investigating the root cause
  chainWebpack: (config) => {
    config.module
      .rule('vue')
      .test(/\.(vue|md)$/) // <-- allows Vue to compile Markdown files

    config
      .plugin('markdown')
      .use(Markdown({
        markdownItUses: [
          prism,
        ],
      }))
  },
}

Example: examples/vue-cli


Import Markdown as Vue components

<template>
  <HelloWorld />
</template>

<script>
import HelloWorld from './README.md'

export default {
  components: {
    HelloWorld,
  },
}
</script>

Use Vue Components inside Markdown

You can even use Vue components inside your markdown, for example

<Counter :init='5'/>

Note you can either register the components globally, or use the <script setup> tag to register them locally.

import { createApp } from 'vue'
import App from './App.vue'
import Counter from './Counter.vue'

const app = createApp(App)

// register global
app.component('Counter', Counter) // <--

app.mount()
<script setup>
import { Counter } from './Counter.vue'
</script>

<Counter :init='5'/>

Or you can use unplugin-vue-components for auto components registration.

Frontmatter

Frontmatter will be parsed and inject into Vue's instance data frontmatter field.

For example:

---
name: My Cool App
description: This is My Cool App
---

# Hello World

This is {{frontmatter.name}}

Will be rendered as

<h1>Hello World</h1>
<p>{{frontmatter.description}}</p>

You can override existing frontmatter values by passing the :frontmatter-merge prop to the component.

<template>
  <HelloWorld :frontmatter-merge="{ name: 'My Awesome App' }" />
</template>

<script>
import HelloWorld from './README.md'

export default {
  components: {
    HelloWorld,
  },
}
</script>

Alternatively, you can replace all frontmatter values using the :frontmatter-replace prop. Any remaining frontmatter properties will not render and will be undefined.

<template>
  <HelloWorld :frontmatter-replace="{ name: 'My Super App' }" />
</template>

<script>
import HelloWorld from './README.md'

export default {
  components: {
    HelloWorld,
  },
}
</script>

For example, if you use :frontmatter-replace, the description property will not be shown on the screen.

Use either :frontmatter-merge or :frontmatter-replace for a component. If both props are provided, only :frontmatter-replace will take effect.

It will also be passed to the wrapper component's props if you have set wrapperComponent option.

Document head and meta

To manage document head and meta, you would need to install @unhead/vue and do some setup.

npm i @unhead/vue
// vite.config.js
import Vue from '@vitejs/plugin-vue'
import Markdown from 'unplugin-vue-markdown/vite'

export default {
  plugins: [
    Vue({
      include: [/\.vue$/, /\.md$/],
    }),
    Markdown({
      headEnabled: true // <--
    })
  ]
}
// src/main.js
import { createHead } from '@unhead/vue' // <--
import { createApp } from 'vue'

const app = createApp(App)

const head = createHead() // <--
app.use(head) // <--

Then you can use frontmatter to control the head. For example:

---
title: My Cool App
meta:
  - name: description
    content: Hello World
---

For more options available, please refer to @unhead/vue's docs.

Options

unplugin-vue-markdown uses markdown-it under the hood, see markdown-it's docs for more details

// vite.config.js
import MarkdownItAnchor from 'markdown-it-anchor'
import MarkdownItPrism from 'markdown-it-prism'
import Markdown from 'unplugin-vue-markdown/vite'

export default {
  plugins: [
    Markdown({
      // default options passed to markdown-it
      // see: https://markdown-it.github.io/markdown-it/
      markdownItOptions: {
        html: true,
        linkify: true,
        typographer: true,
      },
      // A function providing the Markdown It instance gets the ability to apply custom settings/plugins
      markdownItSetup(md) {
        // for example
        md.use(MarkdownItAnchor)
        md.use(MarkdownItPrism)
      },
      // Class names for the wrapper div
      wrapperClasses: 'markdown-body'
    })
  ],
}

See the tsdoc for more advanced options

Example

See the /examples.

Or the pre-configured Markdown template Vitesse.

Integrations

import Vue from '@vitejs/plugin-vue'
import Markdown from 'unplugin-vue-markdown/vite'
import Pages from 'vite-plugin-pages'

export default {
  plugins: [
    Vue({
      include: [/\.vue$/, /\.md$/],
    }),
    Pages({
      extensions: ['vue', 'md'],
    }),
    Markdown()
  ],
}

Put your markdown under ./src/pages/xx.md, then you can access the page via route /xx.

unplugin-vue-components allows you to do on-demand components auto-importing without worrying about registration.

import Vue from '@vitejs/plugin-vue'
import Components from 'unplugin-vue-components/vite'
import Markdown from 'unplugin-vue-markdown/vite'

export default {
  plugins: [
    Vue({
      include: [/\.vue$/, /\.md$/],
    }),
    Markdown(),
    // should be placed after `Markdown()`
    Components({
      // allow auto load markdown components under `./src/components/`
      extensions: ['vue', 'md'],

      // allow auto import and register components used in markdown
      include: [/\.vue$/, /\.vue\?vue/, /\.md$/],
    })
  ],
}

Components under ./src/components can be directly used in markdown components, and markdown components can also be put under ./src/components to be auto imported.

TypeScript Shim

declare module '*.vue' {
  import type { ComponentOptions } from 'vue'

  const Component: ComponentOptions
  export default Component
}

declare module '*.md' {
  import type { ComponentOptions } from 'vue'

  const Component: ComponentOptions
  export default Component
}

License

MIT License © 2020-PRESENT Anthony Fu

About

Compile Markdown to Vue component

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages

  • TypeScript 99.2%
  • JavaScript 0.8%
0