Docs
React Components
Documentation

React Components

Pre-built React components for rendering blog posts and listings.

React Components

The @autoblogwriter/sdk/react entry point provides ready-to-use React components for rendering blog content. All components work with both server and client components.

import { BlogPost, BlogPostList, Markdown } from "@autoblogwriter/sdk/react";

<BlogPostList>

Renders a list of blog post cards with titles, dates, and excerpts.

Basic Usage

import Link from "next/link";
import { fetchBlogPosts } from "@autoblogwriter/sdk/next";
import { BlogPostList } from "@autoblogwriter/sdk/react";
 
export default async function BlogPage() {
  const { posts } = await fetchBlogPosts();
  return <BlogPostList posts={posts} linkComponent={Link} />;
}

Props

PropTypeDefaultDescription
postsBlogPost[]Array of posts to display
titlestring"Latest posts"Section heading. Pass empty string to hide.
routePrefixstring"/blog"URL prefix for post links (e.g., /blog/my-post)
linkComponentReact.ComponentType<a>Link component (use Next.js Link for client navigation)
classNamestring"ba-listing"CSS class on the wrapper <section>
renderCard(post, href) => ReactNodeCustom card renderer (overrides default card)

Pass Next.js Link for client-side navigation:

import Link from "next/link";
<BlogPostList posts={posts} linkComponent={Link} />

Custom Route Prefix

<BlogPostList posts={posts} routePrefix="/articles" />
// Links will be /articles/my-post instead of /blog/my-post

Custom Card Rendering

Override the default card layout with renderCard:

<BlogPostList
  posts={posts}
  linkComponent={Link}
  renderCard={(post, href) => (
    <Link href={href} className="custom-card">
      <h3>{post.title}</h3>
      <p>{post.excerpt}</p>
      {post.metadata?.readingTimeMinutes && (
        <span>{post.metadata.readingTimeMinutes} min read</span>
      )}
    </Link>
  )}
/>

Default HTML Structure

<section class="ba-listing">
  <h1 class="ba-listing-title">Latest posts</h1>
  <div class="ba-posts">
    <article class="ba-post-card">
      <h2 class="ba-post-card-title">
        <a href="/blog/my-post" class="ba-post-card-link">My Post</a>
      </h2>
      <p class="ba-post-card-meta">
        <time datetime="2025-01-15T10:00:00.000Z">January 15, 2025</time>
      </p>
      <div class="ba-post-card-excerpt">
        <!-- Rendered excerpt markdown -->
      </div>
    </article>
    <!-- More cards... -->
  </div>
</section>

<BlogPost>

Renders a full blog post article with title, date, reading time, and markdown content.

Basic Usage

import { fetchBlogPost } from "@autoblogwriter/sdk/next";
import { BlogPost } from "@autoblogwriter/sdk/react";
 
export default async function PostPage({ params }: Props) {
  const { slug } = await params;
  const post = await fetchBlogPost(slug);
  return <BlogPost post={post} />;
}

Props

PropTypeDefaultDescription
postBlogPostThe post to render
showTitlebooleantrueShow the post title as an <h1>
showDatebooleantrueShow publication date
classNamestring"ba-post"CSS class on the wrapper <article>
renderContent(content: string) => ReactNodeCustom content renderer (overrides default Markdown)

Hiding Title and Date

<BlogPost post={post} showTitle={false} showDate={false} />

Custom Content Rendering

Replace the built-in markdown renderer with your own (e.g., for syntax highlighting with react-markdown or next-mdx-remote):

import ReactMarkdown from "react-markdown";
 
<BlogPost
  post={post}
  renderContent={(content) => (
    <ReactMarkdown className="prose">{content}</ReactMarkdown>
  )}
/>

Default HTML Structure

<article class="ba-post">
  <h1 class="ba-post-title">My Post Title</h1>
  <p class="ba-post-meta">
    <time datetime="2025-01-15T10:00:00.000Z">January 15, 2025</time>
    <span class="ba-post-meta-sep"> · </span>
    <span class="ba-post-reading-time">5 min read</span>
  </p>
  <div class="ba-markdown">
    <!-- Rendered markdown HTML -->
  </div>
</article>

<Markdown>

Renders a markdown string to HTML using the built-in renderer.

Basic Usage

import { Markdown } from "@autoblogwriter/sdk/react";
 
<Markdown source="# Hello World\n\nThis is **bold** text." />

Props

PropTypeDefaultDescription
sourcestring | nullMarkdown string to render. Returns null if empty.
classNamestring"ba-markdown"CSS class on the wrapper <div>

Custom Class

<Markdown source={post.content} className="prose dark:prose-invert" />

How It Works

The <Markdown> component uses the built-in renderMarkdownToHtml() function which:

  • Converts headings (# H1 through ###### H6)
  • Renders bold, italic, and inline code
  • Converts links [text](url) with target="_blank" and rel="noreferrer"
  • Converts images ![alt](src) with proper attributes
  • Wraps code blocks in <pre><code>
  • Escapes HTML to prevent XSS attacks
  • Has zero dependencies

If you need more advanced markdown features (tables, footnotes, syntax highlighting), use renderContent on <BlogPost> with a library like react-markdown.

Standalone Markdown Renderer

The renderMarkdownToHtml() function is also available directly:

import { renderMarkdownToHtml } from "@autoblogwriter/sdk";
 
const html = renderMarkdownToHtml("# Hello\n\nWorld");
// "<h1>Hello</h1>\n<p>World</p>"

Next Steps

  • Styling — Customize the look of these components with CSS.
  • Next.js Helpers — Fetch data for the components.