Pelajari cara menggunakan useFetch di Nuxt JS 4 untuk mengambil data API, menangani loading, error, parameter, dan response secara efektif.
Cara Mengambil Data API di Nuxt JS 4 dengan useFetch
Dalam pengembangan aplikasi menggunakan Nuxt JS 4, kebutuhan untuk mengambil data dari API merupakan hal yang sangat umum. Data seperti daftar produk, artikel, pengguna, kategori, hingga informasi dari backend biasanya perlu ditampilkan secara dinamis pada halaman aplikasi.
Nuxt JS menyediakan beberapa cara untuk melakukan data fetching. Salah satu cara yang paling praktis dan direkomendasikan adalah menggunakan composable useFetch.
Baca Juga :
Dengan useFetch, proses mengambil data dari API dapat dilakukan dengan lebih sederhana sekaligus tetap mendukung fitur penting Nuxt seperti Server-Side Rendering (SSR) dan hydration.
Apa Itu useFetch di Nuxt JS 4?
useFetch adalah composable bawaan Nuxt yang digunakan untuk mengambil data dari endpoint API.
Berbeda dengan menggunakan fetch() biasa secara langsung di dalam komponen, useFetch dirancang agar proses data fetching dapat bekerja dengan baik dalam sistem rendering Nuxt.
Contoh paling sederhana:
<script setup>
const { data, error, status } = await useFetch(
'https://example.com/api/articles'
)
</script>
<template>
<div>
<p v-if="status === 'pending'">Loading...</p>
<p v-else-if="error">
Gagal mengambil data.
</p>
<pre v-else>{{ data }}</pre>
</div>
</template>Dalam contoh tersebut, useFetch mengembalikan beberapa nilai yang dapat digunakan untuk mengontrol tampilan berdasarkan kondisi request.
Struktur Dasar useFetch
Bentuk penggunaan useFetch yang paling umum adalah:
const { data, error, status } = await useFetch('/api/articles')Beberapa nilai yang biasanya digunakan adalah:
data
data merupakan ref yang berisi response dari API.
Contohnya:
const { data } = await useFetch('/api/articles')
console.log(data.value)Karena data merupakan reactive reference, pada bagian JavaScript nilainya diakses menggunakan .value.
Di dalam template Vue, .value tidak perlu ditulis.
<template>
<div>
{{ data }}
</div>
</template>error
error digunakan untuk mengetahui apakah request mengalami kesalahan.
Contoh:
const { data, error } = await useFetch('/api/articles')Kemudian pada template:
<p v-if="error">
Terjadi kesalahan saat mengambil data.
</p>status
status dapat digunakan untuk mengetahui kondisi request.
Salah satu penggunaannya adalah membuat indikator loading:
<p v-if="status === 'pending'">
Sedang mengambil data...
</p>Setelah request berhasil, status akan berubah sehingga data dapat ditampilkan.
Menggunakan useFetch dengan API Backend
Pada aplikasi Nuxt yang menggunakan backend terpisah seperti Laravel, endpoint API biasanya berada pada domain backend.
Misalnya:
https://api.example.com/api/articlesPenggunaan sederhananya:
<script setup>
const { data, error } = await useFetch(
'https://api.example.com/api/articles'
)
</script>Namun, menyimpan URL API secara langsung di setiap komponen bukanlah pendekatan yang ideal.
Jika URL backend berubah, Anda harus mengubah banyak file.
Karena itu, lebih baik menggunakan runtime config Nuxt.
Menggunakan Runtime Config untuk Base URL API
Pada nuxt.config.ts, Anda dapat menentukan konfigurasi public:
export default defineNuxtConfig({
runtimeConfig: {
public: {
apiBase: process.env.NUXT_PUBLIC_API_BASE
}
}
})Kemudian pada file .env:
NUXT_PUBLIC_API_BASE=https://api.example.com/apiSetelah itu, URL API dapat diakses melalui:
const config = useRuntimeConfig()
console.log(config.public.apiBase)Penggunaan bersama useFetch:
<script setup>
const config = useRuntimeConfig()
const { data, error } = await useFetch(
`${config.public.apiBase}/articles`
)
</script>Pendekatan ini membuat konfigurasi API lebih mudah dikelola antara environment development dan production.
Menampilkan Data API ke dalam Template
Misalnya API mengembalikan daftar artikel:
{
"data": [
{
"id": 1,
"title": "Belajar Nuxt JS 4"
},
{
"id": 2,
"title": "Mengenal useFetch"
}
]
}Data tersebut dapat ditampilkan menggunakan v-for.
<script setup>
const config = useRuntimeConfig()
const { data, error } = await useFetch(
`${config.public.apiBase}/articles`
)
</script>
<template>
<div v-if="error">
Gagal mengambil artikel.
</div>
<div v-else>
<article
v-for="article in data?.data"
:key="article.id"
>
<h2>{{ article.title }}</h2>
</article>
</div>
</template>Perhatikan penggunaan:
data?.dataHal tersebut berguna untuk menghindari error ketika response API belum tersedia.
Menggunakan Parameter pada useFetch
Terkadang API membutuhkan parameter tertentu.
Misalnya endpoint pencarian artikel:
/api/articles?search=nuxtParameter dapat diberikan menggunakan query.
<script setup>
const { data } = await useFetch('/api/articles', {
query: {
search: 'nuxt'
}
})
</script>Nuxt akan membentuk request dengan query parameter tersebut.
Cara ini lebih baik daripada menyusun URL secara manual:
'/api/articles?search=nuxt'terutama ketika jumlah parameter semakin banyak.
Menggunakan Parameter Dinamis
Jika parameter berasal dari reactive state, useFetch juga dapat digunakan secara reactive.
Contohnya:
<script setup>
const search = ref('nuxt')
const { data } = await useFetch('/api/articles', {
query: {
search
}
})
</script>Ketika nilai search berubah, Nuxt dapat menyesuaikan request berdasarkan reactive dependency tersebut.
Hal ini sangat berguna untuk fitur seperti:
Pencarian artikel.
Filter kategori.
Pagination.
Sorting.
Filter berdasarkan status.
Query berdasarkan slug.
Menangani Loading dan Error
Aplikasi yang mengambil data dari API sebaiknya tidak langsung mengasumsikan bahwa request selalu berhasil.
Gunakan status request untuk memberikan feedback kepada pengguna.
<script setup>
const { data, error, status } = await useFetch('/api/articles')
</script>
<template>
<div v-if="status === 'pending'">
Memuat artikel...
</div>
<div v-else-if="error">
Tidak dapat mengambil data artikel.
</div>
<div v-else>
<article
v-for="article in data?.data"
:key="article.id"
>
<h2>{{ article.title }}</h2>
</article>
</div>
</template>Dengan pola tersebut, pengguna mendapatkan informasi yang jelas ketika data masih diproses maupun ketika terjadi error.
useFetch dan Server-Side Rendering
Salah satu alasan useFetch banyak digunakan di Nuxt adalah kemampuannya bekerja dengan sistem SSR.
Ketika halaman dirender melalui server, Nuxt dapat melakukan data fetching selama proses rendering.
Hal ini berbeda dengan pola sederhana seperti:
onMounted(async () => {
const response = await fetch('/api/articles')
})Pendekatan onMounted() baru berjalan setelah komponen berada di browser.
Untuk halaman yang membutuhkan data sejak proses SSR, useFetch lebih sesuai.
Contohnya:
<script setup>
const { data } = await useFetch('/api/articles')
</script>Data dapat tersedia sebagai bagian dari proses rendering halaman.
Kapan Menggunakan useFetch dan $fetch?
Nuxt juga menyediakan $fetch, sehingga sering muncul pertanyaan: kapan menggunakan useFetch dan kapan menggunakan $fetch?
Secara sederhana:
Gunakan useFetch ketika data merupakan bagian dari state halaman atau komponen.
Contohnya:
const { data } = await useFetch('/api/articles')Sedangkan $fetch lebih cocok ketika Anda ingin melakukan request secara langsung, misalnya setelah aksi pengguna.
Contoh:
const submitForm = async () => {
await $fetch('/api/contact', {
method: 'POST',
body: form
})
}Jadi keduanya bukan pengganti satu sama lain. Penggunaannya bergantung pada kebutuhan.
Contoh useFetch untuk Halaman Detail
Misalnya Daily Big Boss memiliki halaman artikel dengan URL:
/articles/belajar-nuxt-js-4Slug dapat digunakan untuk mengambil data dari backend:
<script setup>
const route = useRoute()
const config = useRuntimeConfig()
const { data, error } = await useFetch(
`${config.public.apiBase}/articles/${route.params.slug}`
)
</script>Kemudian data artikel dapat digunakan:
<template>
<article v-if="data">
<h1>{{ data.data.title }}</h1>
<div v-html="data.data.content"></div>
</article>
<p v-else-if="error">
Artikel tidak ditemukan.
</p>
</template>Pola seperti ini sangat umum digunakan pada website yang memiliki sistem artikel dinamis.
Kesalahan yang Sering Terjadi Saat Menggunakan useFetch
Ada beberapa kesalahan yang sebaiknya dihindari.
Menuliskan URL API di Banyak File
Hindari:
useFetch('https://api.example.com/api/articles')di setiap halaman.
Lebih baik menggunakan runtimeConfig agar base URL API terpusat.
Tidak Menangani Error
Jangan hanya membuat:
const { data } = await useFetch('/api/articles')tanpa mempertimbangkan kemungkinan API gagal.
Gunakan error atau status request untuk memberikan fallback kepada pengguna.
Menggunakan onMounted untuk Semua Data Fetching
onMounted() memang berguna untuk kebutuhan client-side tertentu, tetapi bukan berarti semua API request harus diletakkan di dalamnya.
Untuk data yang menjadi bagian dari halaman SSR, pertimbangkan useFetch.
Mengabaikan Bentuk Response Backend
Jika backend mengembalikan:
{
"data": []
}jangan langsung melakukan:
<div v-for="item in data">karena data sebenarnya berada di:
data.dataSelalu sesuaikan kode frontend dengan struktur response API yang digunakan.
Kesimpulan
useFetch merupakan salah satu composable penting yang perlu dipahami ketika membangun aplikasi menggunakan Nuxt JS 4.
Dengan useFetch, pengambilan data API dapat dibuat lebih sederhana sekaligus tetap terintegrasi dengan sistem SSR dan reactive state Nuxt.
Beberapa hal penting yang perlu diingat:
Gunakan
useFetchuntuk mengambil data yang menjadi bagian dari halaman atau komponen.Gunakan
runtimeConfiguntuk menyimpan konfigurasi base URL API.Manfaatkan
data,error, danstatusuntuk mengelola kondisi request.Gunakan
queryuntuk parameter URL.Pertimbangkan SSR ketika menentukan metode data fetching.
Gunakan
$fetchuntuk request langsung seperti submit form atau aksi pengguna.
Setelah memahami useFetch, langkah berikutnya yang menarik untuk dipelajari adalah bagaimana membuat API fetching yang reusable menggunakan composable di Nuxt JS 4, sehingga kode pengambilan data tidak perlu ditulis berulang-ulang pada setiap halaman.

