实战项目:使用 Next.js 构建个人博客系统

class 个人博客

这个项目将指导你如何使用 Next.js 和 Markdown 构建一个完整的个人博客系统。我们将使用静态生成(SSG)来创建博客页面,并集成 Markdown 作为内容管理方式。

项目结构

以下是项目的基本结构:

my-blog/
├── public/                # 静态文件
├── src/                   # 源代码
│   ├── components/        # 共享组件
│   ├── pages/             # 页面组件
│   ├── posts/             # Markdown 文件存放目录
│   ├── styles/            # 样式文件
│   └── lib/               # 公共函数
├── package.json           # 项目信息
└── next.config.js         # Next.js 配置

1. 创建 Next.js 项目

首先,创建一个新的 Next.js 项目:

npx create-next-app my-blog
cd my-blog

2. 安装依赖

我们需要安装一些用于处理 Markdown 的库:

npm install gray-matter markdown-it
  • gray-matter:用于解析 Markdown 文件的元数据。
  • markdown-it:用于将 Markdown 转换为 HTML。

3. 设置 Markdown 文件

src/posts 目录下创建 Markdown 文件,作为博客文章的内容。

<!-- src/posts/first-post.md -->
---
title: "My First Post"
date: "2024-10-01"
---

# Hello World!

This is my first blog post using **Next.js** and Markdown!

4. 创建文件读取函数

src/lib 目录下创建一个用于读取 Markdown 文件的函数。

// src/lib/posts.js
import fs from 'fs';
import path from 'path';
import matter from 'gray-matter';

const postsDirectory = path.join(process.cwd(), 'src/posts');

export const getPosts = () => {
  const fileNames = fs.readdirSync(postsDirectory);
  const posts = fileNames.map((fileName) => {
    const fullPath = path.join(postsDirectory, fileName);
    const fileContents = fs.readFileSync(fullPath, 'utf8');
    const { data } = matter(fileContents);
    return {
      ...data,
      slug: fileName.replace(/\.md$/, ''),
    };
  });
  return posts;
};

export const getPostBySlug = (slug) => {
  const fullPath = path.join(postsDirectory, `${slug}.md`);
  const fileContents = fs.readFileSync(fullPath, 'utf8');
  const { data, content } = matter(fileContents);
  return {
    ...data,
    content,
  };
};

5. 创建博客列表页面

src/pages/index.js 中,创建一个博客列表页面,展示所有文章的标题和链接。

// src/pages/index.js
import Link from 'next/link';
import { getPosts } from '../lib/posts';

const HomePage = ({ posts }) => {
  return (
    <div>
      <h1>My Blog</h1>
      <ul>
        {posts.map((post) => (
          <li key={post.slug}>
            <Link href={`/posts/${post.slug}`}>
              <a>{post.title}</a>
            </Link>
            <p>{post.date}</p>
          </li>
        ))}
      </ul>
    </div>
  );
};

export async function getStaticProps() {
  const posts = getPosts();
  return {
    props: {
      posts,
    },
  };
}

export default HomePage;

6. 创建博客详情页面

src/pages/posts/[slug].js 中,创建一个动态路由页面,展示单篇博客文章。

// src/pages/posts/[slug].js
import { getPostBySlug, getPosts } from '../../lib/posts';
import MarkdownIt from 'markdown-it';

const PostPage = ({ post }) => {
  const md = new MarkdownIt();
  const htmlContent = md.render(post.content);

  return (
    <div>
      <h1>{post.title}</h1>
      <p>{post.date}</p>
      <div dangerouslySetInnerHTML={{ __html: htmlContent }} />
    </div>
  );
};

export async function getStaticPaths() {
  const posts = getPosts();
  const paths = posts.map((post) => ({ params: { slug: post.slug } }));

  return {
    paths,
    fallback: false,
  };
}

export async function getStaticProps({ params }) {
  const post = getPostBySlug(params.slug);
  return {
    props: {
      post,
    },
  };
}

export default PostPage;

7. 添加样式

src/styles/globals.css 中添加一些基本样式。

/* src/styles/globals.css */
body {
  font-family: Arial, sans-serif;
  margin: 0;
  padding: 20px;
}

h1 {
  color: #333;
}

ul {
  list-style-type: none;
  padding: 0;
}

li {
  margin: 10px 0;
}

a {
  text-decoration: none;
  color: #0070f3;
}

确保在 _app.js 中引入全局样式。

// src/pages/_app.js
import '../styles/globals.css';

function MyApp({ Component, pageProps }) {
  return <Component {...pageProps} />;
}

export default MyApp;

8. 运行项目

完成所有步骤后,可以在本地运行项目:

npm run dev

访问 http://localhost:3000,你将看到博客文章列表。点击标题将导航到单篇文章的详细页面。

总结

通过以上步骤,你成功构建了一个使用 Next.js 和 Markdown 的个人博客系统。这个系统使用了静态生成(SSG),可确保快速加载,同时允许你通过 Markdown 文件管理内容。可以进一步扩展功能,比如添加评论、搜索、标签等,以提升博客的实用性和美观性。

评论区
评论列表
menu