Next.js Blog App

Build a modern blog with Next.js App Router

📝 What is a Next.js Blog App?

A Next.js blog app uses server-side rendering and static generation to create fast, SEO-friendly blogs. It combines React components with file-based routing for easy content management and optimal performance.


// app/page.tsx - Blog Homepage
export default function Home() {
  return (
    <main>
      <h1>My Blog</h1>
      <p>Welcome to my Next.js blog!</p>
    </main>
  )
}
                                    

Key Blog Features

📄

Blog Posts

Display articles with metadata

// app/blog/page.tsx
export default function Blog() {
  return <h1>All Posts</h1>
}
🔗

Dynamic Routes

Individual post pages

// app/blog/[slug]/page.tsx
export default function Post() {
  return <article>Post</article>
}
🎨

Markdown

Write content in Markdown

// Use markdown files
// posts/hello.md
---
title: Hello
---
🔍

SEO

Optimize for search engines

// Add metadata
export const metadata = {
  title: 'My Blog'
}

🔹 Blog Post List Component

Create a component to display all blog posts. This example shows how to fetch and render a list of posts with titles, dates, and excerpts for easy navigation.

// app/blog/page.tsx
const posts = [
  { id: 1, title: 'First Post', date: '2024-01-01' },
  { id: 2, title: 'Second Post', date: '2024-01-02' }
]

export default function BlogPage() {
  return (
    <div>
      <h1>Blog Posts</h1>
      {posts.map(post => (
        <article key={post.id}>
          <h2>{post.title}</h2>
          <time>{post.date}</time>
        </article>
      ))}
    </div>
  )
}

Output:

Blog Posts

First Post

Second Post

🔹 Dynamic Blog Post Page

Use dynamic routes to create individual pages for each blog post. The slug parameter from the URL determines which post to display with full content.

// app/blog/[slug]/page.tsx
export default function PostPage({ params }) {
  return (
    <article>
      <h1>Post: {params.slug}</h1>
      <p>This is the content of the blog post.</p>
      <p>You can add markdown, images, and more!</p>
    </article>
  )
}

// Generate static paths
export async function generateStaticParams() {
  return [
    { slug: 'first-post' },
    { slug: 'second-post' }
  ]
}

Output (for /blog/first-post):

Post: first-post

This is the content of the blog post.

You can add markdown, images, and more!

🔹 Blog Layout with Navigation

Create a shared layout for your blog with navigation and footer. This layout wraps all blog pages providing consistent structure and styling throughout your blog.

// app/blog/layout.tsx
export default function BlogLayout({ children }) {
  return (
    <div>
      <nav>
        <a href="/">Home</a>
        <a href="/blog">Blog</a>
        <a href="/about">About</a>
      </nav>
      <main>{children}</main>
      <footer>© 2025 My Blog</footer>
    </div>
  )
}

🔹 Fetching Blog Data

Fetch blog posts from an API or database using async server components. Next.js automatically handles data fetching on the server for better performance and SEO optimization.

// app/blog/page.tsx
async function getPosts() {
  const res = await fetch('https://api.example.com/posts')
  return res.json()
}

export default async function BlogPage() {
  const posts = await getPosts()
  
  return (
    <div>
      <h1>Latest Posts</h1>
      {posts.map(post => (
        <article key={post.id}>
          <h2>{post.title}</h2>
          <p>{post.excerpt}</p>
        </article>
      ))}
    </div>
  )
}

🧠 Test Your Knowledge

What folder structure creates a dynamic blog post route?