⚠️ Work in progress — createCMS is pre-1.0 and not production-ready (not tested in production). Expect breaking changes.
createCMS

Media optimize

Client-side resize, compress, and WebP conversion before upload.

The media optimize plugin processes images in the browser before they are uploaded: it resizes, compresses, and optionally converts to WebP. This cuts bandwidth and storage with no server-side processing. It is a client-only plugin.

Installation

Add the client plugin

lib/cms-client.ts
import { createCMSClient } from '@createcms/core/react';
import { mediaOptimizeClient } from '@createcms/core/plugins/media-optimize';
import type { cms } from './cms';

export const cmsClient = createCMSClient<typeof cms>()({
  baseURL: '/api/cms',
  plugins: [
    mediaOptimizeClient({
      compress: { quality: 90 },
      resize: { maxSize: 2000 },
      convert: { format: 'webp', storeOriginal: true },
    }),
  ],
});

For WebP in browsers without native encoding (for example older Safari), also install the optional fallback:

npm install @jsquash/webp

Usage

The plugin adds an optimize namespace. Optimize files first, then hand the results to the upload hook:

function Uploader({ file }: { file: File }) {
  const { results } = cmsClient.optimize.useOptimize(file);
  const upload = cmsClient.media.useUploadAssets();

  // `results` is OptimizeResult[]; flatten to the File[] that upload expects.
  const files = (results ?? []).flatMap((r) =>
    r.originalVariant ? [r.file, r.originalVariant] : [r.file],
  );
  // upload.upload(files)
}

Pass a second argument to useOptimize to override the config for a single call. For a one-off outside React, use the standalone optimizeImage(file, config).

Options

All options are optional; omit a section to skip that step.

SectionFieldTypeDefaultDescription
enabledbooleantrueAuto-optimize on upload. Set false to register no auto-optimizer, so useUploadAssets().upload(...) sends the original bytes and you optimize manually with useOptimize / optimizeImage.
compressqualitynumber80JPEG/PNG quality, 1 to 100.
resizemaxSizenumber2000Max width or height in pixels (aspect ratio preserved).
convertformat'webp'Target format (only WebP is supported).
convertstoreOriginalbooleanfalseAlso keep a resized, compressed copy in the original format.

Failures

This plugin runs entirely in the browser, so there are no HTTP errors. When optimization fails, useOptimize surfaces it as an error string, and the standalone optimizeImage throws. Common causes are a failed WebP encode (the browser lacks native encoding and @jsquash/webp is not installed) or being unable to acquire a canvas 2D context.

On this page