Skip to content

Instantly share code, notes, and snippets.

@ndpniraj
Created November 17, 2022 10:16
Show Gist options
  • Save ndpniraj/2735c3af00a7c4cbe50602ffe6209fc3 to your computer and use it in GitHub Desktop.
Save ndpniraj/2735c3af00a7c4cbe50602ffe6209fc3 to your computer and use it in GitHub Desktop.
import { NextApiHandler, NextApiRequest } from "next";
import formidable from "formidable";
import path from "path";
import fs from "fs/promises";
export const config = {
api: {
bodyParser: false,
},
};
const readFile = (
req: NextApiRequest,
saveLocally?: boolean
): Promise<{ fields: formidable.Fields; files: formidable.Files }> => {
const options: formidable.Options = {};
if (saveLocally) {
options.uploadDir = path.join(process.cwd(), "/public/images");
options.filename = (name, ext, path, form) => {
return Date.now().toString() + "_" + path.originalFilename;
};
}
options.maxFileSize = 4000 * 1024 * 1024;
const form = formidable(options);
return new Promise((resolve, reject) => {
form.parse(req, (err, fields, files) => {
if (err) reject(err);
resolve({ fields, files });
});
});
};
const handler: NextApiHandler = async (req, res) => {
try {
await fs.readdir(path.join(process.cwd() + "/public", "/images"));
} catch (error) {
await fs.mkdir(path.join(process.cwd() + "/public", "/images"));
}
await readFile(req, true);
res.json({ done: "ok" });
};
export default handler;
import { GetServerSideProps, NextPage } from "next";
import { useState } from "react";
import axios from "axios";
import fs from "fs/promises";
import path from "path";
import Link from "next/link";
interface Props {
dirs: string[];
}
const Home: NextPage<Props> = ({ dirs }) => {
const [uploading, setUploading] = useState(false);
const [selectedImage, setSelectedImage] = useState("");
const [selectedFile, setSelectedFile] = useState<File>();
const handleUpload = async () => {
setUploading(true);
try {
if (!selectedFile) return;
const formData = new FormData();
formData.append("myImage", selectedFile);
const { data } = await axios.post("/api/image", formData);
console.log(data);
} catch (error: any) {
console.log(error.response?.data);
}
setUploading(false);
};
return (
<div className="max-w-4xl mx-auto p-20 space-y-6">
<label>
<input
type="file"
hidden
onChange={({ target }) => {
if (target.files) {
const file = target.files[0];
setSelectedImage(URL.createObjectURL(file));
setSelectedFile(file);
}
}}
/>
<div className="w-40 aspect-video rounded flex items-center justify-center border-2 border-dashed cursor-pointer">
{selectedImage ? (
<img src={selectedImage} alt="" />
) : (
<span>Select Image</span>
)}
</div>
</label>
<button
onClick={handleUpload}
disabled={uploading}
style={{ opacity: uploading ? ".5" : "1" }}
className="bg-red-600 p-3 w-32 text-center rounded text-white"
>
{uploading ? "Uploading.." : "Upload"}
</button>
<div className="mt-20 flex flex-col space-y-3">
{dirs.map((item) => (
<Link key={item} href={"/images/" + item}>
<a className="text-blue-500 hover:underline">{item}</a>
</Link>
))}
</div>
</div>
);
};
export const getServerSideProps: GetServerSideProps = async () => {
const props = { dirs: [] };
try {
const dirs = await fs.readdir(path.join(process.cwd(), "/public/images"));
props.dirs = dirs as any;
return { props };
} catch (error) {
return { props };
}
};
export default Home;
@ethmore
Copy link

ethmore commented Jun 15, 2023

I've tried so many different things, but this was the only one that works. Thank you!

@hasnainmalikqf
Copy link

I struggled two days for storing images. I used several ways like multer and other but multer was not working as expected. Your tutorial gave me right direction. Thanks God bless you.

@adarshmishra96
Copy link

Bruh you the best

@VivekGupta011
Copy link

"Great work, brother! You've really outdone yourself."
I had given full two days, still it could not be done but your code worked...
๐—œ ๐—ท๐˜‚๐˜€๐˜ ๐˜„๐—ฎ๐—ป๐˜ ๐˜๐—ผ ๐—ธ๐—ป๐—ผ๐˜„ ๐˜„๐—ต๐—ถ๐—ฐ๐—ต ๐—ฟ๐—ฒ๐˜€๐—ผ๐˜‚๐—ฟ๐—ฐ๐—ฒ(documentation) ๐˜†๐—ผ๐˜‚ ๐˜‚๐˜€๐—ฒ๐—ฑ, ๐—ฐ๐—ฎ๐—ป ๐˜†๐—ผ๐˜‚ ๐—ฝ๐—น๐˜‡ ๐˜€๐—ต๐—ฎ๐—ฟ๐—ฒ ?

@VivekGupta011
Copy link

why my images not working in production just after npm run build but working in development in next js using formidable?

image problem

@mhdizmni
Copy link

why my images not working in production just after npm run build but working in development in next js using formidable?

image problem

same issue

@dzkfzn
Copy link

dzkfzn commented Aug 23, 2023

Your code looks good, I will try it right now!

@dzkfzn
Copy link

dzkfzn commented Aug 23, 2023

Ok LGTM, Thanks

@chineduogbo
Copy link

Thank you i have done a lot of things to get this working seeing how easy i can do that in dotnet

@NikolaosKantartzopoulos
Copy link

Thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment