NextJS 13

NextJS

26 December 20225 min
NextJS 13

Dynamic without limit

Vercel telah merilis NextJS versi 13 pada saat konferensi Next.js Conf di San Francisco, 25 Oktober 2022. Beberapa update yang menarik diantaranya app directory, perubahan data fetching, server dan client components, serta hal lainnya. Namun NextJS versi 12 masih bisa digunakan dan setidaknya kita tidak perlu me-rewrite 10k+ baris code untuk sementara waktu.

Routing

Untuk dokumentasi bisa dibaca di Routing Fundamentals. Di NextJS 12 kita mendefinisikan route di pages directory. Halaman index.js sudah menjadi / atau root. Jika ingin membuat route, contoh: /about; kita hanya perlu membuat file baru di pages dengan nama file about.js dan diisi dengan components biasa.

Pages directory

NextJS 13, memperkenalkan app directory, struktur baru yang membuat project lebih terorganisir. Alih-alih menggunakan page, route kita berada di app directory.

App directory

Saya akan menjelaskan fungsi ketiga file tersebut:

  • head.js

    Seperti namanya, file ini digunakan untuk mendefinisikan tag head html. Kita bisa memasukkan cdn, title, favico, meta, dan lain-lain dengan return harus react fragment </>. Isi file kurang lebih seperti ini.

    export default function head() {
      return (
        <>
          <meta charSet="UTF-8" />
          <link rel="shortcut icon" href="/icon.png" type="image/x-icon" />
          <title>Posts</title>
        </>
      );
    }
    
  • layout.js

    Pada app directory, kita wajib membuat file layout.js sebagai root dari react components. Berisi tag html dan body sebagai tempat components akan di-mount nanti.

    export default function RootLayout({ children }) {
      return (
        <html lang="en">
          <body>{children}</body>
        </html>
      );
    }
    
  • page.js

    File yang berisi jsx atau react component. Jika kita punya halaman landing page atau about page maka di sini-lah tempat kita menuliskan html.

    export default function page() {
      return (
        <div>
          <h1>Hello World</h1>
        </div>
      );
    }
    

Bagaimana dengan nested route? mari lihat perbandingan pages dan app dengan studi kasus kita membuat route /products/{id}. {id} karena akan berisi id yang berbeda tiap produk.

NextJS 12:

// 12
pages
├── index.js
└── products
    └── [id].js

NextJS 13:

// 13
app
├── head.js
├── layout.js
├── page.js
└── products
    └── [id]
        └── page.js

Ada beberapa keuntungan app seperti kita bisa melakukan Loading UI loading.js dan Error Handling error.js. Selengkapnya bisa dibaca di Routing Fundamentals.

Data Fetching

fetching data di NextJS 13 sangat sederhana kita hanya perlu membuat function lalu memanggilnya langsung seperti native. Namun, sebelumnya kita perlu paham tentang client dan server components.

async function fetchData() {
  const options = {
    cache: 'force-cache', // default
          // 'no-store'
  }

  const res = await fetch('https://...', options);
  return res.json();
}

async function page() {
  const data = await fetchData();
  return (
    {/*processing data*/}
  )
}
  • force-chace hanya akan dijalankan ketika di-build atau mekanisme ini mirip seperti getStaticProps.
  • no-store dijalankan setiap request. mirip seperti getServerSideProps.

ada 1 lagi, yaitu:

  • revalidate. Kombinasi SSG dan SSR, ketika kita ingin fetch saat build dan pada kondisi tertentu halaman akan re fetch pada proses request SSR, bukan di client CSR.

    const options = {
      next: { revalidate: 10 }, // pada SSR akan refetch setiap 10 detik
    };
    

Dikarenakan page.js adalah server component by default, jadi kita bisa mengakses langsung database.

export const revalidate = 3600; // jika ingin revalidate

async function getAllUsers() {
  const user: User[] = await primsa.user.findMany();
  return user;
}

async function page() {
  const users: User[] = await getAllUsers();

  return (
    {/*processing data*/}
  )
}

Jika kita mempunyai dynamic route dan ingin men-generate HTML ketika di build, kita bisa menggunakan generateStaticParams. Di versi sebelumnya, proses ini mirip seperti getStaticPaths.

// app/blog/[articleSlug]/page.js
export default function Page({ params }) {
  const { articleSlug } = params;

  return ...
}

export async function generateStaticParams() {
  const posts: Post[] = await getPosts();

  const params  = posts.map((post) => ({
    articleSlug: post.slug,
  }));

  return params
}

@next/font

Font system baru NextJS memiliki banyak keuntungan, seperti optimasi, remove external request, self hosting font, dan yang lainnya. Fitur yang saya suka kita bisa menggunakan Google Fonts dengan performa dan privasi. CSS dan file font akan didownload ketika build. No requests are sent to Google by the browser.

import { Roboto } from '@next/font/google';
const roboto = Roboto({ weight: '700' });

<h1 className={roboto.className}>

Atau jika kita ada custom fonts, NextJS sudah mensuport self hosting, caching, dan preloading font files.

import localFont from '@next/font/local';

const aksara = localFont({ src: './aksara.woff2' });

<html className={aksara.className}>

Masih banyak lagi tentang update Next JS yang bisa dilihat langsung ke Dokumentasi resmi yang saat artikel ini ditulis masih beta version. Seluruh fitur di sini masih beta, jadi beberapa tidak direkomendasikan ke production. Fitur di versi sebelumnya masih bisa digunakan bersamaan dengan experimental fitur terbaru.

Six years ago, we released Next.js to the public. We set out to build a zero-configuration React framework that simplifies your developer experience. Looking back, it's incredible to see how the community has grown, and what we've been able to ship together. Let's keep going.