[Fixed] NodeJs: Serve image, stored on AWS S3, to client img tag


I have a server and a react client running on Heroku. All files are stored on AWS S3. Since the files are private and auth needs to be checked, I am planning to fetch the URL via the server and rerouting URL to the client.

Thus, on the client side:

<img style={{maxHeight: '10vh', width:'auto'}} src=`https://localhost:3000/api/files/${usr_id}/${filename}`/>

Note that the img is only one example, but I do have other data types on AWS (such as pdf), for which it should work just as well.

On the server side the source from the client is supposed to directly return the image (or other data) via a signed URL from AWS. I have the first part, which fetches the signed URL and works well. But can not figure out, how to return the URL to the client so that the image would display properly.

Server side code (simplified):

  router.get('/:user/:filename', async (req, res) => {
    try {
        const url = s3.getSignedUrl('getObject', {
          Bucket: BUCKET_NAME, 
          Key: filename,
          Expires: 60 * 1,
        console.log(url) // This works well and the image can be viewed in browser when copying the url
        // And now... ?
        // How do I return the signed URL to the image in the client?

    } catch (err) {
      res.status(500).json({ message: 'Something went wrong.' });

thanks in advance,


<img> tags can follow redirects, for example, to respond with a png URL, you can do:

res.redirect(301, "/image.png");

where the last param, "/image.png" is the new URL,

here is a working example, my server.js:

let express = require("express");

let app = express();

app.set("view engine", "ejs");

app.get("/", (req, res) => {

app.get("/api/files/*", (req, res) => {
  let newURL = "/image.png";
  res.redirect(301, newURL);


my view at home.ejs:

<h1>Hello World!</h1>

<!-- this path/file doesn't exist -->
<img src="/api/files/hello-world.png" alt="my image" />

Leave a Reply

(*) Required, Your email will not be published