Closed remino closed 2 years ago
I also would be interested in a solution as I right now use marked: https://github.com/LukaHarambasic/harambasic.de/blob/main/nuxt.config.js#L199
@LukaHarambasic offers a good work around, I would add that for consistency consider using https://github.com/micromark/micromark as the markdown parser/transformer. Nuxt content uses remark/micromark https://github.com/nuxt/content/blob/0b6a7be6f6287cde880b0d37c88e6461efa167ff/packages/content/package.json#L47 (and https://github.com/remarkjs/remark/releases/tag/13.0.0) to handle markdown. Using the same parser/transformer for all content can guarantee the content will render the same way no matter where/how it is loaded on the page.
Using the same parser/transformer for all content can guarantee the content will render the same way no matter where/how it is loaded on the page.
How can it be guaranteed? I'm not sure what magic does nuxt/content, okay we could look it up, but then we still need a way to get the same instance or an instance with the same options. Not relevant for my use case at all, just thinking out loud :)
npm/yarn modules are singletons.
if you don't install micromark at the top level, importing micromark
will get the same instance of micromark that nuxt/content is using.
You're right that nuxt applies some plugins on top, which may change the content https://github.com/nuxt/content/blob/939caf36c547a6b4af6e303c52ed5989a5dea2f0/packages/content/lib/utils.js#L14-L26
You could go a level higher in abstraction and use remark and rehype with these same plugins.
However, even without the plugins micromark
and marked
have some differences in how they parse markdown.
Both aim to implement the CommonMark standard, but marked
still has several unresolved CommonMark bugs (https://github.com/markedjs/marked/issues?q=is%3Aissue+is%3Aopen+commonmark+label%3A%22parser%3A+CommonMark%22) which can cause content to be parsed different.
Hello.
I would like to add my own interest to this question.
I too would like to display markdown just like nuxt/content does, but loaded from an api call. Obviously all i get from the api is a string - and not an object compatible with :
<NuxtContent :document="{ body: product.description }" />
This won't work because product.description
is a markdown string.
That means i would first need to use the same markdown parser that nuxt/content uses.
Is there a way for us to use the power of the NuxtContent component while having markdown not fetched from the content directory ? (i.e. from api calls).
I can't use a different rendered because i wish to include components inside my markdown just like nuxt/content supports.
thanks !
Sat Sri Akal ji
Isn't this solved here? https://content.nuxtjs.org/advanced#contentfilebeforeinsert
we can scroll down to 2nd example with json to have a look
but still string content would have to be inside files in 'content' folder
I too would be interested since the solution I am adopting is using @nuxtjs/markdownit'
module,
<div v-html="$md.render(blog.description)"></div>
However, this fails when the markdown string has a reference to an image that is stored within the blog content page directory
// markdown
...
<img src="images/img.png">
![blog image](images/img.png)
Hello :)
This should be solved by <Markdown />
component provided by @nuxt/content v2.
I am closing this issue as there is no plan to provide this feature for v1 versions.
Feel free to reopen with a PR if you manage to add this in v1.
You can find documentation about this feature for v2 here: https://content-v2.nuxtjs.org/guide/syntax/mdc#markdown-rendering
Hello :)
This should be solved by
<Markdown />
component provided by @nuxt/content v2.I am closing this issue as there is no plan to provide this feature for v1 versions.
Feel free to reopen with a PR if you manage to add this in v1.
You can find documentation about this feature for v2 here: https://content-v2.nuxtjs.org/guide/syntax/mdc#markdown-rendering
@Tahul
I don't understand how this would be solved using the <Markdown />
component, as it seems to act as a substitute to a slot. Could you provide an example of how to render a string using the compoment? Also, the link you posted is broken.
I'd like to push this aswell, since the answer does indeed not solve the problem stated in the issue. There was a way to import and use the Markdown Parser in the old version of nuxt content, but the new version does not export it anymore.
Hello :)
This should be solved by
<Markdown />
component provided by @nuxt/content v2.I am closing this issue as there is no plan to provide this feature for v1 versions.
Feel free to reopen with a PR if you manage to add this in v1.
You can find documentation about this feature for v2 here: https://content-v2.nuxtjs.org/guide/syntax/mdc#markdown-rendering
How can I solve it? I have a string as input, but I don't see how can I use it.
I also needed this, and figured it out by source diving 😇
Here is a minimal working example:
import markdownParser from "@nuxt/content/transformers/markdown";
const markdownString = '<your-markdown-string>'
const parsedMarkdown = await markdownParser.parse(
`<some-id>`,
markdownString
);
Your parsedMarkdown
AST can then be rendered like so:
<ContentRenderer :value="parsedMarkdown" />
I don't understand why this is closed. It's still not clear what is the official way of just rendering some markdown that does not come from a file.
Need to parse string content by same parser and plugin in some condition. It would be useful if repo export parser or component.
import markdownParser from "@nuxt/content/transformers/markdown"
Cannot import from "@nuxt/content/transformers/markdown" - module not found
import markdownParser from "@nuxt/content/transformers/markdown"
Cannot import from "@nuxt/content/transformers/markdown" - module not found
<template>
<ContentRenderer :value="parsedMarkdown" />
</template>
<script>
import { defineComponent } from 'vue'
import markdownParser from '@nuxt/content/transformers/markdown'
export default defineComponent({
components: {},
// define props
props: {
md: {
type: String,
default: '',
},
cid: {
type: String,
default: '<some-id>',
},
},
// init
async setup(props) {
return {
parsedMarkdown: await markdownParser.parse(props.cid, props.md),
}
},
})
</script>
^^ This worked for me
import markdownParser from "@nuxt/content/transformers/markdown"
Cannot import from "@nuxt/content/transformers/markdown" - module not found
Which version are you using? and @fr-eed too
import markdownParser from "@nuxt/content/transformers/markdown"
Cannot import from "@nuxt/content/transformers/markdown" - module not found
Which version are you using? and @fr-eed too
"@nuxt/content": "2.3.0"
I'm also having the same issue on v2.3.0
I'm using @nuxt/content
v2.4.3 and it still works. I noticed that you have to register @nuxt/content in your nuxt.config.ts modules section otherwise the parser does not work.
Steps I did to make it work:
Step one: Install @nuxt/content
pnpm i -D @nuxt/content
Step two: Add nuxt content to your modules section
export default defineNuxtConfig({
modules: [
...
'@nuxt/content',
],
...
Step three: Implement a component that uses the markdown parser
<script setup lang="ts">
// @ts-expect-error avoid lint error
import markdownParser from '@nuxt/content/transformers/markdown'
export interface MarkdownRenderProps {
md?: string
cid?: string
}
const props = withDefaults(defineProps<MarkdownRenderProps>(), { md: '', cid: '<some-id>' })
const parsedMarkdown = await markdownParser.parse(props.cid, props.md)
</script>
<template>
<ContentRenderer :value="parsedMarkdown" v-bind="$attrs" />
</template>
Same problem for me: @nuxt/content/transformers/markdown does not exist.
Same here: Same problem for me: @nuxt/content/transformers/markdown does not exist.
I'm wondering how to convert the parsedMardown
to html ? I need to pass this html to a tiptap editor.
Or how you can programmatically use ContentRender
to get the html output ?
highlight not working.
Same here: Same problem for me: @nuxt/content/transformers/markdown does not exist.
This version: "@nuxt/content": "^2.6.0"
import markdownParser from "@nuxt/content/transformers/markdown";
const markdownString = '<your-markdown-string>'
const parsedMarkdown = await markdownParser.parse(
`<some-id>`,
markdownString
);
Error message: Cannot find module '@nuxt/content/transformers/markdown' or its corresponding type declarations.ts(2307)
Maybe this helps to get thinks started
Thanks @piscis for your demo!
Personally, I tried this and it works perfectly! But this is not I am looking for exactly.
I don't want to render the output in the page. I want the HTML output of the rendered markdown to pass this HTML to some libraries like tiptap editor.
markdownParser.parse()
under the hood use remark to convert markdown to mdast
(Markdown Abstract Syntax Tree), and a custom nuxt-content rehype plugin that convert this mdast
to an hast
(HTML Abstract Synt...).
This hast
is used by the ContentRendererMarkdown
component to output the html using Vue VNode.
Actually, there's no way to get the HTML output on the process. We should build our own parser with rehypeStringify
for example.
In our CodeSandbox Demo line app.vue:12
, the variable parsedMarkdown
doesn't contain the HTML, but the hast
.
Thanks @piscis for your demo.
Would it be possible to use this setup for in place rendering as well? I would like to use something a textarea field for rendering Md in realtime.
do you guys know how to use nice syntax highlighting when doing this?
maybe the answer is here: https://github.com/nuxt/content/issues/1490
It worked for me https://codesandbox.io/p/github/piscis/nuxt3-markdown-renderer-codingsandbox/main?file=/app.vue:12,1-12,74 with version 2.7.0
I'm using
@nuxt/content
v2.4.3 and it still works. I noticed that you have to register @nuxt/content in your nuxt.config.ts modules section otherwise the parser does not work.Steps I did to make it work:
Step one: Install @nuxt/content
pnpm i -D @nuxt/content
Step two: Add nuxt content to your modules section
export default defineNuxtConfig({ modules: [ ... '@nuxt/content', ], ...
Step three: Implement a component that uses the markdown parser
<script setup lang="ts"> // @ts-expect-error avoid lint error import markdownParser from '@nuxt/content/transformers/markdown' export interface MarkdownRenderProps { md?: string cid?: string } const props = withDefaults(defineProps<MarkdownRenderProps>(), { md: '', cid: '<some-id>' }) const parsedMarkdown = await markdownParser.parse(props.cid, props.md) </script> <template> <ContentRenderer :value="parsedMarkdown" v-bind="$attrs" /> </template>
HI, is there a way to unwrap the p
tag before rendering the parsed content?
I'm trying as following but it's doesn't work..
const { unwrap } = useUnwrap()
const parsedMarkdown = await markdownParser
.parse(`<some-id>`, props.md)
.then((vnode: any) => unwrap(vnode, ['p']))
where am i wrong? Thanks
It's now (since nuxt/content v2.8.1 / @nuxtjs/mdc v0.1.3) possible to use @nuxtjs/mdc instead, see details here; https://github.com/nuxt-modules/mdc, essentially you'll do
import { parseMarkdown } from '@nuxtjs/mdc/runtime'
async function main(mdc: string) {
const ast = await parseMarkdown(mdc)
// Do your magic with parsed AST tree
return ast
}
It's now (since nuxt/content v2.8.1 / @nuxtjs/mdc v0.1.3) possible to use @nuxtjs/mdc instead, see details here; https://github.com/nuxt-modules/mdc, essentially you'll do
import { parseMarkdown } from '@nuxtjs/mdc/runtime' async function main(mdc: string) { const ast = await parseMarkdown(mdc) // Do your magic with parsed AST tree return ast }
Hi @tveimo ! Cool, in my case I already switched to vue-showdown
creating a custom component.
Are there any significant differences with @nuxtjs/mdc
?
With @nuxt/content/transformers/markdown
, how does one use the remark/rehype plugins as defined in the nuxt.config
file?
It's now (since nuxt/content v2.8.1 / @nuxtjs/mdc v0.1.3) possible to use @nuxtjs/mdc instead, see details here; https://github.com/nuxt-modules/mdc, essentially you'll do
import { parseMarkdown } from '@nuxtjs/mdc/runtime' async function main(mdc: string) { const ast = await parseMarkdown(mdc) // Do your magic with parsed AST tree return ast }
With v0.2.8 of @nuxtjs/mdc it is even simpler. Just use their <MDC />
component
<script setup lang="ts">
const exampleMarkdownString = `##Hello MDC`
</script>
<template>
<MDC :value="exampleMarkdownString" tag="article" />
</template>
The following code can run normally, but there are warnings. How should I handle this?
This works fine, but it seems like line breaks are not properly parsed. One line break = Ignored, 2 line break only works but for the first one
The following code can run normally, but there are warnings. How should I handle this?
I'm having the same issue:
Is there a way, like a Nuxt plugin or Vue component, @nuxt/content provides to let you reuse its instance of remark to render a single Markdown string?