Rendering articles (ArticleContent)
A published article’s body is plain Markdown (article.markdown). ArticleContent renders it to sanitized HTML — GFM on, HTML sanitized — the same contract as @ghostwritr/react’s <ArticleContent>. It’s a render-function component, so it works anywhere Vue 3 runs: Nuxt, Vite SSR, and the browser (SPA).
The renderer is a separate, opt-in entry — it keeps the Markdown dependencies out of data-only consumers:
import { ArticleContent } from "@ghostwritr/vue/article-content";Pass the article’s markdown. With no class it renders a bare <div> wrapper; pass class to apply prose/Tailwind:
<script setup lang="ts">import { fetchArticle } from "@ghostwritr/vue";import { ArticleContent } from "@ghostwritr/vue/article-content";
const route = useRoute();const { data: article } = await useAsyncData(`gw-${route.params.slug}`, () => fetchArticle({ siteId: useRuntimeConfig().public.ghostwritrSiteId, slug: String(route.params.slug), }),);
if (!article.value) throw createError({ statusCode: 404, statusMessage: "Not found" });</script>
<template> <article v-if="article"> <h1>{{ article.title }}</h1> <ArticleContent :markdown="article.markdown" class="prose" /> </article></template>| Prop | Type | Default | Effect |
|---|---|---|---|
markdown | string | — (required) | The article’s Markdown body. |
class | string | undefined | Wrapper class on the <div> — apply prose/Tailwind here. |
remarkPlugins | PluggableList | undefined | Extra remark plugins, appended after the built-in remark-gfm. |
rehypePlugins | PluggableList | undefined | Extra rehype plugins, appended after the built-in rehype-sanitize. |
The built-ins always apply; your plugins run after them in the same pipeline.
<ArticleContent :markdown="article.markdown" class="prose" :remark-plugins="[/* appended after remark-gfm */]" :rehype-plugins="[/* appended after rehype-sanitize */]"/>The renderMarkdown helper
Section titled “The renderMarkdown helper”ArticleContent is a thin wrapper over renderMarkdown — the underlying synchronous Markdown → sanitized-HTML function. Reach for it directly when you need the HTML string itself (an RSS body, an email, a v-html binding you control):
import { renderMarkdown } from "@ghostwritr/vue/article-content";
const html = renderMarkdown(article.markdown, { remarkPlugins: [/* appended after remark-gfm */], rehypePlugins: [/* appended after rehype-sanitize */],});renderMarkdown(markdown, opts?) returns a string. It applies the same GFM + sanitize built-ins, and appends your remarkPlugins/rehypePlugins after them — identical to the component. See The article shape for what article.markdown contains.