Tutorial

Membuat Layout Gatsby Tampil Persisten

Yudy Ananda

Dalam sebuah aplikasi web seperti Gatsby biasanya ada komponen yang berfungsi sebagai tata letak. Sebut saja layout. Tujuannya sih sederhana yaitu untuk menghindari redundan dari kode yang seharusnya tidak perlu ditullis berulang kaliβ€”seperti header, footer dll.β€”di setiap bagian template halaman.

Singkat cerita berkat layout lah kita bisa mengimplementasikan DRY, tapi yang jadi pertanyaan apakah tata letak tersebut bisa tampil persisten? Maksud dari persisten di sini layout bisa tetap eksis tanpa unmounted dan render ulang ketika berpindah rute.

Tentu saja tidak!

Kenapa harus persisten?

Setiap pindah halaman Gatsby akan memuat ulang seluruh komponen yang berada dalam root-nya yaitu komponen dengan id ___gatsby. Hal tersebut memang normal dan memang fitrahnya sebuah Single Page Application, tapi dalam kasus tertentu perilaku seperti itu bisa pengalaman pengguna.

Contohnya adalah layout blog ini dengan menu navigasi versi mobile yang seharusnya bisa menutup dengan mulus ketika di-klik oleh pengguna, tapi karena di-unmounted maka transisinya akan terlihat jelek.

Itu hanyalah sebagian contoh dari kasus yang akan sering dijumpai. Intinya sih kalau tidak mau mengorbankan UX tentu kita harus punya cara untuk membuat perilaku re-render hanya terjadi pada komponen yang kita kehendaki.

Gatbsy API

Untungnya Gatsby punya wrapPageElement dan wrapRootElement. Keduanya merupakan API yang disediakan untuk menyelesaikan masalah seperti ini. Karena yang dibutuhkan adalah pembungkus komponen maka yang akan kita gunakan saat ini adalah wrapPageElement.

Sebelumnya pastikan project Gatsby mu punya layout yang membungkus konten utama seperti header dan footer di contoh berikut ini.

// Layout.js

import * as React from 'react';

export const Layout = ({ children }) => {
  return (
    <div className="wrapper">
      <header> logo, navigasi dll... </header>
      {children}
      <footer> kredit, navigasi dll... </footer>
    </div>
  );
};

Selanjutnya beri tahu Gatsby jika ada elemen dengan tipe layout maka perlakukan sebagai layout. Metode ini diimplementasikan melalui wrapPageElement di gatsby-browser.js dan gatsby-ssr.js.

// gatsby-browser.js & gatsby-ssr.js

import * as React from 'react';

export function wrapPageElement({ element, props }) {
  // Cek, apakah ada properti layout di halaman
  // jika eksis gunakan, tapi jika tidak
  // kembalikan saja sebagai fragment <>
  const Layout = element.type.Layout ?? React.Fragment;

  // Argumen props dengan operator spread digunakan
  // agar seluruh kueri dalam layout bisa diakses
  return <Layout {...props}>{element}</Layout>;
}

Langkah terakhir ikut sertakan layout dalam setiap template halaman, tapi alih-alih disematkan secara langsung dalam fungsi kita hanya mendefinisikannya sebagai komponen statis.


// pages/index.js

import * as React from "react";
import Layout from "../components/Layout";

const Beranda = () => {
    return (
        <div>...</div>
    )
}

// Kita beritahu Gatsby bahwa komponen Layout yang di import
// adalah tata letak yang disebutkan di fungsi wrapPageElement
Beranda.Layout = Layout
export default.Beranda;

Jalan ninja

Lagi buru-buru atau ingin jalan yang lebih praktis? Untuk urusan yang satu ini Gatsby punya official plugin bernama gatsby-plugin-layout. Fungsinya kurang lebih sama seperti yang kita lakukan dengan barisan kode di atas tadi.

Secara default plugin ini akan menggunakan layout yang disimpan di src/layouts/index.js, tapi kalau lokasi dan penamaan berbeda maka harus menambahkan konfigurasi tambahan di gatsby-config.js.

Untuk lebih lengkapnya bisa di lihat di sini.

Sum

Layout yang tampil persisten bisa memberikan nilai tambah untuk pengalaman pengguna yang lebih baik. Dalam project yang kompleks pembungkus tersebut bisa saja berbentuk context provider dari hooks atau state management seperti Redux. Bedanya API yang digunakan adalah wrapRootElement.

Ikon penanda buku
Javascript