title: Display images from aws s3 using react dropzone and multer S3
body: <p>Before switching to aws s3, my mern app was uploading and displaying images using react-dropzone and multer.  The image files were saved in a server-side 'uploads' folder. The app worked fine locally.</p>
  
  <p>My issue started once I deployed on Heroku.  For context, here's my live site:  <a href="https://famcloud.herokuapp.com/" rel="nofollow noreferrer">https://famcloud.herokuapp.com/</a></p>
  
  <p>Now that I've changed a few lines of code to store the files in the aws s3 bucket, my images aren't rendering.</p>
  
  <p>The good news is, through my console, I can see that the images are being uploaded and sent to the aws s3 bucket (as well as the Db).  So the issue is figuring out how to render them.  </p>
  
  <p>I'm stuck in tutorial hell with so many youtube videos and blog articles explaining how to upload files to aws, but can't seem to find the right guidance for displaying them.</p>
  
  <p>Well, I'll get to the code now.  </p>
  
  <p>Luckily, it's just two files where I'm missing something.  </p>
  
  <p>On the back-end side, my photo.js file in my Routes Folder looks like this:</p>
  
  <pre><code>const router = express.Router();
  const { Photo } = require("../../models/Photo");
  const multer = require('multer');
  const aws = require('aws-sdk');
  const multerS3 = require('multer-s3');
  const path = require('path');
  
  const { auth } = require("../../middleware/auth");
  
  
  
  const s3 = new aws.S3({
      accessKeyId: '',
      secretAccessKey: '',
      Bucket: 'famcloud2'
  });
  
  function checkFileType(file, cb) {
      // Allowed ext
      const filetypes = /jpeg|jpg|png|gif/;
      // Check ext
      const extname = filetypes.test(path.extname(file.originalname).toLowerCase());
      // Check mime
      const mimetype = filetypes.test(file.mimetype);
      if (mimetype &amp;&amp; extname) {
          return cb(null, true);
      } else {
          cb('Error: Images Only!');
      }
  }
  
  // Multiple File Uploads ( max 4 )
  const uploadsBusinessGallery = multer({
      storage: multerS3({
          s3: s3,
          bucket: 'famcloud2',
          acl: 'public-read',
          metadata: function (req, file, cb) {
              cb(null, { fieldName: file.fieldname });
          },
          key: function (req, file, cb) {
              cb(null, path.basename(file.originalname, path.extname(file.originalname)) + '-' + Date.now() + path.extname(file.originalname))
          }
      }),
      limits: { fileSize: 10000000 }, // In bytes: 2000000 bytes = 2 MB
      fileFilter: function (req, file, cb) {
          checkFileType(file, cb);
  
      }
  }).array('galleryImage', 4);
  
  
  router.post('/uploadMultiple', auth, (req, res) =&gt; {
      uploadsBusinessGallery(req, res, err =&gt; {
          console.log('file sent/saved to AWS: ', req.files);
          if (err) {
              return res.json({ success: false, err })
          }
          return res.json({ success: true, image: req.files.key, fileName: req.files.key })
      })
  
  });
  
  
  
  
  //Here's the front-end React Component file:
  
  import React, { useState } from 'react'
  import Dropzone from 'react-dropzone';
  import { CloudUploadOutlined } from '@ant-design/icons'
  import Axios from 'axios';
  
  
  function FileUpload(props) {
  
      const [Images, setImages] = useState([])
  
      const onDrop = (files) =&gt; {
  
      let formData = new FormData();
          const config = {
              header: {
                  'accept': 'application/json',
                  'Accept-Language': 'en-US,en;q=0.8',
                  'Content-Type': `multipart/form-data; boundary=${formData._boundary}`
              }
          }
          formData.append("galleryImage", files[0])
          //save the Image we chose inside the Node Server 
          Axios.post('/api/photo/uploadMultiple', formData, config)
              .then(response =&gt; {
                  if (response.data.success) {
  
                      setImages([...Images, response.data.image])
                      props.refreshFunction([...Images, response.data.image])
  
                  } else {
                      alert('Failed to save the Image in Server')
                  }
              })
  }
  
  
      const onDelete = (image) =&gt; {
          const currentIndex = Images.indexOf(image);
  
          let newImages = [...Images]
          newImages.splice(currentIndex, 1)
  
          setImages(newImages)
          props.refreshFunction(newImages)
      }
  
      return (
          &lt;div style={{ display: 'flex', justifyContent: 'space-between' }}&gt;
              &lt;Dropzone
                  onDrop={onDrop}
                  multiple={false}
                  maxSize={800000000}
  
              &gt;
                  {({ getRootProps, getInputProps }) =&gt; (
                      &lt;div className="uploadTarget"
                          style={{
                              width: '300px', height: '240px', border: '1px solid lightgray',
                              display: 'flex', alignItems: 'center', justifyContent: 'center',
                              backgroundColor: "rgba(1,1,1,0.3)", borderRadius: "10px"
                          }}
                          {...getRootProps()}
                      &gt;
                          &lt;input {...getInputProps()} /&gt;
                          &lt;CloudUploadOutlined style={{ fontSize: '5rem', cursor: "pointer" }} /&gt;
  
                      &lt;/div&gt;
                  )}
              &lt;/Dropzone&gt;
  
              &lt;div style={{ display: 'flex', width: '350px', height: '240px', overflowX: 'scroll' }}&gt;
  
                  {Images.map((image, index) =&gt; (
                      &lt;div onClick={() =&gt; onDelete(image)}&gt;
                          &lt;img style={{ minWidth: '300px', width: '300px', height: '240px' }} src={`http://localhost:5000/${image}`} alt={`photoImg-${index}`} /&gt;
                      &lt;/div&gt;
                  ))}
  
  
              &lt;/div&gt;
  
          &lt;/div&gt;
      )
  }
  
  export default FileUpload```
  
  
  
  
  
  </code></pre>