Hampir semua aplikasi web saat ini—baik CMS, e-commerce, hingga aplikasi admin—membutuhkan fitur upload file. Pada bagian ini, kamu akan belajar:


🎯 Tujuan Part 9


📥 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:


🧠 Best Practice Upload File

AspekRekomendasi
Validasi fileBatasi tipe dan ukuran (jpg, png, max 2MB)
Tempat penyimpananGunakan folder public/uploads atau cloud
Naming fileGunakan UUID atau timestamp untuk unik
Akses gambarBeri prefix URL public, atau simpan di S3
Proteksi aksesGunakan token/jwt untuk akses terbatas

🧰 Elektra Network Vision – Solusi Upload & Media Web

Kami bantu Anda:

🌐 elektranetworkvision.com — Layanan Next.js profesional untuk aplikasi dan website bisnis Anda.

Leave a Reply

Your email address will not be published. Required fields are marked *