sandros94 / nuxt-markdown-render

A Nuxt wrapper for the popular markdown-it.
https://www.npmjs.com/package/nuxt-markdown-render
MIT License
7 stars 1 forks source link

How to add markdown-it plugins #1

Closed lnbiuc closed 9 months ago

lnbiuc commented 9 months ago

I attempted to add the Shikiji code highlighting plugin, but encountered a failure as the content is not rendering on the page. Below is my usage method:

import Shikiji from 'markdown-it-shikiji'

export default defineNuxtConfig({
  modules: [
    // others
    'nuxt-markdown-render',
  ],

  nuxtMarkdownRender: {
    as: 'article',
    componentName: 'NotNuxtMarkdown',
    options: {
      html: true,
    },
    plugins: ['pluginMdc', Shikiji({
      themes: {
        light: 'vitesse-light',
        dark: 'vitesse-dark',
      },
    })],
    global: true,
  },
const md = '#hello world'
<NuxtMarkdown class="prose" :source="md" />

Could you please provide guidance on the correct usage or any additional steps needed to successfully add the Shikiji code highlighting plugin to my project? Thank you for your assistance!

sandros94 commented 9 months ago

I noticed that some plugins aren't correctly working when added with additional configs.

This is something I've planned to debug during the upcoming week (currently flying back home), I'll update once I'm up with something.

sandros94 commented 9 months ago

Btw: if you change componentName in your nuxt.config.ts you have to use that name in your nuxt pages/layouts/components:

export default defineNuxtConfig({
  modules: [
    // others
    'nuxt-markdown-render',
  ],

  nuxtMarkdownRender: {
    componentName: 'NotNuxtMarkdown'
    // other nuxt-mardown-render configs
  }
})
<script setup>
const md = `# hello world`
</script>

<template>
  <NotNuxtMarkdown class="prose" :source="md" />
</template>
lnbiuc commented 9 months ago

I apologize; this is a basic mistake. I modified the code like this, but it still doesn't work properly. The console is outputting an error.

import Shikiji from 'markdown-it-shikiji'
import { appDescription } from './constants/index'

export default defineNuxtConfig({
  modules: [
    'nuxt-markdown-render',
  ],
  nuxtMarkdownRender: {
    plugins: ['pluginMdc', Shikiji],
  },
<NuxtMarkdown class="prose" :source="md" />
image
sandros94 commented 9 months ago

I apologize; this is a basic mistake. I modified the code like this, but it still doesn't work properly. The console is outputting an error.

[...]

image

No problem! And thanks, now I might know what the problem is.

Once I'm home (in a couple of days max) I'll work on it, either by implementing a fix or a workaround I already had in mind.

sandros94 commented 9 months ago

@lnbiuc I forgot that I already implemented the workaround for such cases.

The issue is that some plugins are promises that needs to be resolved before being used. Until I handle them properly a simple workaround would be not to use those plugins inside nuxt.config.ts but instead create your own custom component that resolve those promises and adds them, for example create a ~/components/MyMarkdown.vue:

<template>
  <NuxtMarkdown
    :source="source"
    :options="{ html: true }"
    :plugins="[configuredShiki]"
  />
</template>

<script setup>
import shiki from '@shikijs/markdown-it'

const configuredShiki = await shiki({
  themes: {
    light: 'vitesse-light',
    dark: 'vitesse-dark'
  }
})

const props = defineProps({
  source: {
    type: String,
    required: true,
  },
})
</script>

And then use it in your pages/layouts/components:

<template>
  <MyMarkdown :source="md" />
</template>

<script setup>
const md = `
# My Markdown
`
</script>
lnbiuc commented 9 months ago

Thank you very much for taking the time to help me resolve the issue. Through your assistance, the problem has been perfectly resolved. I will now close this issue.

sandros94 commented 9 months ago

I'm replying here just for backlogging this.

I completely forgot about runtimeConfig serialization, this means that we cannot pass plugins from nuxt.config.ts at all, thus making the workaround the only option available. I'll both remove the plugin option from the runtimeConfig as well as adding a dedicated section on how to correctly handle the use of plugins.

lnbiuc commented 9 months ago

@Sandros94 I have upgraded nuxt-markdown-render to version 1.2. I encountered a problem when I tried to use another markdown-it plugin. I couldn't configure the plugin correctly. Here is my code, and I intend to use markdown-it-anchor to generate a table of contents.

Directly using the plugin, the plugin can work properly, but I am unable to add configurations.

<script setup lang="ts">
import shikiji from 'markdown-it-shikiji'
import anchor from 'markdown-it-anchor'

const props = defineProps({
  source: {
    type: String,
    required: true,
  },
})

const { rendered: NuxtMarkdown } = useNuxtMarkdown(props.source, {
  plugins: [
    await shikiji({
      themes: {
        dark: 'github-dark',
        light: 'github-light',
      },
    }),
    anchor,
  ],
})
</script>

<template>
  <NuxtMarkdown />
</template>

In order to configure the anchor plugin, I modified the code.

const { rendered: NuxtMarkdown } = useNuxtMarkdown(props.source, {
  plugins: [
    await shikiji({
      themes: {
        dark: 'github-dark',
        light: 'github-light',
      },
    }),
    anchor({
      level: 2,
    }),
  ],
})

However, I noticed that the first parameter of anchor() is MarkdownIt, so I modified the code to

image

<script setup lang="ts">
import shikiji from 'markdown-it-shikiji'
import anchor from 'markdown-it-anchor'
import md from 'markdown-it'

const props = defineProps({
  source: {
    type: String,
    required: true,
  },
})

const { rendered: NuxtMarkdown } = useNuxtMarkdown(props.source, {
  plugins: [
    await shikiji({
      themes: {
        dark: 'github-dark',
        light: 'github-light',
      },
    }),
    anchor(md, {
      level: 2,
    }),
  ],
})
</script>

<template>
  <div class="violet-prose">
    <NuxtMarkdown />
  </div>
</template>

but, this does not work properly.

image

If possible, could you give an example of how to correctly configure the plugin?

sandros94 commented 9 months ago

indeed, since I was mainly learning things from vue-markdown-render I copied a limitation they have too.

As soon I'm able to I'll fix the types that prevent this, thanks for reopening this

sandros94 commented 9 months ago

Ok, to fix this a number of other type issue raised while trying to build a new version, so I changed approach and decided to prevent most of them by only exporting the md constructor for more advanced use cases like this one.

With v1.3.0 this means that for those plugins that do require the use of PluginWithOptions<T> or PluginWithParams you could export the md constructor and customize it further as per markdown-it documentation. As you can see below you could also mix both approaches to load plugins in your ~components/NuxtMarkdown.vue:

<script setup lang="ts">
import shikiji from 'markdown-it-shikiji'
import anchor from 'markdown-it-anchor'

const props = defineProps({
  source: {
    type: String,
    required: true,
  },
})

const { rendered: NuxtMarkdown, md } = useNuxtMarkdown(props.source, {
  plugins: [
    await shikiji({
      themes: {
        dark: 'github-dark',
        light: 'github-light',
      },
    }),
  ],
})

md.value.use(anchor, { level: 2 })
</script>

<template>
  <NuxtMarkdown />
</template>

Feel free to reopen if you are having issues!