Serving next.js static assets from public folder after build time problems #18005
-
I'm working on a nextjs application that should be deployed in a LAN, and the server is not connected to the internet. So the problem that I have is that in the As the application will be deployed in an offline server, I cannot use services like I've also tried serving them with Next application listen on
|
Beta Was this translation helpful? Give feedback.
Replies: 4 comments 13 replies
-
Try Minio for local Aws S3 |
Beta Was this translation helpful? Give feedback.
-
The Therefore you'd need to setup another endpoint using Node or similar server technology to be able to get/set objects on the servers filesystem outside of Next. |
Beta Was this translation helpful? Give feedback.
-
Hi, To anyone who is reading this thread looking for a solution to access files in the public folder at runtime but would prefer a simple solution that works with next you can do the following: Create a new folder: "./pages/api/public" import fs from "fs"
export default function handler(req, res) {
if (req.query.slug && req.query.slug.length) {
const publicDir = __dirname.split(".next")[0] + "public/"
const fileUrl = req.query.slug.join("/")
fs.readFile(publicDir + fileUrl, (error, data) => {
if(error) {
return res.status(404).send(null)
}
return res.status(200).send(data)
})
} else {
res.status(404).send(null)
}
} Now you can access the files in your public folder using "yourapplication:3000/api/public/*" You may need to slightly customize the code to your needs. Hope this helps anyone in need! :) |
Beta Was this translation helpful? Give feedback.
-
Next 14/15. Uploading and dynamically retrieving files in a folder /app/public. // Server action to Upload avatar to a folder: /public/images/avatar
// It is assumed to use upload image by input form with formData. I'm not considering it here.
// imgAPI.tsx
'use server'
import fs from 'node:fs/promises'
import path from 'path'
const publicFolder = path.resolve('public') // /app/public (on docker) and ./public (on local)
// newPath = '/images/avatar/1234567.jpg'
export async function uploadFile(newPath: string, formData: FormData) {
try {
if (!newPath) throw new Error('Download directory not specified')
const file = formData.get('file') as File
if (!file) throw new Error('Specify the correct file')
const arrayBuffer = await file.arrayBuffer()
const uint8Array = new Uint8Array(arrayBuffer)
await fs.writeFile(publicFolder + newPath, uint8Array)
} catch (err) {
console.error(' uploadFile: ', err)
if (err instanceof Error && err.message) return { msg: err.message }
return { msg: 'Error updating avatar' }
}
} // Create a route to dynamically getting a file from folder /public/images/avatar
// app/api/public/[[...slug]]/route.ts
import { promises as fs } from 'fs'
import { NextResponse } from 'next/server'
import path from 'path'
const publicFolder = path.resolve('public') // /app/public (on docker) and ./public (on local)
export async function GET(req: Request, { params }: { params: { slug?: string[] } }) {
try {
const slug = params.slug || [] // ["images", "avatar", "1234567.jpg"]
const filePath = slug ? path.join(publicFolder, ...slug) : null // /public/images/avatar/1234567.jpg
if (!filePath) throw new Error()
const fileContent = await fs.readFile(filePath)
if (!fileContent) throw new Error()
return new NextResponse(fileContent)
} catch (err) {
console.error(' GET Avatar | err: ', err)
return new NextResponse(null)
}
} // From the component we send a GET request ( '/api/public/images/1234567.jpg') to receive an avatar and display it
// app/components/Avatar.tsx
'use client'
import Image from 'next/image'
import { useState } from 'react'
type Props = {
avatar: string // from user session or DB '/images/avatar/1234567.jpg'
}
export function Avatar({avatar}: Props) {
if (!avatar) return null
const [err, setErr] = useState<string>('')
return (
<Image
src={err || `/api/public${avatar}`}
width={36}
height={36}
style={{ objectFit: 'cover' }}
alt='avatar'
className='avatar'
quality={100}
onError={() => setErr('/api/public/assets/no-image.png')}
/>
)
} |
Beta Was this translation helpful? Give feedback.
The
public
folder is not meant to dynamically set objects in it. After build it should not be altered.Therefore you'd need to setup another endpoint using Node or similar server technology to be able to get/set objects on the servers filesystem outside of Next.