Build an AI-powered blog for your NextJS app
Learn how to Build an AI-powered blog for your NextJS app. Generate SEO optimized blogs daily fully automatically. Grow to rank #1 on search engines.Jul 6, 2025
Table of Contents
TL;DR
Want to add a blog to your Next.js app, but don’t want to write every post by hand? Here’s how I plugged in NextBlog to automate content, keep things SEO-friendly, and let the robots do the heavy lifting—so I can focus on shipping features, not writing articles.
Why I Automated My Blog
I love building products, but writing blog posts? Not so much. I wanted my app to have a blog (for SEO, for users, for the “we’re alive!” signal), but I didn’t want to spend hours writing or wrangling guest posts.
That’s when I found NextBlog. It’s a tool that uses AI to generate blog content, and it has a dead-simple API. I figured: why not let it handle the writing, and just wire it up to my Next.js app?
Here’s how I did it.
Step 1: Set Up NextJS and dependencies
Create your NextJs project if you haven't already.
npx create-next-app@latest
Install react-markdown. We’ll use this to render the markdown content from NextBlog
npm install react-markdown
Step 2: Set Up NextBlog
Nextblog is sick. You can use it for free to manage your blog and create unlimited posts.
You also have the option to automatically generate and publish blogs daily as well with AI.
Step 3: Add Your API Key to Next.js
In your Next.js project, add these to
.env.local
:NEXTBLOG_API_KEY=your_api_key_here
NEXTBLOG_PROJECT_ID=your_project_id_here
Restart your dev server so Next.js picks up the new env vars.
Step 4: Fetch and Render Blog Posts
// Blog List Page (/app/blog/page.js) import Link from 'next/link'; export const metadata = { title: 'My Website Blog', description: 'Latest posts and updates.', }; // Fetch all your blog posts async function getBlogPosts() { const apiKey = process.env.NEXTBLOG_API_KEY; const projectId = process.env.NEXTBLOG_PROJECT_ID; try { const response = await fetch(`https://nextblog.ai/api/blog/${projectId}`, { headers: { 'Authorization': `Bearer ${apiKey}` }, next: { revalidate: 3600 } }); if (!response.ok) throw new Error('Failed to fetch blog posts'); const data = await response.json(); return data.blogs; } catch (err) { console.error('Error fetching blog posts:', err); return []; } } // Render the blog posts export default async function BlogList() { const blogs = await getBlogPosts(); return ( <div> <h1>Blog</h1> {blogs.map(blog => ( <article key={blog.id}> <h2>{blog.title}</h2> <p>{blog.description}</p> {blog.cover_image_url && <img src={blog.cover_image_url} alt={blog.title} />} <Link href={`/blog/${blog.slug}`}>Read more</Link> </article> ))} </div> ); }
Step 5: Page for Single Blog Post
// Single Blog Post Page (app/blog/[slug]/page.js) import { notFound } from 'next/navigation'; import ReactMarkdown from 'react-markdown'; // Fetch the blog post based on the pathname (slug) async function getBlogPost(slug) { const apiKey = process.env.NEXTBLOG_API_KEY; const projectId = process.env.NEXTBLOG_PROJECT_ID; try { const response = await fetch(`https://nextblog.ai/api/blog/${projectId}/${slug}`, { headers: { 'Authorization': `Bearer ${apiKey}` }, next: { revalidate: 3600 } }); if (!response.ok) throw new Error('Failed to fetch blog post'); const data = await response.json(); return data.blog; } catch (err) { console.error('Error fetching blog post:', err); return null; } } // Generate SEO optimized metadata export async function generateMetadata({ params }) { const blog = await getBlogPost(params.slug); return { title: blog?.title || 'Blog Post', description: blog?.description || '', openGraph: { title: blog?.title, description: blog?.description, images: blog?.cover_image_url, }, }; } // Render the blog post export default async function BlogPost({ params }) { const blog = await getBlogPost(params.slug); if (!blog) notFound(); return ( <article> <h1>{blog.title}</h1> <div> <time>{new Date(blog.created_at).toLocaleDateString()}</time> </div> <ReactMarkdown>{blog.markdown}</ReactMarkdown> </article> ); }
Step 6: That’s It—Let the Robots Write
Now, whenever NextBlog generates a new post for your project, it’ll show up in your app automatically. No rebuilds, no copy-pasting, no “I’ll write that post tomorrow” guilt.
FAQ
Q: Is this good for SEO?
A: Yep. NextBlog’s posts are optimized for search engines, and you can tweak the project description to steer the AI.
Q: Can I edit posts?
A: You can sync with Notion and edit there, or just use the API to fetch whatever you want.
Q: Is it free?
A: There’s a free trial. After that, it’s paid—but honestly, it’s cheaper than hiring a writer.
Final Thoughts
I built this because I wanted to focus on shipping features, not writing blog posts. If you’re an indie hacker or solo dev, and you want a blog that updates itself, give NextBlog a try. It’s one less thing to worry about.
If you have questions or want to see more advanced stuff (like caching, custom templates, or analytics), let me know in the comments!
Happy shipping 🚀