Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to store files in production in Next.js?

I have a file exchange Next.js app that I would like to deploy. In development whenever a file is dropped, the app stores the file in root public folder, and when the file is downloaded the app takes it from there as well using the <a> tag with href attribute of uploads/{filename}. This all works pretty well in development, but not in production.

I know that whenever npm run build is run, Next.js takes the files from the public folder and the files added there at runtime will not be served.

The question is, are there any ways of persistent file storage in Next.js apart from third party services like AWS S3?

like image 618
Tymofii Koval Avatar asked Sep 08 '25 04:09

Tymofii Koval


2 Answers

next in node runtime is NodeJS, thus If your cloud provider allows create persistent disk and mount it to your project, then you can do it:

e.g. pages/api/saveFile.ts:

import { writeFileSync } from 'fs';
import { NextApiRequest, NextApiResponse } from 'next';

export default async function handler(req: NextApiRequest, res: NextApiResponse) {
    const { path = null } = req.query;
    if (!path) {
        res.status(400).json({ name: 'no path provided' })
    } else {
        // your file content here
        const content = Date.now().toString();
        writeFileSync(`/tmp/${path}.txt`, content);
        res.json({
            path,
            content
        })
    }
}

/tmp works almost in every cloud provider (including Vercel itself), but those files will be lost on next deployment; instead you should use your mounted disk path

pages/api/readFile.ts

import { readFileSync } from 'fs';
import { NextApiRequest, NextApiResponse } from 'next';

export default async function handler(req: NextApiRequest, res: NextApiResponse) {
    const { path = '' } = req.query;
    if (!path) {
        res.status(400).json({ name: 'wrong' })
    } else {
        res.send(readFileSync(`/tmp/${path}`));
    }
}

Live running example:

fetch('https://eaglesdoc.vercel.app/api/writefile?path=test')
.then(res => res.text()).then(res => console.log(res)).then( () => 
fetch('https://eaglesdoc.vercel.app/api/readfile?path=test'))
.then(res => res.text()).then(res => console.log(res))
like image 61
Mhmdrz_A Avatar answered Sep 10 '25 11:09

Mhmdrz_A


Next.js does allow file storage at buildtime, but not at runtime. Next.js will not be able to fulfill your file upload requirement. AWS S3 is the best option here.

like image 28
Matt Avatar answered Sep 10 '25 11:09

Matt