<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 pnpm add @ghostwritr/react yarn add @ghostwritr/react bun add @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> );}| prop | type | default |
|---|---|---|
markdown | string | — (required) |
components | react-markdown Components | element defaults |
remarkPlugins | extra remark plugins | appended after GFM |
rehypePlugins | extra rehype plugins | appended after sanitize |
className | string | no wrapper element |
markdown
Section titled “markdown”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.
components
Section titled “components”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} /> }}/>remarkPlugins / rehypePlugins
Section titled “remarkPlugins / rehypePlugins”Extra plugins, appended after the built-ins. They run after remark-gfm and rehype-sanitize respectively. See the ordering and sanitize caveat.
className
Section titled “className”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.
What’s on by default
Section titled “What’s on by default”These two behaviors are the built-ins. Your plugins extend them; they never replace them.
What to reach for next
Section titled “What to reach for next”- Customize the output — highlighter, links, images, and
prosestyling. See Customizing rendering. - Render on the server — drop it into an RSC tree with zero client JS. See Server Components.
- Get the markdown — fetch an Article from the content feed.