Pendahuluan
Blog Merupakan suatu wadah untuk menuangkan ide, pemikiran, anatau untuk wadah bertukar informasi. Sebagai Developer kita bisa membuat blog dengan menggunakan berbagai macam teknologi, salah satunya adalah dengan menggunakan Next.js dan MDX.
Apa itu nextjs
Next.js merupakan project open source yang dikembangkan oleh Vercel. Next.js menggunakan React sebagai library utama untuk membangun web app, dengan menggunakan Next.js yang memiliki konsep component-based architecture memungkinkan kita untuk membangun web app dengan lebih cepat dan efisien. Lalu mengapa kita harus menggunakan Next.js? berikut beberapa alasan mengapa kita harus menggunakan Next.js:
- Easy Routing
- Static Site Generation
- Server Side Rendering
- SEO optimization
Informasi lebih lanjut mengenai Next.js bisa dilihat di sini.
Apa itu MDX?
MDX merupakan gabungan dari Markdown dan JSX, hal ini memungkinkan MDX dicompile menggunakan JSX dan memungkinkan kita untuk menambahkan komponen JSX menuju Markdown.
---
title: "Membuat Blog dengan MDX dan Next.js"
description: "This is the first blog post"
date: 2024-01-01
---
# Ini heading dari MDX
menambahkan komponen alert pada file MDX
<Component />
MDX sendiri memiliki struktur file yang mirip dengan markdown seperti contoh diatas dimana terdapat frontMatter
dan main content
. frontMatter
bisa juga disebut dengan metadata dari suatu file, biasanya terdiri dari judul, deskripsi, tanggal, atau pengarang. Sedangakn main content
merupakan isi konten dari file tersebut.
Mengapa kita harus menggunakan MDX? berikut beberapa alasan mengapa kita harus menggunakan MDX:
- Memungkinkan kita untuk menulis komponen React di dalam Markdown.
- Memiliki basis markdown sehingga mudah untuk digunakan.
- Bisa melakukan customisasi sesuai kebutuhan.
Untuk lebih lengkap mengenai MDX bisa dilihat di sini.
Konfigurasi MDX
Untuk membangun blog dengan menggunakan MDX dan Next.js kita harus melakukan konfigurasi terlebih dahulu, berikut langkah-langkah yang harus dilakukan untuk melakukan konfigurasi MDX.
1. Installasi package Next.js
npx create-next-app@latest blox-mdx
cd blox-mdx
npm install
npm run dev
2. Installasi package MDX
npm install @next/mdx @mdx-js/loader @mdx-js/react @types/mdx
Setelah melakukan installasi package diatas lakukan penambahan seperti dibawah ini pada file next.config.mjs .
import createMDX from "@next/mdx";
/** @type {import('next').NextConfig} */
const nextConfig = {
// Configure `pageExtensions` to include markdown and MDX files
pageExtensions: ["js", "jsx", "md", "mdx", "ts", "tsx"],
// Optionally, add any other Next.js config below
};
const withMDX = createMDX({
// Add markdown plugins here, as desired
});
// Merge MDX config with Next.js config
export default withMDX(nextConfig);
Penambahan code diatas digunakan untuk memberikan akses nextjs untuk bisa menggunakan file markdown dan mdx.
3. Install gray-matter
npm install gray-matter
Directory Structure
Setelah melakukan konfigurasi diatas kita bisa lanjut untuk membuat blog page, yang pertama dilakukan adalah buat halaman blog dan buat folder posts seperti dibawah ini. Setelah melakukan konfigurasi diatas selanjutnya buat halaman blog dengan membuat file page.tsx pada folder blog dan buat folder posts pada app directory project kemudian isi dengan 1 atau 2 dile mdx dengan struktur seperti contoh sebelumnya.
.
└── project/
├── app/
│ └── blog/
│ └── page.tsx
└── posts/
├── blog-one.tsx
└── blog-two.tsx
Fungsi untuk mendapatkan postingan blog
Sebelum membuat fungsi yang berfungsi untuk mendapatkan slug, content, dan frontMatter dari file mdx, mari kita pahami bagaimana cara mendapatkan isi (isi disini mencakup fronMatter dan main content) dari file mdx. Dengan menggunakan fungsi readdirSync dan readFileSync pada package fs kita bisa mendapatkan isi dari file mdx yang ada pada directory posts, berikut gambaran untuk lebih mudah dipahami.
Langkah selanjutnya adalah membuat fungsi yang berfungsi untuk mendapatkan slug, content, dan frontMatter dari file mdx yang ada pada directory posts.
import fs from "fs";
import path from "path";
import matter from "gray-matter";
export function getPosts() {
// declare directory
const dir = path.join(process.cwd(), "posts");
const files = fs.readdirSync(dir);
const contentFile = files.map((file) => {
return fs.readFileSync(`${dir}/${file}`, "utf8");
});
// ...
// get slug from name file
const slug = files.map((file) => {
const slug = file.replace(".mdx", "");
return slug;
});
// get frontMatter and content from file and combine with slug
let frontMatter = contentFile.map((file, id) => {
const {content,data} = matter(file);
return {
frontMatter: data,
content: content,
slug: slug[id]
};
});
return frontMatter;
}
fungsi diatas terdiri dari beberapa bagian utama diantaranya:
- Mendapatkan isi konten dari file mdx.
- Mendapatkan frontMatter dari file mdx.
- Mendapatkan slug dari file mdx.
Menampilkan Postingan Blog
Untuk kita dapat menampilkan postingan blog kita bisa menggunakan fungsi yang telah kita buat sebelumnya, berikut contoh code untuk mendapatkan frontMatter dan slug dari postingan blog.
const fetchData = async () => {
const posts = getPosts();
return posts ;
// const data = props;
};
const files = await fetchData();
Untuk menampilkan postingan blog kita bisa melakukan mapping, menggunakan fungsi map
dari js
pada variabel object files, yang berisi frontMatter
dan slug
dari postingan yang ada pada posts directory. Kalian bisa membuat sebuah component untuk blog card
, atau bisa langsung menampilkan postingan blog pada page blog. Berikut contoh code untuk menampilkan postingan blog.
// pages/blog/page.tsx
export default async function Blog() {
const fetchData = async () => {
const posts = getPosts();
return posts ;
// const data = props;
};
const files = await fetchData();
return (
<section>
{posts.map((post) => (
<article key={post.slug}>
<h1>{post.frontMatter.title}</h1>
<p>{post.frontMatter.description}</p>
<p>{post.frontMatter.date}</p>
</article>
))}
</section>
);
}
Detail Postingan Blog
Dalam konteks pembuatan blog dengan Next.js dan MDX, [slug]
directory biasanya merujuk pada parameter
pada halaman dinamis yang dibuat untuk setiap postingan blog. Slug adalah bagian dari URL yang biasanya digunakan untuk mengidentifikasi sumber daya secara unik. Dalam kasus ini, slug diambil dari nama file postingan blog.
Buat folder [slug]
pada folder blog, kemudian buat file page.tsx
pada folder [slug]
seperti dibawah ini.
.
└── project/
├── app/
│ └── blog/
│ ├── page.tsx
│ └── [slug]/
│ └── page.tsx
└── posts/
├── blog-one.tsx
└── blog-two.tsx
Untuk mendapatkan data postingan yang sesuai dengan slug
yang diberikan, kita bisa menggunakan fungsi yang telah kita buat sebelumnya. Berikut contoh code untuk mendapatkan data postingan yang sesuai dengan slug
yang diberikan.
// pages/blog/[slug]/page.tsx
import { getPosts } from "../../../lib/posts";
export default function Blog({ params }: { params: { slug: string } }) {
const props = getPost().find((post) => post.slug === params.slug);
//...
if (!props) {
return <div>Post not found</div>;
}
return (
//...
<article>
{props.content}
</article>
//...
);
}
Untuk menampilkannya kita bisa lengsung memasukkan saja menuju tag article
. Namun dikarenakan content yang kita dapat masih menggunakan format mdx
atau md
kita harus mengkonversinya terlebih dahulu menggunakan MDXRemote
. Berikut contoh code untuk menampilkan postingan blog.
// pages/blog/[slug]/page.tsx
import { MDXRemote } from "next-mdx-remote/rsc";
//...
export default function Blog({ params }: { params: { slug: string } }) {
//...
return (
//...
<article>
<MDXRemote source={props.content} />
</article>
//...
);
}
Jika fungsi diatas berjalan maka akan nampak seperti gambar dibawah ini.
Dilihat dari hasil diatas postingan berhasil ditampilkan pada halaman menggunakan MDXRemote
, namun terdapat masalah pada styling yang tidak teraplikasikan dengan baik. Untuk mengaytasi hal berikut bisa menggunakan package @tailwindcss/typography
dari TailwindCSS.
Pertama kita install terlabih dahulu package tersebut.
npm install -D @tailwindcss/typography
Setelah melakukan instalasi package kita tambahkan terlebih dahulu pada tailwind.config.js seperti dibawah ini.
// tailwind.config.js
module.exports = {
//...
plugins: [require("@tailwindcss/typography")],
};
Langkah selanjutnya ialah menambahkan class prose
pada tag article pada detail konten page seperti dibawah ini. Setelah menambahkan class prose maka postingan blog akan terlihat seperti gambar dibawah ini.
// pages/blog/[slug]/page.tsx
//...
<article className="prose">
<MDXRemote source={props.content} />
</article>
//...
Dari hasil diatas masih banyak yang bisa di kembangkan lagi sesuai kebutuhan masing-masing, seperti menambahkan navigasi, menambahkan style, atau menambahkan fitur lainnya seperti Table Of Content, Input Search, dan Filter Tags.