This project is a barebones blog system that uses Markdown for content formatting, built on NextJS with Tailwind CSS. It should be enough to get you started with whatever you want to make.
It has basic styling applied, allowing you to write your own HTML layouts and styles without having to remove a bunch of crap you don't want (a problem I found with a lot of starter templates).
To create your own blog using this project, follow the steps below.
- Click the Use This Template button in the top-right corner of the repository.
- Click Create a new repository option.
- In the
Repository name
field, enter<your github username>.github.io
. - (Optional) Enter a description and set the repo to Public or Private1, then click Create Repository.
You can see your code changes in real-time by running a local development server on your machine.
- Open the project root directory in your preferred terminal client.
- Type
npm run dev
into the terminal window. - Open https://localhost:30000 to see your result.
You can change the main page code in src/app/page.tsx
.
export default async function Index() {
const allPosts: Post[] = getAllPosts(['title', 'date', 'slug']);
return (
<div className="container mx-auto">
<h1 className="text-4xl font-bold my-8">Your Blog Name</h1>
<ul>
{allPosts.map((post) => (
<li key={post.slug}>
<Link href={`/posts/${post.slug}`} legacyBehavior>
<a className="text-xl text-blue-500">{post.title}</a>
</Link>
<p className="text-gray-600">{post.date}</p>
</li>
))}
</ul>
</div>
);
}
If you want to change the code for the post pages, you can edit the code in src/app/posts/[slug]/page.tsx
.
import { getPostBySlug, getAllPosts } from '../../lib/posts';
interface PostProps {
post: {
title: string;
date: string;
content: string;
};
}
export async function generateStaticParams() {
const posts = getAllPosts(['slug']);
return posts.map(post => ({ slug: post.slug }));
}
export default async function Post({ params }: { params: { slug: string } }) {
const post = getPostBySlug(params.slug, ['title', 'date', 'slug', 'content']);
return (
<div className="container mx-auto">
<h1 className="text-4xl font-bold my-8">{post.title}</h1>
<p className="text-gray-600">{post.date}</p>
<div className="prose" dangerouslySetInnerHTML={{ __html: post.content }} />
</div>
);
}
This repo already includes a GitHub Actions workflow that will build and deploy to GitHub Pages whenever any changes are merged to main
branch. If you'd like to implement your own workflow, simply delete the .github
directory.
If you'd like to generate a static version of the site when you run npm run build
, change the next.config.mjs
file to the following:
/** @type {import('next').NextConfig} */
const nextConfig = {
output: 'export'
};
export default nextConfig;
New posts can be created in the posts/
directory with individual Markdown or .md
files.
---
title: 'Hello World!'
date: '2024-07-26'
---
This is your post body
The name of the .md
file will determine the page name when you visit your site (ie. hello-world.md will be sitename.com/posts/hello-world
)
The post metadata such as the post title and name are contained in the top of the file between the hyphen tags. The post body is below the meta section. Check out the Markdown website for a rundown on how to format your posts.
To learn more about Next.js, take a look at the following resources:
- Next.js Documentation - learn about Next.js features and API.
- Next.js GitHub repository
- Learn Next.js - an interactive Next.js tutorial.
Footnotes
-
If you are using a free GitHub account, selecting Private repository will prevent the CICD pipeline from executing. If you'd like to have a private repo but a public site, you'll need a GitHub Pro subscription. ↩