2

I want to create a simple Nuxt 3 file upload implementation that stores the file in the locally in a folder in the Nuxt project. In PHP the server side code is very easy and straight forward but I am finding it difficult doing the same thing in Nuxt 3 server side.

  • In Nuxt, it's as easy. Check a tutorial on how to achieve that with Node.js or provide more effort regarding what you already tried. – kissu Oct 13 '22 at 10:53

2 Answers2

3

First:

npm install formidable

second:

define formidable in Nuxt config file inside modules list.

export default defineNuxtConfig({
modules: ["formidable"],
});

then in your handler for example upload.post.js :

import formidable from "formidable";
import fs from "fs";
import path from "path";

export default defineEventHandler(async (event) => {
  let imageUrl = "";
  let oldPath = "";
  let newPath = "";

  const form = formidable({ multiples: true });
  const data = await new Promise((resolve, reject) => {
    form.parse(event.req, (err, fields, files) => {
      if (err) {
        reject(err);
      }
      if (!files.photo) {
        resolve({
          status: "error",
          message: "Please upload a photo with name photo in the form",
        });
      }
      if (files.photo.mimetype.startsWith("image/")) {
        let imageName =
          Date.now() +
          Math.round(Math.random() * 100000) +
          files.photo.originalFilename;
        oldPath = files.photo.filepath;
        newPath = `${path.join("public", "uploads", imageName)}`;
        imageUrl = "./public/upload/" + imageName;
        fs.copyFileSync(oldPath, newPath);
        resolve({
          status: "ok",
          url: imageUrl,
        });
      } else {
        resolve({
          status: "error",
          message: "Please upload nothing but images.",
        });
      }
    });
  });
  return data;
});

don't forget to name the input field "photo" in the client side or change it here in every "files.photo". ALso the path of uploaded photos will be in public/uploads directory you can change it too if you like in "path.join" method. Good luck

kissu
  • 40,416
  • 14
  • 65
  • 133
Amr Shahba
  • 39
  • 4
1

I found a better alternative using https://github.com/wobsoriano/h3-formidable

import { readFiles } from 'h3-formidable';
import fs from "fs";
import path from "path";

export default defineEventHandler(async (event) => {
    const { files: { photo: [ { filepath, mimetype } ] } } = await readFiles(event, {
         includeFields: true
    });

    let imageName = String(Date.now()) + String(Math.round(Math.random() * 10000000));
    let newPath = `${path.join("public", "uploads", imageName)}.${ mimetype.split('/')[1] }`;
    fs.copyFileSync(filepath, newPath);

    return { success: true }
});