Performance 5 min read

How SleekCMS Handles Image Optimization (And Why You Probably Don't Need a Separate Service)

Image optimization consistently tops the list of Core Web Vitals improvements — and consistently requires a Cloudinary account, a framework image component, or a manual CDN transform layer. SleekCMS handles it at the platform level, via URL parameters.

April 14, 2026
A close-up view of a laptop displaying a search engine page.

The image problem in headless CMS

Image optimization is consistently one of the top contributors to poor Core Web Vitals scores. It's also one of the most tooling-heavy problems in a typical web project. The solutions — Cloudinary, Imgix, Next.js <Image>, <picture> with srcset — each solve the problem but add a dependency, a subscription cost, or a configuration surface.

For a headless CMS, the problem is specific: the CMS gives you image URLs. Serving those images at the right size, in the right format, for the right device is your problem. That usually means a third-party image CDN, a framework-level image component, or a manual transform layer wired up separately.

SleekCMS handles this at the platform level — image transformation via URL query parameters, built into every image asset.

The URL parameter API

Every image uploaded to SleekCMS has a CDN-backed URL. Appending query parameters transforms the image before delivery:

https://cdn.sleekcms.com/images/IMAGE_ID.jpg?w=1200&h=600&fit=cover&fmt=webp&q=85

No API call, no SDK, no configuration — just query parameters on the image URL.

Supported parameters:

Parameter Description Example values
w Width in pixels 400, 1200, 1920
h Height in pixels 300, 600, 1080
s Combined size shorthand (WxH) 1200x600, 400x300
fit Crop/resize mode cover, contain, fill
fmt Output format webp, jpg, png
q Quality (1–100) 85, 70, 40
dpr Device pixel ratio 2, 3
blur Gaussian blur radius 10, 20

The EJS helper functions

In SleekCMS templates, you don't typically construct these URLs by hand. The built-in helper functions handle it:

src(image, attr) — returns the transformed URL:

<img src="<%- src(item.cover, '1200x600') %>" alt="<%= item.cover.alt %>">

img(image, attr) — renders a complete <img> element with correct src, alt, width, and height:

<%- img(item.cover, '1200x600') %>

picture(image, attr) — renders a <picture> element with dark/light variant support and responsive source sets:

<%- picture(item.hero_background, { w: 1920, h: 800, fit: 'cover' }) %>

svg(image, attr) — renders an inline SVG for icon fields:

<%- svg(item.logo, { class: 'h-8 w-auto' }) %>

The attr parameter accepts either a "WxH" string for quick sizing or a full object for precise control:

<%- img(item.avatar, { w: 64, h: 64, fit: 'cover', class: 'rounded-full' }) %>

Common patterns

Blog hero image — full width, WebP, high quality:

<%- img(item.cover, { w: 1200, h: 630, fit: 'cover', fmt: 'webp', q: 90 }) %>

Thumbnail in a card grid — small, fast:

<%- img(post.cover, { w: 400, h: 250, fit: 'cover', fmt: 'webp', q: 75 }) %>

Author avatar — small, circular (handled with CSS):

<%- img(item.author_avatar, { w: 64, h: 64, fit: 'cover', class: 'rounded-full' }) %>

OG image for sharing — exact dimensions required by most social platforms:

<% meta({ property: 'og:image', content: src(item.seo.image, '1200x630') }) %>

Blurred placeholder (low-quality image placeholder pattern):

<div style="background-image: url('<%- src(item.cover, { w: 40, blur: 10 }) %>')"
     data-src="<%- src(item.cover, '1200x600') %>">
</div>

What this replaces

For most SleekCMS sites, the built-in transform API replaces:

  • Cloudinary or Imgix — a third-party image CDN subscription. The transform capabilities overlap significantly for standard web use cases.
  • Next.js <Image> component — if you're using the site builder, there's no Next.js in the stack. The img() helper covers the same functionality.
  • Manual srcset attributes — the picture() helper handles responsive image generation.
  • PostCSS image plugins — image optimization at build time. The transform URL handles it at request time, per device.

There are cases where a dedicated image CDN is still the right choice: complex focal-point cropping, facial detection, art direction with multiple editorial crops, high-volume media libraries that need advanced asset management. For standard web content — hero images, blog covers, team photos, product thumbnails — the built-in transform API covers the use case.

Core Web Vitals implications

Image optimization affects three of the Core Web Vitals metrics:

Largest Contentful Paint (LCP) — the hero image is often the LCP element. Serving it at the right size (not 4000px wide scaled down in CSS) and in WebP format typically yields the largest single LCP improvement available.

Cumulative Layout Shift (CLS) — the img() helper outputs width and height attributes, giving the browser the aspect ratio before the image loads. This prevents layout shift caused by images loading in without reserved space.

Interaction to Next Paint (INP) — less directly related to images, but serving smaller files reduces the bandwidth contention that delays interaction.

The URL parameter API makes it straightforward to serve the right image for every context — without a separate service, without a build-time step, and without per-framework configuration.