Image Management & Optimization

SleekCMS provides a complete image management system — upload, organize, transform, optimize, and deliver images from a single platform. Every image is stored centrally, served from a CDN, and can be transformed on the fly through URL parameters without modifying the original file. This means a single uploaded image can serve as a full-width hero banner, a thumbnail card, a retina-ready social preview, and a blurred background — all without creating separate versions.

This page covers how images work in SleekCMS, how to add and manage them, image metadata and handles, the transformation and optimization system, how images appear in templates and API responses, and how to use transformed images in markdown and rich text content.


How Images Work

When you add an image to SleekCMS — whether through upload, an integrated source, or a URL — the platform stores the original file and assigns it a CDN-backed URL. This URL is permanent. The image is immediately available across your entire site, in any content model that uses an image field.

Every image has two URLs:

url — The CDN URL with a default format applied (typically WebP). This is the ready-to-use URL for direct rendering.

raw — The base CDN URL without format or transformation parameters. This is the URL you append query parameters to for custom transformations.

The original file is never modified. All transformations — resizing, cropping, format conversion, filters — are applied at request time via query parameters on the raw URL. The CDN caches transformed versions, so subsequent requests for the same transformation are served instantly.


Adding Images

Images can be added to SleekCMS through multiple sources, all accessible from the image picker in the content editor.

Upload — Drag and drop or select files from your local machine. Uploaded images are stored in SleekCMS's media storage and served from the CDN.

Unsplash — Browse and search the Unsplash library directly from the image picker. Selected images are stored in your media library with their original attribution metadata.

Pexels — Search the Pexels stock photo library and add images without leaving the editor.

Pixabay — Access Pixabay's free image library for photos, illustrations, and vector graphics.

Iconify — Browse icon sets from Iconify's library. Selected icons are stored as SVG images, useful for feature icons, UI elements, and decorative graphics.

URL — Provide a direct URL to an externally hosted image. SleekCMS references the image at that URL, which is useful for images already hosted elsewhere that you don't want to re-upload.

All sources are available from the same image picker interface. Editors choose the source, find or upload the image, and the result is a consistent image object in the content record regardless of where the image came from.


Image Metadata

Every image in SleekCMS carries metadata that editors can manage and that your templates and frontend code can consume.

Alt Text

Each image has an alt description field. Editors enter a text description of the image, which is used for the alt attribute in HTML and for accessibility. Alt text is stored alongside the image and delivered in API responses, so your rendering code always has access to it without maintaining a separate mapping.

Alt text is set per image instance — when an editor selects an image for a content field, they can provide or edit the alt description for that usage. This means the same image can have different alt text in different contexts, which is the correct approach since alt text should describe the image's purpose in its specific context.

Default Dimensions and Filters

Image metadata can include default width, height, and filter settings. These defaults define how the image should be rendered when no explicit transformation parameters are provided. A logo image might have default dimensions of 200×50 to ensure consistent sizing across the site. A profile photo might have a default filter applied.

Default metadata acts as a baseline — your templates and frontend code can override these values with explicit parameters when needed, but the defaults ensure consistent rendering when no overrides are specified.

Theme Variants

Images can have dark and light theme variants — alternate versions of the same image optimized for different color schemes. A logo with a dark background variant and a light background variant, for example. When theme variants are present, the picture() template helper automatically generates <source> elements with prefers-color-scheme media queries.


Image Handles

When you assign a handle to an image in the media library, that image becomes directly accessible through the content API and in templates by name, independent of any content field.

Handles are useful for site-wide images that aren't tied to a specific content record — your site logo, a default Open Graph image, a favicon, a background pattern. Instead of storing these in a settings entry or hardcoding URLs, you give the image a handle and access it directly.

In the Content API

Images with handles appear in the images object of the content payload and can be retrieved with the getImage() method:

const logo = client.getImage('site-logo');
// {
//   url: 'https://img.sleekcms.com/az41/logo.webp',
//   raw: 'https://img.sleekcms.com/az41/logo',
//   alt: 'Company Logo'
// }

The full content payload includes all handled images under the images key:

const content = client.getContent();
// content.images → {
//   'site-logo': { url: '...', raw: '...', alt: '...' },
//   'og-default': { url: '...', raw: '...', alt: '...' },
//   'favicon': { url: '...', raw: '...', alt: '...' }
// }

In Templates

In the site builder, handled images are accessible through the getImage() function in the template context:

<% const logo = getImage('site-logo'); %>
<img src="<%- src(logo, '200x50') %>" alt="<%- logo.alt %>">

This makes handled images available in any template — layout, page, block, or entry — without needing to pass them through content fields or entry references.


Replacing Images Without Changing URLs

One of the most important properties of SleekCMS's image system is that images can be replaced without changing their URL. When you upload a new version of an image — an updated logo, a refreshed product photo, a corrected headshot — the URL stays the same. Every page, entry, block, and template that references that image automatically serves the new version.

This is possible because image URLs are tied to the image's identity in the media library, not to the file contents. Replacing the file updates what the URL serves without breaking any references.

This has practical benefits across the entire workflow. Designers can update brand assets without involving content editors. Product teams can refresh imagery without editing content records. Marketing can swap seasonal photos without touching templates. The URL is the stable reference, and the file behind it can change as needed.


CDN Delivery

All images in SleekCMS are served from a CDN. This means images are delivered from edge servers geographically close to your visitors, with automatic caching for fast load times.

When a transformation is requested — a specific size, format, or filter — the CDN caches the transformed result. The first request for a particular transformation processes the image on the fly. Subsequent requests for the same transformation are served directly from the CDN cache with no processing delay.

This architecture means you don't need to pre-generate image variants or maintain separate files for different sizes. You define the transformation you need at the point of use — in your template, in your frontend code, or in a markdown image URL — and the CDN handles caching and delivery.


Image Transformation Reference

Every image in SleekCMS can be transformed on the fly by appending query parameters to the image's raw URL. Transformations are processed server-side, cached at the CDN edge, and the original file is never modified.

The base URL pattern is:

https://img.sleekcms.com/{site-id}/{image-id}?{parameters}

Dimensions

Parameter Range Description
s WxH Combined size (e.g., 300x200)
w 1–8192 Width in pixels
h 1–8192 Height in pixels
dpr 1–4 Device pixel ratio multiplier

w and h override values from s. Final dimensions are multiplied by dpr, so w=400&dpr=2 produces an 800px wide image suitable for retina displays.

Resize and Crop

Parameter Values Description
fit cover (default), contain, fill, inside, outside Resize fitting mode
pos Position keyword or gravity Position/gravity for cropping
bg Hex color Background color (e.g., fff, ff0000, ffffff80)

Fit modes:

  • cover — Resize to fill the target dimensions, cropping edges as needed. This is the default and the most common choice for thumbnails and cards.
  • contain — Resize to fit within the target dimensions, adding background padding if the aspect ratio doesn't match. Use bg to set the padding color.
  • fill — Stretch the image to exactly match the target dimensions, ignoring aspect ratio.
  • inside — Resize to fit within the target dimensions without exceeding either. Similar to contain but without padding.
  • outside — Resize so the image covers the target dimensions, potentially exceeding one dimension.

Position values for cropping: top, right top, right, right bottom, bottom, left bottom, left, left top, center, north, northeast, east, southeast, south, southwest, west, northwest, entropy, attention

The entropy and attention positions are smart crop modes — entropy focuses on the area with the most detail, and attention uses saliency detection to focus on the most visually interesting region.

Format and Quality

Parameter Values Description
fmt webp, avif, png, jpg, jpeg, gif, tiff, svg Output format
q 1–100 (default: 80) Output quality

Format conversion happens on the fly. Serve modern formats like WebP or AVIF to reduce file sizes without maintaining separate versions. The svg format returns the original file without any raster transformations applied.

Transformations

Parameter Range Description
rot 0, 90, 180, 270 Rotation in degrees
flip h, v, hv Flip horizontal, vertical, or both
blur 0.3–1000 Gaussian blur sigma
sharp 0.5–10 Sharpen sigma
round 0–9999 Border radius for rounded corners
p 0–1000 Padding (extend image edges)

Padding formats:

  • p=20 — Uniform padding on all sides
  • p=10,20 — Vertical (top/bottom), horizontal (left/right)
  • p=10,20,30,40 — Top, right, bottom, left

Padding uses the bg color if specified, otherwise transparent.

Color Adjustments

Parameter Range Description
gray 1, true, or present Convert to grayscale
tint Hex color Apply color tint overlay
bri -100 to 100 Brightness adjustment
con -100 to 100 Contrast adjustment
sat -100 to 100 Saturation adjustment

Filters

Parameter Values Description
filter Comma-separated list Apply multiple filters

Available filters: grayscale, greyscale, negate, normalize, clahe

Multiple filters can be combined: filter=normalize,negate

Transformation Examples

# Resize to 400×300, cover fit, WebP format
?w=400&h=300&fmt=webp

# Combined size with quality control
?s=800x600&q=90

# Thumbnail with rounded corners
?w=150&h=150&round=75&fmt=png

# Retina display (2x device pixel ratio)
?w=400&h=300&dpr=2

# Grayscale with blur (useful for backgrounds)
?w=800&gray=1&blur=2

# Crop focusing on bottom-right with background fill
?w=500&h=500&fit=contain&pos=southeast&bg=ffffff

# Color adjustments
?w=600&bri=10&con=20&sat=-50

# Multiple filters
?w=800&filter=normalize,negate

# Rotate and flip
?w=600&rot=90&flip=h

# Add padding with background color
?w=400&p=20&bg=f0f0f0

# Asymmetric padding (10px vertical, 30px horizontal)
?w=400&p=10,30&bg=ffffff

Images in Templates

The site builder provides four helper functions for working with images in EJS templates. These helpers generate optimized URLs and HTML elements from image objects, handling transformation parameters, alt text, theme variants, and fallback behavior.

src(obj, attr)

Generates an optimized image URL with transformation parameters. Returns a URL string.

<!-- String dimensions -->
<img src="<%- src(item.hero, '800x600') %>" alt="<%- item.hero.alt %>">

<!-- Object form with format and fit -->
<img src="<%- src(item.thumbnail, { w: 400, h: 300, fit: 'cover', type: 'webp' }) %>">

<!-- Size shorthand -->
<img src="<%- src(item.photo, { size: '400x300', fit: 'cover' }) %>">

When the image object is invalid or missing, src() returns a placeholder URL (https://placehold.co/{size}.png) so layouts don't break during development.

img(obj, attr)

Generates a complete <img> HTML element with the optimized source, alt text, and optional CSS attributes. This is a simpler alternative to picture() when theme variants are not needed.

<!-- Basic img element -->
<%- img(item.hero, '800x600') %>
<!-- Output: <img src="https://img.../hero?w=800&h=600" alt="Hero description"> -->

<!-- With CSS class and style -->
<%- img(item.hero, { size: '800x600', class: 'hero-img', style: 'object-fit: cover' }) %>

picture(obj, attr)

Generates a <picture> element with automatic dark/light theme variant support. When the image has dark or light variants, the helper includes <source> elements with prefers-color-scheme media queries.

<!-- Basic usage -->
<%- picture(item.hero, '800x600') %>

<!-- When the image has a dark variant, outputs: -->
<!-- <picture>
  <source srcset="https://img.../hero-dark?w=800&h=600" media="(prefers-color-scheme: dark)">
  <img src="https://img.../hero?w=800&h=600" alt="Hero description">
</picture> -->

<!-- With class and style -->
<%- picture(item.logo, { size: '200x50', class: 'logo', style: 'max-width: 100%' }) %>

svg(obj, attr?)

Inlines an SVG file with custom attributes applied directly to the SVG element. Use this for logos, icons, and vector graphics where you need to control size, color, or CSS class through attributes.

<!-- Basic SVG inline -->
<%- svg(item.icon) %>

<!-- With custom attributes -->
<%- svg(item.logo, { width: 120, height: 40, class: 'logo' }) %>

Returns an empty SVG with an error attribute if the image object is invalid or the URL doesn't end with .svg.


Using Transformed Images in Markdown

When you include images in markdown or rich text fields, you can apply transformations directly in the image URL. This is useful for controlling how inline images render in article body content, blog posts, or any content authored in markdown.

Since markdown images use standard URL syntax, you append transformation parameters to the image's raw URL just as you would anywhere else:

<!-- Standard size -->
![A plate of pasta](https://img.sleekcms.com/az41/m7urgy6z?w=800&h=400&fit=cover&fmt=webp)

<!-- Thumbnail with rounded corners -->
![Author headshot](https://img.sleekcms.com/az41/m7uxv6ze?w=150&h=150&round=75&fmt=webp)

<!-- Grayscale background image -->
![Background](https://img.sleekcms.com/az41/m7utzbuj?w=1200&gray=1&blur=3&q=60)

This gives content authors precise control over image rendering within their written content. The same transformation parameters available in templates and API integrations work identically in markdown image URLs — resize, crop, format convert, adjust quality, apply filters — all through query parameters on the raw URL.

For content editors who aren't comfortable constructing transformation URLs manually, the recommended approach is to use the image's default url (which includes the default format) and handle sizing through CSS in the page or block template. The transformation URL approach is most useful for developers authoring content or for editorial workflows where specific image treatments are part of the content itself.


Images in the Content API

When consuming images through the content API, image data is included inline in the content records that reference them.

Image Object Structure

Every image field returns an object with this shape:

{
  url: 'https://img.sleekcms.com/az41/m7urgy6z.webp',   // CDN URL with default format
  raw: 'https://img.sleekcms.com/az41/m7urgy6z',         // Base URL for custom transformations
  alt: 'Description of the image',                        // Alt text set by editors
  source: 'unsplash',                                     // Source platform (null for uploads)
  light: null,                                            // Light theme variant (URL or null)
  dark: null                                              // Dark theme variant (URL or null)
}

Use url for direct rendering with the default format. Use raw to construct custom transformation URLs by appending query parameters.

Retrieving Handled Images

Images with assigned handles are accessible directly through the getImage() method:

const logo = client.getImage('site-logo');
// { url: '...', raw: '...', alt: 'Company Logo' }

const ogImage = client.getImage('og-default');
// { url: '...', raw: '...', alt: 'Default social preview' }

Building Transformation URLs

Your frontend code constructs transformation URLs by appending parameters to the raw URL:

const page = client.getPage('/blog/hello-world');

// Hero banner at 1200×600 in WebP
const heroUrl = `${page.image.raw}?w=1200&h=600&fit=cover&fmt=webp`;

// Thumbnail at 400×300
const thumbUrl = `${page.image.raw}?w=400&h=300&fit=cover&fmt=webp`;

// Retina-ready social preview
const ogUrl = `${page.image.raw}?w=1200&h=630&dpr=2&fmt=jpg&q=85`;

// Blurred background
const bgUrl = `${page.image.raw}?w=1920&blur=20&q=40`;

Multiple Image Fields

When an image field is configured as multiple, the API returns an array of image objects:

const product = client.getPage('/products/widget');
// product.gallery → [
//   { url: '...', raw: '...', alt: 'Front view' },
//   { url: '...', raw: '...', alt: 'Side view' },
//   { url: '...', raw: '...', alt: 'Detail shot' }
// ]

What's Next