Next.js public images not showing in production build
Asked Answered
H

6

11

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

components
pages
public
Homer answered 1/3, 2021 at 18:51 Comment(8)
How are you deploying to heroku? Maybe the server is blocking that traffic?Cocci
@Cocci through the cli. I also have a favicon in that public folder that is working. Just the .png images are notHomer
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.com/vercel/next.js/discussions/14121Cocci
@Cocci 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.Homer
added some (kinda) concrete instruction below.Cocci
I am currently experiencing the same issue with firebase hosting at the moment Have you been able to find a solution to this issue?Aubine
I am experiencing this issue even when I try to run in local system using next start it still doesn' loadSleeping
Any resolutions on this guys?Sleeping
C
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.

Cocci answered 3/3, 2021 at 14:35 Comment(5)
what solution with you proffer for someone using firbase functions and hosting been battling this issue for days nowAubine
@vincentO Create another post and refer to it here.Cocci
@vincentO Have you found any solution to this? I just bumped into this problem and don't know how to solve it.Harmonie
save images in another directoryNicolenicolea
what do you mean by another directory @NicolenicoleaAubine
A
1

I was having this same problem. For me the issue was not the components 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 compiled 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 components 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.

Acarid answered 16/11, 2021 at 23:35 Comment(4)
I still didn't understand what you said. For me when running yarn start after yarn build images are disappearingSleeping
If this only happens when you run build but not when you run yarn dev then it might be the same problem. I think that build only bundles the packages under dependencies but not devDependencies. I'm not a nextjs expert, but as a temporary quick test you could try moving all your devDependencies into dependencies and test if that works. (This is just for testing. Not a great solution for production)Acarid
Hmm even if it works but bundling up dev dependencies for production isn't a good thing right?Sleeping
> as a temporary quick test... (This is just for testing. Not a great solution for production)Acarid
S
0

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>.com',
        port: '',
        pathname: '/images/**',
      },
    ],
  },

Re-upload your project and restart all dynos

Saintjust answered 6/11, 2023 at 21:48 Comment(0)
N
-1

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

Nicolenicolea answered 28/6, 2021 at 18:33 Comment(0)
D
-1

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.

Diluvium answered 2/2, 2022 at 0:57 Comment(0)
G
-1

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

Gallant answered 11/10, 2022 at 3:13 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.