Beginilah bagaimana aku membuat blog dengan SvelteKit

Teknologi : #Svelte ‍ #SvelteKit ‍ #Markdown ‍ #Javascript ‍ #Vite ‍ 

Saturday, Mar 27, 2021

Oke. Mempertimbangkan isi catatan yang lebih singkat namun berbobot, dan tentu saja cacat verbal yang ku miliki. Mungkin mulai dari catatan ini hingga ke depannya, aku akan menjadi lebih to the point. Jadi, mari mulai.

Instal SvelteKit dulu lah

pnpm init svelte@next blog
cd blog
pnpm i

Oh iya. Ketika catatan ini dibuat versi SvelteKit ada di 1.0.0.next-61. Pada versi ini, ketika kita melakukan fresh init, tidak hanya Typescript support dan pilihan penulisan style saja yang ditawarkan. Namun ada juga penawaran untuk menggunakan ESlint dan Prettier. Mantap, aku mengambil yang Prettier saja

Hooks data postingan

Kamu ingin menyiapkan data berisi daftar post yang ada di direktori contens/post dan meta datanya, seperti judul dan deskripsi. Untuk itu kamu dapat menggunakan Hooks.

Hooks awalnya bernama Setup. Kamu membuat berkas opsional dengan nama src/hooks.js (atau src/hooks.ts, atau src/hooks/index.js). Jika kamu telah membuat berkas setup sebelumnya cukup ubah namanya menjadi hooks.

Jadi, mari buat berkas src/hooks.js supaya lebih sederhana.

export async function getSession() {
  const posts = await Promise.all(
    Object.entries(import.meta.glob('/contents/post/*.md')).map(async ([path, page]) => {
      const { default: post } = await page()
      const { body, image, ...attributes } = post
      const slug = path.split('/').pop().split('.').shift()
      return { slug, ...attributes }
    })
  )

  return {
    posts
  }
}

Oops, aku lupa memberitahu bahwa pada catatan ini blog yang dibuat akan menggunakan berkas Markdown alih-alih fetch API, tentu saja kamu dapat mengubah isi getSession() ini sesuai kebutuhan.

Satu lagi, alih-alih menggunakan fs milik Node untuk membaca berkas Markdown yang entah bisa atau tidak, aku membuat sebuah vite-plugin-markdown untuk ini.

Mari bahas kodenya.

  1. export async function getSession() {} mewajibkan untuk mengembalikan sebuah objek murni tanpa function yang akan diberikan kepada Browser menggunakan session setiap kali SvelteKit me-render sebuah halaman. Cek dokumentasi resminya.

  2. Object.entries(import.meta.glob('/contents/post/*.md')).map() akan membuat sebuah array berisi objek dari hasil dynamic import menggunakan Glob Import, ini adalah fitur dari Vite.

    Penjelasan di dokumentasi remsinya sangat sederhana dan mudah dipahami. import.meta.glob() akan mengembalikan sebuah array berbentuk objek.

  3. Karena menggunakan plugin tadi, maka hasil import akan mengembalikan array objek dari marked.js. Di contoh kode di atas, aku mengambil slug dari alamat file, dan attribut dari hasil import.

  4. Terakhir, aku mengembalikan objek berisi daftar post yang aku aku namai posts. Kamu dapat melakukan pengurutan data jika perlu, misalnya berdasarkan tanggal.

src/post/[slug].svelte

Kamu tentu sudah paham berkas ini digunakan untuk menangani alamat.web/post/judul-artikel. Di berkas ini, kamu dapat memanggil objek dari hooks dengan cara berikut

<script context="module">
  export async function load({ page, session }) {
    const slug = page.params.slug
    const slugs = session.posts
  
    if (!slugs.includes(slug)) {
      return {
        status: 404,
        error: 'Catatan seperti itu tidak ada'
      }
    }

    const posts = await import.meta.glob('../../../contents/post/*.md')
  
    return {
      props: { post }
    }
  }
</script>

<script>
  export let post
</script>

<h1>{post.title}</h1>
{@html post.body}

Bonus

Untuk menggunakan plugin yang tadi di index.svelte dan about.svelte maupun [slug].svelte malah lebih mudah lagi.

<script>
  import content from '../../contents/page/index.md'
</script>

<h1>{content.title}</h1>
{@html content.body}

Ada yang terlewat? Beri tanggapan ya...