How to optimize images uploaded through Netlify CMS?

1.7k views Asked by At

I have a Hugo site and I'm using Netlify CMS to manage the content. Everytime the site builds, it runs a Gulp task that optimizes images from the src folder to the static folder. But, the problem is, when I upload an image through the CMS, it stores it in the static folder.

So, in the admin config.yml, should I set the media_folder to src/images instead?

My thinking is that the task will run and store the new minified image into the static folder but is that right? Or is there another way to do this?

Gulp task:

gulp.task('images', () => {
    return gulp.src('src/images/**/*.{png,jpg,jpeg,gif,svg,webp,ico}')
        .pipe($.newer('static/images'))
        .pipe($.print())
        .pipe($.imagemin([
            $.imagemin.jpegtran({progressive: true}),
            $.imagemin.optipng({optimizationLevel: 5}),
        ]))
        .pipe(gulp.dest('static/images'));
});

Admin config.yml

media_folder: "static/images"
public_folder: "images"
2

There are 2 answers

1
zivc On BEST ANSWER

In your content repository, you can make a build script (build & deploy if hosted on Netlify) and it can resize and optimise images and put them into a new folder anytime it detects new content. Most importantly, remove EXIF data such as Geolocation.

  const path = require('path');
  const gm = require('gm');
  const fs = require('fs-extra');
  const klaw = require('klaw');

  const mediaDir = path.resolve(__dirname, 'media');
  const imagesDir = path.resolve(__dirname, 'images');

  const sizes = [
     {size: 1280, rename: false},
     {size: 640, rename: true},
     {size: 320, rename: true},
  ];

  const imagesToProcess = [];

  (async () => {
     await fs.ensureDir(imagesDir);

     klaw(mediaDir)
        .on('data', (item) => {

           const stat = fs.lstatSync(item.path);
           const copyPath = path.resolve(imagesDir, path.basename(item.path));

           if (stat.isFile() && !fs.pathExistsSync(copyPath)) {

              imagesToProcess.push([item.path, copyPath]);

           }

        })
        .on('end', () => {

           imagesToProcess.reduce((promise, [originalImage, copyPath]) => {

              sizes.reduce((promise, sizeObject) => {

                 return promise.then(() => new Promise((resolve) => {

                    gm(originalImage)
                       .noProfile()
                       .resizeExact(sizeObject.size, sizeObject.size)
                       .quality(75)
                       .write(copyPath.replace('.jpg', `-${sizeObject.size}.jpg`), () => resolve());

                 }));

              }, promise);

           }, Promise.resolve());

        });

  })();
0
Seth Warburton On

Just configure Netlify CMS to upload files to a different location, i.e. a page bundle, then Hugo can take care of image optimisation natively.