Hampir semua aplikasi web saat ini—baik CMS, e-commerce, hingga aplikasi admin—membutuhkan fitur upload file. Pada bagian ini, kamu akan belajar:
- Membuat form upload file di Next.js
- Menangani file di API route
- Menyimpan file secara lokal atau cloud (Cloudinary/S3)
- Menampilkan gambar dengan optimasi performa
🎯 Tujuan Part 9
- Mengupload file melalui form HTML
- Menangani file upload dengan API Route Next.js
- Menyimpan file ke server lokal atau cloud
- Menggunakan komponen
<Image />
dari Next.js untuk optimasi
📥 1. Form Upload Gambar di Next.js
Buat halaman app/dashboard/media/page.jsx
:
'use client';
import { useState } from 'react';
export default function UploadPage() {
const [file, setFile] = useState(null);
const [preview, setPreview] = useState('');
const handleUpload = async (e) => {
e.preventDefault();
const data = new FormData();
data.append('file', file);
const res = await fetch('/api/upload', {
method: 'POST',
body: data,
});
const result = await res.json();
alert(`Berhasil upload: ${result.filename}`);
};
return (
<form onSubmit={handleUpload} className="space-y-4">
<input
type="file"
accept="image/*"
onChange={(e) => {
setFile(e.target.files[0]);
setPreview(URL.createObjectURL(e.target.files[0]));
}}
/>
{preview && <img src={preview} alt="Preview" className="w-40 rounded" />}
<button type="submit" className="bg-blue-600 text-white px-4 py-2">
Upload
</button>
</form>
);
}
🧾 2. API Route: Menangani File Upload
Karena API Route di Next.js 13+ bersifat streaming dan tidak langsung support multipart/form-data
, kita perlu helper seperti formidable
atau parser manual.
a. Install formidable
npm install formidable
b. API route app/api/upload/route.js
import { writeFile } from 'fs/promises';
import path from 'path';
import { IncomingForm } from 'formidable';
export const config = {
api: {
bodyParser: false,
},
};
export async function POST(req) {
const form = new IncomingForm({ keepExtensions: true });
const uploadDir = path.join(process.cwd(), 'public', 'uploads');
const data = await new Promise((resolve, reject) => {
form.parse(req, async (err, fields, files) => {
if (err) return reject(err);
const file = files.file[0];
const buffer = await file.toBuffer();
const filePath = path.join(uploadDir, file.originalFilename);
await writeFile(filePath, buffer);
resolve({ filename: file.originalFilename });
});
});
return Response.json(data);
}
🔐 Upload file akan tersimpan di
/public/uploads/filename.jpg
☁️ 3. Upload ke Cloud (Cloudinary)
Untuk aplikasi production, simpan file di Cloudinary lebih aman dan scalable.
a. Install SDK
npm install cloudinary
b. Konfigurasi API
Tambahkan ke .env.local
:
CLOUDINARY_CLOUD_NAME=xxx
CLOUDINARY_API_KEY=xxx
CLOUDINARY_API_SECRET=xxx
c. Gunakan di route:
import { v2 as cloudinary } from 'cloudinary';
cloudinary.config({
cloud_name: process.env.CLOUDINARY_CLOUD_NAME,
api_key: process.env.CLOUDINARY_API_KEY,
api_secret: process.env.CLOUDINARY_API_SECRET,
});
const res = await cloudinary.uploader.upload(filePath);
📸 4. Menampilkan Gambar dengan Next.js <Image />
import Image from 'next/image';
<Image
src="/uploads/photo.jpg"
width={200}
height={200}
alt="Foto pengguna"
className="rounded"
/>
Keuntungan:
- Otomatis resize dan compress
- Lazy load bawaan
- Performa tinggi (CDN)
🧠 Best Practice Upload File
Aspek | Rekomendasi |
---|---|
Validasi file | Batasi tipe dan ukuran (jpg, png, max 2MB) |
Tempat penyimpanan | Gunakan folder public/uploads atau cloud |
Naming file | Gunakan UUID atau timestamp untuk unik |
Akses gambar | Beri prefix URL public, atau simpan di S3 |
Proteksi akses | Gunakan token/jwt untuk akses terbatas |
🧰 Elektra Network Vision – Solusi Upload & Media Web
Kami bantu Anda:
- Sistem upload gambar untuk e-commerce atau CMS
- Integrasi Cloudinary / Amazon S3
- Kompresi, resize, dan proteksi media
🌐 elektranetworkvision.com — Layanan Next.js profesional untuk aplikasi dan website bisnis Anda.