#Introduction
Over the past few months from December 2024, I've planned to crate blog site. Then from January 2025, I've started to code build my blog site. Firstly I Prefer Next.js. I've used the following technologies to build my blog site.
#The Technologies I've Used
Next.js
15.1.6
React
19.0.0
MDX
3.0.1
Tailwind CSS
3.4.1
Shiki
2.0.3
React Spring
9.0.0
Framer Motion
4.1.17
MongoDB
4.4.0
TypeScript
4.5.4
When I built my blog, I knew I needed a way to embed completely custom content in every post—things. Traditional markdown or rich-text editors in a CMS typically restrict you to a limited set of HTML elements, making it difficult to implement truly unique features.
#Content Management
This blog is written with Next.js App Router
. Which is support Server component. This is static site which means every time I write blog I have to rebuild the app. I've used MDX to write my posts. MDX is a markdown format that allows you to write JSX in your markdown files. This means you can import React components and use them in your posts.
I have use Next.js Server action for Data fetching and mutation. I need to use database staff hits and like. I've used mongoose for database connection and MongoDB for database.
#Using MDX with Next.js
There are some ways to use MDX with Next.js. I've used the following way to use MDX with Next.js.
- ->The official way @next/mdx
- ->Hashicorp's next-mdx-remote
- ->Hashicorp's next-mdx-enhanced
On this blog, I've used next-mdx-remote.
#Metadata
I've used gray-matter to extract metadata from my MDX files. This allows me to include things like the title, description, and published date in the front matter of my posts.
Here's what this post looks like:
--- title: How I Built My Blog description: Firstly I Prefer Next.js. I've used. background: bg1.png technologies: Next.js, Tailwind CSS, MDX, Shiki publishedAt: 2024-12-14 updatedAt: 2024-12-14 tags: ["introduction", "mdx"] --- (Actual blog post content here!)
#Content writing on MDX file
Hello there! This is a paragraph. This is another paragraph, with some **bold text**. Here's a list of things: 1. Apple 2. Banana 3. Carrot
When using Markdown in a web application, there's a "compile" step; the Markdown needs to be transformed into HTML, so that it can be understood by the browser. Those asterisks get turned into a <strong>
tag, the list gets turned into a <ul>
, and each paragraph gets a <p>
tag.
This is great, but it means we're limited to a handful of HTML elements that Markdown is aware of.
MDX takes the format a step further, and allows us to include our own elements, in the form of React components:
import PieChart from '../components/PieChart'; This paragraph introduces a **data visualization**: <PieChart title="Favourite foods" data={[ { label: 'Pizza', value: '30%' }, { label: 'Broccoli', value: '5%' }, { label: 'Haagen-Dasz', value: '65%' }, ]} />
#Index page
On the home page. I have two separate sections
- ->All latest posts, in chronological order
- ->The 10 most-viewed posts of all time
As I am using Next.js App Router
I write server component and it allow to call database for list of articles
// app/page.js (or page.tsx if using TypeScript) import { getLatestContent, getPopularContent } from "@/lib/content"; export default async function Homepage() { // Fetch data directly inside the server component const newestContent = await getLatestContent({ limit: 20 }); const popularContent = await getPopularContent({ limit: 10 }); return ( // jsx ); }
#Backend staff
I've used mongoose for database connection and MongoDB for database. I've used mongoose schema for database model.
{ "slug": "how-i-built-my-blog", "categorySlug": "general", "hits": 20, "likesByUser": { "abc123": 16, "def456": 4, "ghi789": 16 } }
Vercel provide IP address of user and I've used that IP address and using crypto I've generated unique user id. I've used that user id to store like. One user can like 16 times. I've used hits
to store how many times article has been viewed.
Quick little NPM protip: you can create pre-run scripts by using the pre prefix. When I run npm run build or yarn build, it will automatically run the prebuild script first, if defined. You can also run scripts afterwards with the post prefix.
#RSS Feed
Taking the RSS feed as an example, the process looks like this:
- ->Install the rss dependency: It'll handle the XML formatting for us.
- ->Collect all of the MDX files in the pages directory, using fs.readdirSync.
- ->Load the frontmatter, using gray-matter. Pluck out the relevant details (title, abstract).
- ->Filter out any unpublished posts (ones where isPublished is not set to true).
- ->Add each item to the feed, using the rss module
- ->Save the generated .xml file in ./public/rss.xml
By storing it in public, I ensure that Next will copy it over to the static directory, and make it publicly-available. I also added this file to my .gitignore, since it's a generated file.
To be continued...