最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Next.js public images not showing in production build - Stack Overflow

programmeradmin2浏览0评论

I have a Next.js app I am deploying to Heroku. When I dev locally I see the images, but when I push to Heroku and check the site, the images have a 404. I have a public folder where I have the images (.png) right in the folder, and the code I reference the image like this

<Image
    src="/wb_blue_white.png"
    alt="WB Concept"
    width="70"
    height="70"
    className={navStyles.logo}
/>

Both locally and in prod the if I look at the image source they are the same src="/_next/image?url=%2Fwb_blue_white.png&w=256&q=75" but I get a 404 in prod. What could be causing the image to show up localhost but not in Heroku prod build?

package.json

"scripts": {
    "dev": "next dev",
    "build": "next build",
    "start": "next start -p $PORT"
},

file structure

ponents
pages
public

I have a Next.js app I am deploying to Heroku. When I dev locally I see the images, but when I push to Heroku and check the site, the images have a 404. I have a public folder where I have the images (.png) right in the folder, and the code I reference the image like this

<Image
    src="/wb_blue_white.png"
    alt="WB Concept"
    width="70"
    height="70"
    className={navStyles.logo}
/>

Both locally and in prod the if I look at the image source they are the same src="/_next/image?url=%2Fwb_blue_white.png&w=256&q=75" but I get a 404 in prod. What could be causing the image to show up localhost but not in Heroku prod build?

package.json

"scripts": {
    "dev": "next dev",
    "build": "next build",
    "start": "next start -p $PORT"
},

file structure

ponents
pages
public
Share Improve this question edited Mar 1, 2021 at 19:03 juliomalves 50.3k23 gold badges177 silver badges168 bronze badges asked Mar 1, 2021 at 18:51 ChipeChipe 4,81110 gold badges39 silver badges65 bronze badges 8
  • How are you deploying to heroku? Maybe the server is blocking that traffic? – Hiro Commented Mar 1, 2021 at 18:56
  • @Hiro through the cli. I also have a favicon in that public folder that is working. Just the .png images are not – Chipe Commented Mar 1, 2021 at 19:06
  • What buildpack did you use? Probably auto detected as node app? then it seems like nextjs uses built-in(?) express server to serve content. In that case, is the express static serve configured? Like this: github./vercel/next.js/discussions/14121 – Hiro Commented Mar 1, 2021 at 19:17
  • @Hiro I was thinking it was something like that. I created the project using create-next-app which might use built in express server? I am not sure about that. Very new to next trying to learn it as I go along. So not sure where I would add the reference to use the path.join. I think next produces the server file when you build the project. – Chipe Commented Mar 1, 2021 at 20:24
  • added some (kinda) concrete instruction below. – Hiro Commented Mar 3, 2021 at 14:36
 |  Show 3 more ments

6 Answers 6

Reset to default 2

Check out next custom server doc and its example repo.

Here in this express-looking code that's used to configure the server, app.render() seems to be setting routes for nextjs page, i.e. /a to pages/a. I'm not sure if that's even needed for each path or done for demo purpose. Try fiddling around.

Anyway, if it's anything like basic express server, which I suspect, use() method on express instance will add a "middleware", which 1. takes the request and 2. passes it to next middleware, or sends the response to client.

With server.use(express.static(path.join(__dirname, 'public')));, where server is the express instance in this case and fortunately(convention actually) in the example repo as well, you can add the middleware that handles static files serve.

I've forgotten the exact way of configuring express, but i'm guessing either:

  • right after the express() instantiation, or
  • right before the listen()

should do the trick. Just put server.use(express.static(path.join(__dirname, 'public'))) in there.

I was having this same problem. For me the issue was not the ponents at all. I was hosting my site on Netlify, and I didn't realize that by default Netlify builds the devDependencies. So node packages for development/testing were accidentally getting piled for production.

I changed the NODE_ENV (in Netlify) to production and reorganized the packages between dependencies and devDependencies... and the error went away.

I think that the ponents triggered this issue because the initial request(s) cause them to be generated/optimized server-side. So even though the build succeeded. The remote image request caused dev packages to run in the wrong context.

I hope this someday helps someone else.

Save your images in the public directory, e.g. public/images.

Then add this in your next.config.js file

images: {
      {
        protocol: 'http',
        hostname: 'localhost',
        port: '3000',
        pathname: '/images/**',
      }, 
      {
        protocol: 'https',
        hostname: '<YOUR SITE URL>.',
        port: '',
        pathname: '/images/**',
      },
    ],
  },

Re-upload your project and restart all dynos

Create a directory for images in the root folder and import, relatively, from there. Does the trick.

There are several articles on this, but basically Sharp is required and should be installed. The wording in the NextJS docs makes it sound optional, but with the default loader, Sharp is required.

In my case I had public folder in .dockerignore and all static assets were ignored as the result. Hope it might help someone.

发布评论

评论列表(0)

  1. 暂无评论