Skip to content

<ArticleContent>

<ArticleContent> renders an article’s Markdown body to React elements. It is the one component in @ghostwritr/react, and it is framework-neutral — it works in any React renderer, including React Server Components with no "use client" boundary.

npm install @ghostwritr/react

It pairs with any fetcher that gives you an Article: @ghostwritr/next, @ghostwritr/react-router, or the bare @ghostwritr/feed core.

Pass the article’s markdown field. Render the title yourself — the feed strips the leading # title heading out of the body, so there is no duplicate <h1> on the page.

import { ArticleContent } from "@ghostwritr/react";
export function Article({ article }) {
return (
<article>
<h1>{article.title}</h1>
<ArticleContent markdown={article.markdown} className="prose" />
</article>
);
}
proptypedefault
markdownstring— (required)
componentsreact-markdown Componentselement defaults
remarkPluginsextra remark pluginsappended after GFM
rehypePluginsextra rehype pluginsappended after sanitize
classNamestringno wrapper element

The article body as a Markdown string. Ghost Writr emits Markdown, not MDX — there is no component evaluation, so an article can never execute code in your app.

An object that overrides how individual elements render, passed straight through to react-markdown. Use it for a syntax highlighter, a framework-aware link, or next/image. See Customizing rendering.

<ArticleContent
markdown={article.markdown}
components={{ img: (p) => <img loading="lazy" {...p} /> }}
/>

Extra plugins, appended after the built-ins. They run after remark-gfm and rehype-sanitize respectively. See the ordering and sanitize caveat.

When set, the output is wrapped in a single <div> carrying that class — the place to put prose / Tailwind Typography. Omit it for no wrapper element at all: the Markdown renders directly with no surrounding tag.

These two behaviors are the built-ins. Your plugins extend them; they never replace them.