DISKON TERBATAS! Masukkan kupon "skillbaru" saat checkout di kelas apa saja
Skodev
Belajar coding dalam bahasa Indonesia
Yuk belajar bikin blog dengan bantuan Notion sebagai CMS. Kamu bisa membuat blog layaknya wordpress tapi dengan tampilan yang bisa kamu buat sendiri.
Daftar Isi:
Membuat blog pribadi memang menjadi kebutuhan seorang programmer. Di sana kita bisa menuliskan hal - hal yang kita pelajari atau sekedar sharing pengalaman. Saat ini, banyak yang memilih Notion sebagai platform untuk menulis konten mereka.
Berdasarkan data dari Forbes pada tahun 2021, pengguna Notion sudah mencapai 20 juta. Notion sendiri merupakan platform pengelolaan konten yang memiliki banyak fitur unggulan seperti mudah untuk kolaborasi, support Notion AI, fleksibel, dan banyak fitur lainnya. Kabar baiknya, Notion juga memiliki fitur Notion API yang memudahkan kita untuk menggunakannya sebagai CMS (Content Management System) untuk blog kita.
Pastikan kamu sudah terlebih dahulu menginstall Node.js dan npm. Stack yang dipakai untuk tutorial ini adalah :
Disclaimer : Pada tutorial ini kita akan berfokus kepada NextJS dan Notion API. Untuk aspek tampilan visual dan SEO, teman - teman diharapkan melakukan improvisasi.
Sebelum memulai konfigurasi, pastikan kamu memiliki akun Notion karena integrasi dengan NextJS memerlukan dua key, yaitu Notion Token
dan Database ID
Tutorial cara membuat Notion Token
, kamu bisa lihat tutorial atau ke halaman membuat token baru. Pada tutorial ini, saya menggunakan nama Integrasi Blog Pribadi.
Copy Notion Token
dari tab Secret
dan simpan dengan baik. (Keep it secret 🤫)
Setelah Notion Token
terbuat, kita akan mengatur Capabilities
integrasinya hanya untuk read-only
, sehingga fitur-fitur lain dapat dinonaktifkan.
Setelah berhasil membuat Notion Token
, langkah selanjutnya adalah membuat Database ID
.
Kamu bisa menduplikasi template Blog Pribadi yang ada di sini. Untuk tutorial duplikasi template, lihat pada tutorial.
Dalam template Blog Pribadi tersebut kita memiliki 7 atribute utama :
Setelah menduplikasi template di atas, buka template Notion di workspace kamu. Pada URL page tersebut, copy Database ID
sesuai dengan posisi URL di bawah ini:
https://www.notion.so/{workspace_name}/**{database_id}**?v={view_id}
Untuk mengintegrasikan Notion Token
dengan database, kita perlu menambahkan koneksi dengan cara mengklik •••
di kanan atas, lalu pilih Add Connections
dan pilih Integrasi Blog Pribadi yang telah dibuat pada step sebelumnya, atau dapat mengikuti petunjuk dalam tutorial.
Sampai di step ini, kita telah memiliki Notion Token
dan Database ID
.
NextJS adalah framework React yang memudahkan kita dalam mengembangkan aplikasi berbasis react. NextJS juga support Server Side Rendering (SSR) yang cocok untuk membuat blog menggunakan Notion API.
Untuk menginstall NextJS bisa menjalankan perintah ini pada terminal.
npx create-next-app@latest
Konfigurasi NextJS yang saya pakai tutorial ini.
√ What is your project named? blog-pribadi
√ Would you like to use TypeScript with this project? Yes
√ Would you like to use ESLint with this project? Yes
√ Would you like to use Tailwind CSS with this project? Yes
√ Would you like to use `src/` directory with this project? Yes
√ Use App Router (recommended)? Yes
√ Would you like to customize the default import alias? No
Masuk ke directory blog-pribadi
dan tambahkan plugin tailwind untuk membantu proses rendering HTML khususnya bagian typograhpy.
cd blog-pribadi
npm install -D @tailwindcss/typography
Buka tailwind.config.js
dan copy paste konfigurasi di bawah ini. Pada langkah ini kita hanya menghapus konfigurasi yang tidak terpakai dan menambahkan plugins yang telah kita install barusan.
/** @type {import('tailwindcss').Config} */
module.exports = {
content: [
'./src/pages/**/*.{js,ts,jsx,tsx,mdx}',
'./src/components/**/*.{js,ts,jsx,tsx,mdx}',
'./src/app/**/*.{js,ts,jsx,tsx,mdx}',
],
theme: {}, // Hapus theme yang tidak terpakai
plugins: [
require('@tailwindcss/typography'),
],
}
Pada step selanjutnya, kita hapus CSS class yang tidak diperlukan dan mengganti warna background pada body menjadi warna putih. Caranya bisa copy paste src/app/globals.css
di bawah ini.
@tailwind base;
@tailwind components;
@tailwind utilities;
body {
background: #ffffff;
}
Selanjutnya hapus codingan yang tidak terpakai di halaman page.tsx
sehingga menyisakan codingan di bawah ini.
export default function Home() {
return <></>;
}
Kemudian kita run perintah di bawah ini untuk memulai project.
npm run dev
Untuk mengaksesnya project kita pada browser, kita dapat menuliskan pada URL :
Jika tidak ada error, maka akan muncul halaman putih tanpa tulisan apa - apa. Dengan begini, kita berhasil menghapus codingan yang tidak terpakai dan siap untuk melanjutkan integrasi dengan Notion.
Kita akan menyimpan Notion Token
dan Database ID
yang telah kita dapatkan dengan format seperti di bawah ini pada .env.local
. Jika belum ada, bisa di buat file terlebih dahulu, pastikan untuk membuatnya pada root project.
NOTION_TOKEN="secret_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
NOTION_DATABASE_ID="xxxxxxxxxxxxxxxxxxxxxxx"
Untuk memudahkan dalam menampilkan data Notion di project kita, maka kita perlu menginstall library Notion.
npm install @notionhq/client @notion-render/client
Kita akan membuat tampilan list blog seperti di bawah ini. Data ini diambil dari template notion yang telah kita buat sebelumnya, dan hanya menampilkan list blog yang statusnya sudah Published
.
Buat file baru di src/app/lib/notion.tsx
dan copy paste codingan di bawah ini.
const { Client } = require("@notionhq/client");
export const notion = new Client({
auth: process.env.NOTION_TOKEN,
});
export const getAllPublishedBlog = async () => {
const posts = await notion.databases.query({
database_id: process.env.NOTION_DATABASE_ID,
filter: {
property: "status",
select: {
equals: "Published",
},
},
sorts: [
{
property: "createdTime",
direction: "descending",
},
],
});
const allPosts = posts.results;
return allPosts.map((post: any) => {
return getPageContent(post);
});
};
const getPageContent = (post: any) => {
return {
id: post.id,
title: post.properties.title.title[0].plain_text,
author: post.properties.author.select.name,
publishedDate: post.properties.publishedDate.date.start,
slug: post.properties.slug.formula.string,
description: post.properties.description.rich_text[0].plain_text,
};
};
status
= Published
dan diurutkan berdasarkan createdTime
secara descending
.Post
agar hasil dari fungsi tersebut hanya berisi object yang kita butuhkan.Tambahkan file baru src/app/types/Notion.tsx
untuk deklarasi types.
export type Post = {
id: string;
title: string;
slug: string;
description: string;
author: string;
status: string;
publishedDate: Date;
createdDate: Date;
}
Hapus semua codingan yang ada di page.tsx
dan copy paste dari codingan di bawah ini. Pada halaman ini, kita akan memanggil getAllPublishedBlog
dan me-render-nya pada halaman utama.
import Link from "next/link";
import { getAllPublishedBlog } from "./lib/notion";
import { Post } from "./types/Notion";
export default async function Home() {
const posts = await fetchBlogData();
return (
<main className="flex min-h-screen flex-col items-center justify-between p-24">
<div className="w-[672px] mx-auto">
<h1 className="text-3xl font-bold mb-6">List Blog</h1>
{posts.length === 0 ? (
<p>No posts available.</p>
) : (
posts.map((post: Post, index: number) => (
<article
key={index}
className="bg-white rounded-lg cursor-pointer p-4 mb-4 border-b border-gray-300"
>
<div>
<span className="text-gray-500 mb-2 text-sm">
{post.publishedDate.toString()}
</span>
<h2 className="text-xl font-semibold mb-2">
<Link
className="text-blue-500 hover:underline"
href={`/blog/${encodeURIComponent(post.slug)}`}
>
{post.title}
</Link>
</h2>
<p>{post.description}</p>
</div>
</article>
))
)}
</div>
</main>
);
}
async function fetchBlogData() {
const res = getAllPublishedBlog();
return res;
}
Jika kita mengklik salah satu judul blog dari list blog yang ada, maka halaman tersebut akan pergi ke halaman Detail Blog berdasarkan slug
yang dikirimkan.
Untuk implementasinya, kita kembali lagi file ke lib/notion.tsx
dan tambahkan codingan di bawah ini.
import { NotionRenderer } from "@notion-render/client";
// tambahkan di bawah function getAllPublishedBlog
export const getSinglePost = async (slug: string) => {
const response = await notion.databases.query({
database_id: process.env.NOTION_DATABASE_ID,
filter: {
property: "slug",
formula: {
string: {
equals: slug,
},
},
},
});
const singlePost = response.results[0];
const responseBlockPages = await notion.blocks.children.list({
block_id: singlePost.id,
});
const content = responseBlockPages.results;
const renderer = new NotionRenderer({
client: notion,
});
const html = await renderer.render(...content);
return {
...getPageContent(singlePost),
content: html,
};
};
slug
= parameter yang kita kirim. Selanjutnya kita mengambil isi block yang ada di dalam Notion dan me-render-nya ke dalam format HTML menggunakan library @notion-render/client
yang telah kita install sebelumnya.Buat file baru di src/app/blog/[slug]/page.tsx
dan copy paste codingan di bawah ini. Pada halaman ini kita akan me-render halaman detail blog dengan memanggil getSinglePost
. Parameter slug
yang ada di URL kita lempar ke dalam fungsi getSinglePost
untuk mendapatkan data Notion.
import { getSinglePost } from "@/app/lib/notion";
import Link from "next/link";
export default async function Page({ params }: { params: { slug: string } }) {
const post = await fetchBlogData(params.slug);
return (
<main className="flex min-h-screen flex-col items-center justify-between p-24">
<div className="w-[672px] mx-auto">
<Link href="/" className="text-blue-500">
< Go Back
</Link>
<div className="my-4">
<span className="text-gray-600">
{post.publishedDate} | By {post.author}{" "}
</span>
</div>
<h1 className="text-6xl text-gray-900 font-bold my-6">{post.title}</h1>
<div
className="prose"
dangerouslySetInnerHTML={{ __html: post.content }}
></div>
</div>
</main>
);
}
async function fetchBlogData(slug: string) {
const res = getSinglePost(slug);
return res;
}
Jika semuanya sudah berjalan dengan baik, kamu bisa push codingan kamu ke github dan mendeploy ke Vercel. Pastikan Notion Token
dan Database ID
kamu terkonfigurasi dengan baik di Vercel.
Untuk source code tutorial ini bisa di lihat di github.
Jika kamu ingin melakukan perubahan dalam konten blog kamu, kamu tidak perlu mengubah codingan apapun, kamu hanya perlu mengubahnya pada notion database dan perubahan tersebut akan langsung teraplikasi pada blog kamu. Selamat mencoba.
Hi, saya Michelle, software engineer yang suka menulis kata dan syntax.