Ketika kalian mempertimbangkan membuat blog dev untuk diri sendiri. Anda mungkin akan cukup kewalahan dengan banyaknya tool dan teknologi baru yang bermunculan. Ya, mungkin kita hidup di era yang cukup berkelimpahan dengan banyaknya pilihan.
Ketika saya ingin membuat blog dev saya, yang pertama saya pertimbangkan adalah bagaimana saya bisa membuat postingan yang sepenuhnya dapat di custom, seperti terdapat editor html yang realtime preview, komponen yang interaktif seperti tombol yang bisa di mouseover dan juga terdapat fitur ubah css. Pada intinya bagaimana konten tersebut bisa lebih interaktif.
React
Blog ini menggunakan Gatsbyjs.
Gatsbyjs adalah salah satu framework static site generator
atau tool penghasil halaman statik yang berbasis React
. Salah satu fitur gatsbyjs yang menarik bagi saya adalah sistem pluginnya, dimana kita dapat dengan mudah mengintegrasikan layanan yang lain, misalnya untuk kebutuhan content seperti contentful, prismic, headless wordpress dan headless CMS lainnya.
Apapun yang Anda bayangkan ketika ingin mengambil data dari CMS hingga headless ecommerce dapat dilakukan dengan mudah memanfaatkan Gatsby Plugin.
Route
Saya menggunakan File System Route dan Client-only Route dalam menyajikan konten-konten yang ada di blog saya.
Walaupun Gatsby merupakan static site generator, namun tidak menutup kemungkinan kita dapat membangun aplikasi dengan route yang dimamis menggunakan Gatsby. Dengan memnafaatkan Cleint-only route
, kita dapat membangun aplikasi dinamis layaknya framework yang lain seperti CRA (create react app).
Files system route adalah sistem perutean yang ada di Gatsby dengan memanfaatkan nama file, sehingga setiap ingin membuat sebuah route hanya dengan membuat file didalam direktori pages
, sistem perutean ini akan di generate pada saat proses build.
Client-only routes adalah sistem perutean yang hanya akan tersedia disi client karena proses renderingnya hanya dilakukan disisi client, sehingga dengan menggunakan route ini memungkinkan untuk membuat route yang lebih dinamis.
Dalam kasus ini, saya menggunakan client-only route hanya di halaman work
, karena di halaman ini saya menginginkan konten yang lebih dinamis, sehingga konten akan lebih cepat terupdate tanpa perlu melakukan build ulang.
Perlu diingat bahwa Gatsby adalah static site generator yang mana semua perubahan yang dilakukan terhadap konten (source) hanya dapat terlihat setelah melakukan build ulang.
Secara keseluruhan, blog ini tersedia dalam bentuk statik yang di generate oleh Gatsby. Namun ada bagian-bagian tertentu yang ditampilkan secara dinamis, sehingga dalam kasus ini perlu dilakukan fetching di sisi klien. Seperti halaman home pada gambar berikut:
Data Fetching
Dibagian home, saya memiliki dua daftar postingan yang terpisah yaitu postingan article
dan work
.
Bagian article
, saya menggunakan metode static generate
yang menghasilkan sebuah file statik pada saat build, yang dapat membuat proses response lebih cepat ketika diakses. Hal ini juga memungkinkan artikel kita lebih optimal dari sisi SEO.
Kemudian bagian work
menggunakan data fetching di sisi klien, sehingga proses renderingnya pun di sisi klien. Kenapa hal ini berbeda dengan yang lain?, karena:
- Ketergantungan menambah dan mengedit
work
dari project yang telah dikerjakan sehingga membutuhkan response yang lebih dinamis untuk melihat hasilnya. - Kita bisa abaikan dari sisi SEO dibagian
work
, jadi tidak perlu dilakukan render di sisi server ataupun digenerate statik.
// query untuk artikel
const data = useStaticQuery(graphql`
query {
allFile(
limit: 6
sort: {fields: childMdx___frontmatter___publishedOn, order: DESC}
filter: {
childMdx: {
frontmatter: {isPublished: {eq: true}}
}
sourceInstanceName: { eq: "blogs" }
}
) {
edges {
node {
childMdx {
frontmatter {
title
publishedOn
isPublished
seoTitle
abstract
featuredImage {
childImageSharp {
gatsbyImageData(layout: FULL_WIDTH, placeholder: BLURRED)
}
}
}
fields {
slug
}
body
slug
excerpt
}
}
}
}
}
`)
Disini saya menggunakan hooks
useStaticQuery
untuk mengambil data dari mdx
.
Jadi MDX
adalah perpanjangan dari Markdown
, hanya saja dengan mdx
kita dapat meanmbahkan komponen react kedalam file mdx
.
// query untuk work
const WORK_COLLECTION = gql`
query GetWorkCollection {
workCollection(limit: 6) {
items {
title
sys {
id
}
description
featuredImage {
url
}
techsCollection {
items {
... on TechIcon {
name
}
}
}
category {
... on WorkCategory {
title
}
}
}
}
}
`
const { loading, data: dataWorks } = useQuery(WORK_COLLECTION)
Kemdudian untuk postingan work
, disini saya menggunakan hooks
yang disediakan oleh Apollo Client dari ApolloGraphQL. Bagian ini akan diquery di sisi klien, jadi proses querynya akan dilakukan setiap kita mengakses halaman work
sehingga membuat konten ini up to date, namun sekali lagi hal ini mungkin dari sisi SEO kurang optimal.
Source
Berhubungan dengan sumber datanya, disini saya menggunakan dua sumber data yaitu Mdx dan CMS Contentful. Saya menulis artikel di mdx
ketika ingin membuat konten tersebut lebih interaktif, seperti untuk konten sepeutar style di React
, kita dapat menempatkan komponen react seperti Button
yang memiliki action
hover
ataupun akan muncul popup ketika di klik.
Kemudian untuk sumber data Contentful
biasanya untuk konten yang sifatnya abstrak yang hanya terdiri dari pargraf, gambar autupun code block
.
Prosesnya dapat dilihat pada blok kode berikut:
const composeBlogs = [...data?.allFile.edges, ...data?.allContentfulArticle.edges]
const blogsSort = composeBlogs.sort((a,b) => {
const current = a.node?.childMdx?.frontmatter?.publishedOn || a.node.createdAt
const next = b.node?.childMdx?.frontmatter?.publishedOn || b.node.createdAt
return current > next ? -1 : 1
})
Jadi yang pertama, kita gabungkan semua artikel baik dari mdx
maupun artikel dari Contentful, kemudian kita sorting berdasarkan tanggal pembuatan artikelnya.
<ul className="grid grid-cols-1 mt-12 sm:grid-cols-2 md:grid-cols-3 gap-8">
{
blogsSort.map(({node}, key) => {
if (key < 6) {
node?.childMdx?.frontmatter?.isPublished || node.isPublished ? (
<li key={key}>
<BlogItem data={node.childMdx || node}/>
</li>
) : null
}
})
}
</ul>
Dari hasil sorting tersebut baru kemudian kita iterate
menggunakan map
, setiap perulangan kita mengecek apakah artikel tersebut telah siap untuk dipublish.
Deployment
Sebelumnya saya menggunakan Github Page yang disediakan github secara gratis. Namun dengan pertimbangan akan menambahkan konten dari headless CMS yaitu Contentful, dan kebetulan baru-baru ini Cloudflare Pages menambahkan fitur webhooks, akhirnya saya memindahkan blog saya ke Cloudflare Pages.
Code Snippet
Yah ini mungkin termasuk bagian terpenting bagi seorang developer. Tidak ada blog yang sempurna tanpa adanya code snippet
.
Untuk code snippet, saya telah membuat sebuah plugin untuk menangani hal tersebut. Saya membuat plugin menggunakan libaray prism-react-renderer
dengan tambahan beberapa fitur.
Saya menggunakan Shipless Highlight dimana salah satu fiturnya adalah fitur highlight untuk kode yang ditambahkan dan dikurangi.
Dilain situasi, saya mempunya juga komponen yang berbeda, Shipless Play yaitu simple playground untuk HTML, CSS dan JS. Saya membuat playground ini menggunakan library @monaco-editor/react kemudian ditambahkan fitur component preview yang realtime.
Tool lainnya
- Styled Component: untuk styling
CSS in JS
- Framer Motion: untuk animasinya
- Tailwindcss: untuk tambahan utility di css
- Radix-UI: untuk komponen-komponen primitive
Ringkasan
Di era sekarang, kita memang dimanjakan dengan tool dan teknologi dengan banyaknya pilihan untuk membantu menyelesaikan pekerjaan kita. Salah satunya adalah Gatsbyjs yang merupakan framework react yang dapat membantu para pengembang front end dapat dengan mudah membangun website mereka dengan cepat serta memiliki performa yang lebih baik.
Gatsby dilengkapi dengan fitur plugin, yang memungkinkan kita mengintegrasikan dengan layanan-layanan lain. Dan ini salah satu alasan saya menggunakan Gatsby, dimana saya tidak ingin membuang waktu untuk melakukan sesuatu yang hal-hal dasar, seperti bagaimana menampilkan file mdx
di Gatsby. Yah, dengan memasang plugin dan menentukan lokasi filenya kita sudah dapat mengolah file md
.
Berbeda halnya ketika kita butuh kendali yang lebih banyak untuk kondisi tertentu. Tentu saya akan menggunakan framework lain seperti Nextjs, yang dapat menangani aplikasi yang leibh dinamis dan umumnya untuk proses integrasi dengan layanan lain memberikan banyak kendali sehingga kita leluasa mengatur sesuai keinginan kita.