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
| Prop | Type | Default | Description |
|---|---|---|---|
posts | BlogPost[] | — | Array of posts to display |
title | string | "Latest posts" | Section heading. Pass empty string to hide. |
routePrefix | string | "/blog" | URL prefix for post links (e.g., /blog/my-post) |
linkComponent | React.ComponentType | <a> | Link component (use Next.js Link for client navigation) |
className | string | "ba-listing" | CSS class on the wrapper <section> |
renderCard | (post, href) => ReactNode | — | Custom card renderer (overrides default card) |
Custom Link Component
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-postCustom 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
| Prop | Type | Default | Description |
|---|---|---|---|
post | BlogPost | — | The post to render |
showTitle | boolean | true | Show the post title as an <h1> |
showDate | boolean | true | Show publication date |
className | string | "ba-post" | CSS class on the wrapper <article> |
renderContent | (content: string) => ReactNode | — | Custom 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
| Prop | Type | Default | Description |
|---|---|---|---|
source | string | null | — | Markdown string to render. Returns null if empty. |
className | string | "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 (
# H1through###### H6) - Renders bold, italic, and
inline code - Converts links
[text](url)withtarget="_blank"andrel="noreferrer" - Converts images
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.
On this page
- `<BlogPostList>`
- Basic Usage
- Props
- Custom Link Component
- Custom Route Prefix
- Custom Card Rendering
- Default HTML Structure
- `<BlogPost>`
- Basic Usage
- Props
- Hiding Title and Date
- Custom Content Rendering
- Default HTML Structure
- `<Markdown>`
- Basic Usage
- Props
- Custom Class
- How It Works
- Standalone Markdown Renderer
- Next Steps