I will show you how to build a simple portfolio blog using Next.js, a powerful React framework that allows you to create fast and SEO-friendly web applications. We’ll create a minimalistic blog to showcase posts, each of which can have a title, date, tags, and content. I’ll walk you through the coding steps, the project structure, and also how to display results dynamically in a live environment.
The homepage displays links to each post, and when you click on one, the blog displays the full article. This project uses Next.js to handle server-side rendering (SSR), dynamic routing, and static site generation (SSG), ensuring optimal performance.
The Structure of an Article on the Blog
Each blog post is created as a Markdown file and contains metadata at the top. Here’s an example of how a blog post might look:
---
title: "Building a Simple Portfolio Blog"
date: "2025-06-01"
tags: ["Next.js", "Portfolio", "Blogging"]
---
## Introduction
This blog post is about building a portfolio blog using Next.js...
This file is placed in the /posts
directory and rendered by Next.js.
How the Search Feature
The search feature is simple and client-side. It filters blog posts based on the title matching the user’s query. When you type in the search bar, the page dynamically filters the blog posts without needing to reload the page.
Here’s how it works:
- Collecting Data: All posts are stored in a folder (
/posts
), and we loop through them to extract the titles and metadata. - Filtering Data: The user’s input is matched against the titles of the posts. This is done by filtering the post list on the client-side.
- Displaying Results: The filtered posts are displayed as the user types, allowing for real-time search results.
The Project Structure
Here’s a look at the project structure:
/portfolio-blog
├── /pages
│ ├── index.js
│ ├── /posts
│ │ ├── [slug].js
│ └── _app.js
├── /posts
│ ├── post-1.md
│ ├── post-2.md
│ └── post-3.md
├── /components
│ ├── Layout.js
│ ├── SearchBar.js
│ └── PostList.js
└── package.json
Steps to Build the Blog
Create a New Next.js Project
First, create a new Next.js project by running the following commands:
create-next-app portfolio-blog
Navigate into the project folder and run the development server:
portfolio-blog
npm run dev
Now you can view a project at http://localhost:3000.
Set Up the Markdown File
Next, create a folder called posts
in the root directory, and add some Markdown files with content for your blog posts.
Example post-1.md
:
---
title: "How to Build a Portfolio Blog"
date: "2025-06-01"
tags: ["Next.js", "Portfolio", "Blogging"]
---
## Introduction
This blog post is about building a portfolio blog using Next.js...
Create the Components
Let’s create three components for the blog:
Layout.js – A common layout with a header, footer, and content wrapper:
// components/Layout.js
import React from 'react';
const Layout = ({ children }) => {
return (
<div>
<header>
<h1>My Portfolio Blog</h1>
</header>
<main>{children}</main>
<footer>
<p>© 2025 My Portfolio Blog</p>
</footer>
</div>
);
};
export default Layout;
SearchBar.js – A component for searching through blog posts:
// components/SearchBar.js
import { useState } from 'react';
const SearchBar = ({ posts }) => {
const [query, setQuery] = useState('');
const filteredPosts = posts.filter(post => post.title.toLowerCase().includes(query.toLowerCase()));
return (
<div>
<input
type="text"
placeholder="Search posts..."
value={query}
onChange={(e) => setQuery(e.target.value)}
/>
<ul>
{filteredPosts.map(post => (
<li key={post.slug}>{post.title}</li>
))}
</ul>
</div>
);
};
export default SearchBar;
PostList.js – A component to display the list of blog posts:
// components/PostList.js
import Link from 'next/link';
const PostList = ({ posts }) => {
return (
<div>
<h2>Blog Posts</h2>
<ul>
{posts.map(post => (
<li key={post.slug}>
<Link href={`/posts/${post.slug}`}>
<a>{post.title}</a>
</Link>
</li>
))}
</ul>
</div>
);
};
export default PostList;
Fetch and Display Posts on the Homepage
Now, in the pages/index.js
file, we will fetch the blog posts and render them using the components we created:
// pages/index.js
import { useEffect, useState } from 'react';
import PostList from '../components/PostList';
import SearchBar from '../components/SearchBar';
import Layout from '../components/Layout';
const Home = () => {
const [posts, setPosts] = useState([]);
useEffect(() => {
const fetchPosts = async () => {
const postFiles = require.context('../posts', false, /\.md$/);
const postsData = postFiles.keys().map(filename => {
const postContent = postFiles(filename);
return {
slug: filename.replace('./', '').replace('.md', ''),
title: postContent.title,
date: postContent.date
};
});
setPosts(postsData);
};
fetchPosts();
}, []);
return (
<Layout>
<SearchBar posts={posts} />
<PostList posts={posts} />
</Layout>
);
};
export default Home;
Dynamic Post Pages
Create dynamic post pages inside the /pages/posts/[slug].js
file to display the full article:
// pages/posts/[slug].js
import { useRouter } from 'next/router';
import Layout from '../../components/Layout';
const Post = ({ post }) => {
if (!post) {
return <div>Loading...</div>;
}
return (
<Layout>
<h2>{post.title}</h2>
<p>{post.date}</p>
<div>{post.content}</div>
</Layout>
);
};
export default Post;
Live Example
To see this portfolio blog in action, you can deploy it using platforms like Vercel or Netlify, which are optimized for Next.js projects. Once deployed, you will have a live version of the blog, where you can interact with the search functionality and navigate between posts.
If you would like to deploy this blog yourself, follow the steps provided in the official Next.js Deployment Documentation.
Conclusion
Building a portfolio blog with Next.js is a simple yet effective project to get started with the framework. By following this guide, you’ll have a functional blog with a search feature, dynamic pages, and a clean layout. You can expand this further by adding more features, such as authentication, comments, or even a CMS for easier content management.