Getting Started
This guide walks you from zero to a fully working content site. By the end, you'll have a content list page and individual content pages — all statically generated for maximum performance.
1. Install the Packages
You need two packages: core for reading your markdown files, and react for rendering them.
npm install @haroonwaves/blog-kit-core @haroonwaves/blog-kit-react
# or
pnpm add @haroonwaves/blog-kit-core @haroonwaves/blog-kit-react
# or
yarn add @haroonwaves/blog-kit-core @haroonwaves/blog-kit-react
Note: The React package requires React 19+ as a peer dependency.
2. Import the Styles
Blog Kit ships two CSS files. Import them before your app's global CSS so the component styles load correctly:
// In your root layout or entry file (e.g., layout.tsx, App.tsx)
import '@haroonwaves/blog-kit-react/dist/index.css'; // Prism theme (code block styling)
import '@haroonwaves/blog-kit-react/dist/style.css'; // Component styles (Tailwind classes)
import './globals.css'; // Your app's CSS
Why this order matters: Blog Kit uses a
bk:namespace for all its utility classes (e.g.,bk:text-2xl), so library styles never clash with your app's Tailwind classes. Importing Blog Kit's CSS first lets your app's base typography serve as the foundation.
3. Write Your First Blog Post
Create a markdown file with frontmatter metadata. Blog Kit uses gray-matter to parse frontmatter and reading-time to calculate reading time automatically.
Project structure:
your-project/
├── content/
│ └── blog/
│ ├── hello-world.md
│ └── my-second-post.md
└── src/
└── app/
├── blog/
│ ├── page.tsx ← Content list page
│ └── [slug]/
│ └── page.tsx ← Content item page
└── layout.tsx
Example markdown file (content/blog/hello-world.md):
---
title: Hello World
description: My first post built with Blog Kit.
date: 2024-01-15
categories:
- Technology
- Web Development
---
# Hello World
Welcome to my blog! This is my first post built with Blog Kit.
Required frontmatter fields:
title(string): The content titledescription(string): A brief description/summarydate(string): Publication date (ISO format recommended: YYYY-MM-DD)
Optional frontmatter fields:
categories(string[]): Array of categories/tags for the content
4. Create the Configuration
Define your configuration once and reuse it across pages:
// lib/content.ts (or wherever you keep shared config)
import type { ContentConfig } from '@haroonwaves/blog-kit-core';
export const contentConfig: ContentConfig = {
contentDirectory: process.cwd(), // The project root
contentSubdirectory: 'content/blog', // Path to your markdown files
};
5. Build the Blog List Page
// app/blog/page.tsx
import { getAllContentMeta } from '@haroonwaves/blog-kit-core';
import { ContentList } from '@haroonwaves/blog-kit-react';
import Link from 'next/link';
import { contentConfig } from '@/lib/content';
export default function BlogPage() {
const blogsMeta = getAllContentMeta(contentConfig);
return (
<ContentList
metadata={blogsMeta}
title="Blogs"
description="Welcome to my blog built with Blog Kit."
basePath="/blog"
renderLink={(href, children) => <Link href={href}>{children}</Link>}
/>
);
}
That's it — ContentList renders a responsive list of cards with category badges, reading time, and
dates. No extra configuration needed.
6. Build the Blog Post Page
// app/blog/[slug]/page.tsx
import { getAllContentMeta, getContent } from '@haroonwaves/blog-kit-core';
import { ContentRenderer } from '@haroonwaves/blog-kit-react';
import { notFound } from 'next/navigation';
import { contentConfig } from '@/lib/content';
export function generateStaticParams() {
const blogsMeta = getAllContentMeta(contentConfig);
return blogsMeta.map((meta) => ({ slug: meta.slug }));
}
export default async function BlogPostPage({ params }: { params: Promise<{ slug: string }> }) {
const { slug } = await params;
const blog = getContent(slug, contentConfig);
if (!blog) notFound();
return (
<article>
<ContentRenderer body={blog.body} metadata={blog.metadata} />
</article>
);
}
ContentRenderer automatically handles markdown rendering with syntax highlighting, GFM support,
heading anchor links, and beautiful typography — all out of the box.
Next Steps
Your site is now fully functional! Here's what to explore next:
- Guides — Add search/filtering, dark mode, and customize component styling
- API Reference — Complete reference for all functions, components, hooks, and types