如何利用 Github Issues 写博客?
主要技术点
主要开发步骤
步骤一:创建 Next.js App
npx create-next-app@latest --typescript
步骤二:使用 Vercel 环境变量
export const REPO = process.env.VERCEL_GIT_REPO_SLUG || "";
export const OWNER = process.env.VERCEL_GIT_REPO_OWNER || "";
import { Octokit } from "@octokit/core";
import { OWNER, REPO } from "../config";
export async function getRepositoryIssues() {
const octokit = new Octokit();
const response = await octokit.request("GET /repos/{owner}/{repo}/issues", {
owner: OWNER,
repo: REPO,
});
return response.data;
}
export async function getRepositoryIssue(issueNumber: number) {
const octokit = new Octokit();
const response = await octokit.request(
"GET /repos/{owner}/{repo}/issues/{issue_number}",
{
owner: OWNER,
repo: REPO,
issue_number: issueNumber,
}
);
return response.data;
}
步骤四:首页展示仓库 issues 列表
import type { GetStaticProps, NextPage } from "next";
import Link from "next/link";
import { getRepositoryIssues } from "../lib/github";
import { PostType } from "../types";
const Home: NextPage<{ posts: PostType[] }> = ({ posts = [] }) => {
return (
<ul>
{posts.map((post) => (
<li key={post.title}>
<Link href={`/posts/${post.number}`}>
<a>{post.title}</a>
</Link>
</li>
))}
</ul>
);
};
export const getStaticProps: GetStaticProps = async () => {
const issues = await getRepositoryIssues();
return {
props: {
posts,
},
};
};
export default Home;
步骤五:生成具体的每一篇博客
import { GetStaticPaths, GetStaticProps, NextPage } from "next";
import ReactMarkdown from "react-markdown";
import { getRepositoryIssue, getRepositoryIssues } from "../../lib/github";
const Post: NextPage<{ dataSource?: PostType }> = ({ dataSource }) => {
return <ReactMarkdown>{dataSource.body || ""}</ReactMarkdown>;
};
export const getStaticPaths: GetStaticPaths = async () => {
const issues = await getRepositoryIssues();
return {
paths: issues.map((issue) => ({
params: { number: String(issue.number) },
})),
fallback: false,
};
};
export const getStaticProps: GetStaticProps = async ({ params }) => {
const issue = await getRepositoryIssue(Number(params.number));
return {
props: {
dataSource: issue,
},
};
};
export default Post;