Next.js: production mode public folder can't access dynamically creating files

Created on 9 May 2020  路  10Comments  路  Source: vercel/next.js

Bug report

Describe the bug

thing happens when you switch from next dev to next start.
This is very confusing especially when you are dynamically creating files to the public folder and some pages are accessing them. Everything works fine in dev mode but fail in production mode

To Reproduce

Steps to reproduce the behavior, please provide code snippets or a repository:

  1. Go to npm run build & npm run start
  2. now createing a folder display in public folder and a file index.html in folder display
  3. can't access the index.html from http://localhost:3000/display/index.html
  4. but if you npm run dev you can access it as you do the same above
  5. This is very confusing

Expected behavior

A clear and concise description of what you expected to happen.

Screenshots

System information

  • OS: Windows
  • Browser chrome
  • Version of Next.js 9.3.4
  • Version of Node.js: 10.16.0

Additional context

Add any other context about the problem here.

Most helpful comment

You can send the file yourself using standard Node/connect helpers.

@Timer Can you please elaborate on this?

It seems like this would require opting out of the default Next.js server (which I'm not too keen on doing). Am I missing something obvious?

Looking at the next-server, this would require somehow registering the path into this set at runtime, and there is no such API exposed by Next.js? (Something like registerServeablePublicPath(filePath) which leaves it up to the developer to manually allow a path during runtime)

With the static regeneration, there are times where new files need to be created in public during runtime (manipulated/optimized images, parsed data and such) and this issue makes it a bit difficult/inconvenient.

All 10 comments

This is expected behavior as per https://github.com/zeit/next.js/releases/tag/v9.3.2. It's done to prevent accidentally leaking files that should not be accessed.

@timneutkens
Thanks for the response. If this is the expected behavior, I wonder what is the suggested way in next.js to serve dynamically created public files?

You can send the file yourself using standard Node/connect helpers.

You can use a custom express static live-server
https://nextjs.org/docs/advanced-features/custom-server

server.js

const express = require('express')
const next = require('next')

const port = parseInt(process.env.PORT, 10) || 3000
const dev = process.env.NODE_ENV !== 'production'
const app = next({ dev })
const handle = app.getRequestHandler()

app.prepare().then(() => {
  const server = express()

  server.use("/upload", express.static(__dirname + "/upload"));

  server.all('*', (req, res) => {
      return handle(req, res)
  })
  server.listen(port, (err) => {
    if (err) throw err
    console.log(`> Ready on http://localhost:${port}`)
  })

})

You can send the file yourself using standard Node/connect helpers.

@Timer Can you please elaborate on this?

It seems like this would require opting out of the default Next.js server (which I'm not too keen on doing). Am I missing something obvious?

Looking at the next-server, this would require somehow registering the path into this set at runtime, and there is no such API exposed by Next.js? (Something like registerServeablePublicPath(filePath) which leaves it up to the developer to manually allow a path during runtime)

With the static regeneration, there are times where new files need to be created in public during runtime (manipulated/optimized images, parsed data and such) and this issue makes it a bit difficult/inconvenient.

You can send the file yourself using standard Node/connect helpers.

@Timer Can you please elaborate on this?

It seems like this would require opting out of the default Next.js server (which I'm not too keen on doing). Am I missing something obvious?

Looking at the next-server, this would require somehow registering the path into this set at runtime, and there is no such API exposed by Next.js? (Something like registerServeablePublicPath(filePath) which leaves it up to the developer to manually allow a path during runtime)

With the static regeneration, there are times where new files need to be created in public during runtime (manipulated/optimized images, parsed data and such) and this issue makes it a bit difficult/inconvenient.

@Tenga ,
Would you please let me know if you find any workaround for the problem?
I tried the custom server way, but it ran unacceptably slow, and broke some of my code :(
I am building a small e-commerce site, and it is weird to restart server every time a picture is uploaded to public folder.

@animevn If I do, I will, but I haven't really dug into the problem anymore due to other work. I was hoping that @Timer or someone from the team would point us in the right direction before this becomes critical for us. 馃槃

From what I've seen, I don't really have much hope of us currently letting Next.js manually know that a certain file was intentionally added to public. And I'm not sure if Next.js team would be open an addition that was proposed above which focuses solely on the server mode.

It seems like either an intentional or unintentional oversight with regards to ISR and and server mode.

While I understand and support the decision to protect against accidental exposure, not having a way to add to that set manually and intentionally seems like straying away from the "pit of success". But it's easily sabotaged by self-recovery mechanisms that restart the server.

It leads people into things like, ejecting into custom servers, writing other custom serving logic and potentially introducing more problems, or intentionally restarting the server to bypass this check as the files get locked in memory at next start, or some other custom solutions that are more involved than necessary.

Hopefully I'm missing something here. 馃槃

@animevn If I do, I will, but I haven't really dug into the problem anymore due to other work. I was hoping that @Timer or someone from the team would point us in the right direction before this becomes critical for us. 馃槃

From what I've seen, I don't really have much hope of us currently letting Next.js manually know that a certain file was intentionally added to public. And I'm not sure if Next.js team would be open an addition that was proposed above which focuses solely on the server mode.

It seems like either an intentional or unintentional oversight with regards to ISR and and server mode.

While I understand and support the decision to protect against accidental exposure, not having a way to add to that set manually and intentionally seems like straying away from the "pit of success", and leads people into things like, ejecting into custom servers, writing other custom serving logic and potentially introducing more problems, or intentionally restarting the server to bypass this check as the files get locked in memory at next start, or some other custom solutions that are more involved than necessary.

Hopefully I'm missing something here. 馃槃

Dear @Tenga

Thank you for reply.

Currently, I have to resort to using nginx to serve static files in public/images/ (which is my public images folder) . That means next js server will have no role over my static images (though of course it still can upload and delete files in that public/images folder, but not serving these files)

Because I don't have much experience about next, would you please give me your advise, is that good or bad ?, I think next normally will cache all my files, if I let nginx do all the serving static images, will that break with next server?

Thank you and wish you a very nice weekend :D . Cheer

Currently, I have to resort to using nginx to serve static files in public/images/ (which is my public images folder) . That means next js server will have no role over my static images (though of course it still can upload and delete files in that public/images folder, but not serving these files)

Because I don't have much experience about next, would you please give me your advise, is that good or bad ?, I think next normally will cache all my files, if I let nginx do all the serving static images, will that break with next server?

Disclaimer: I don't think I'm the best person to give advice here. 馃槃

With that said, I don't believe Next.js does any caching or anything special with /public/ apart from:

I don't see anything _obviously_ wrong with your approach (assuming that is also not susceptible to directory traversal, and that you're not randomly putting sensitive files in that directory), and I don't believe it will break the next.js server (as those requests should not reach next.js server).

Thank you and wish you a very nice weekend :D . Cheer

You too! 馃憤

Faced the same problem. Was deeply disappointed. A very strange decision to make the public directory incomplete and with reduced functionality. I have to make a crutch for this. It is not clear what the developers were thinking while introducing this functionality. Wash the usual shortsightedness.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

swrdfish picture swrdfish  路  3Comments

olifante picture olifante  路  3Comments

DvirSh picture DvirSh  路  3Comments

YarivGilad picture YarivGilad  路  3Comments

jesselee34 picture jesselee34  路  3Comments