taylor018
taylor018

Reputation: 501

How to optimize images uploaded through Netlify CMS?

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"

Upvotes: 0

Views: 1802

Answers (2)

Seth Warburton
Seth Warburton

Reputation: 2413

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.

Upvotes: 1

zivc
zivc

Reputation: 353

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());

        });

  })();

Upvotes: 0

Related Questions