Jun 17, 2024 · Updated Sep 15, 2026

<span aria-hidden="true" id="reduce-costs--latency-with-transloadits-smart-cdn-file-previews"></span>

<span aria-hidden="true" id="on-demand-media-previews-with-smart-cdn"></span>

# On-demand media previews with Smart CDN

![Kevin van Zonneveld](/assets/images/teammates/avatar-kvz-4.jpg)

**Kevin van Zonneveld**

Co-founder · Amsterdam, The Netherlands · Show bio

[](https://x.com/kvz)[](https://github.com/kvz)

A file browser rarely needs to download an entire video just to show what it contains. A thumbnail, an audio waveform, or a file-type icon can provide that context with a much smaller response.

The [/file/preview](/docs/robots/file-preview.md) Robot generates those previews. [Smart CDN](/services/content-delivery.md) can run the processing workflow when a preview is requested and cache the result. This article combines a working demo, a bounded Template, and server-side URL signing.

<span aria-hidden="true" id="what-is-the-transloadit-smart-cdn"></span>

## What is the Transloadit Smart CDN?

Smart CDN connects a delivery URL to a Transloadit Assembly. On a cache miss, Transloadit imports the source, runs the Template, and serves the result. A later request can reuse a cached derivative while it remains available and cacheable.

A warm response and a cache miss have different costs and latency. The source location, file format, preview strategy, cache lifetime, and request pattern all matter. Our [published performance measurements](/services/content-delivery.md#performance) describe a particular test setup, not a latency guarantee for every file.

<span aria-hidden="true" id="what-is-the-file-preview-feature"></span>

## What is the file preview feature?

![The /file/preview Robot](/_next/static/immutable/media/file-preview.0kikjpr3nc6jo.png)

The Robot tries the configured preview strategies for each file category. For example, it can look for embedded artwork before extracting a video frame. An icon can be the final fallback when a richer preview is unavailable. The [Robot reference](/docs/robots/file-preview.md) is the source of truth for supported formats, strategy order, limits, and parameters.

<span aria-hidden="true" id="key-features"></span>

### Key features

* Images can become resized thumbnails.
* Videos can use artwork, a frame, or other supported video strategies.
* Audio can use artwork or a waveform.
* Documents can use a rendered page.
* Web pages can use a screenshot.
* Archives and unsupported content can use an icon when that fallback is configured.

These are previews, not complete renditions of the original. A waveform is not an audio player, and a thumbnail is not a video download. Test your own formats and keep a usable fallback for failures.

<span aria-hidden="true" id="benefits-of-file-previews"></span>

### Benefits of file previews

Generating previews on demand can avoid work for files that nobody views. Caching can reduce repeated processing, and smaller responses can reduce delivery bandwidth. Preprocessing remains useful when every file needs a preview before publication or when a first-view processing delay is unacceptable.

The savings are workload-dependent. A preview can even be larger than a tiny source image, so measure delivered bytes rather than assuming a fixed reduction percentage.

<span aria-hidden="true" id="interactive-demo"></span>

## Interactive demo

The demo uses four public sample files. It fetches a preview only when you submit the form. It does not upload your files, fetch the original video or audio into your browser, or run an Assembly metadata lookup.

The public demo runs on Transloadit's `my-app` Workspace with an existing Template that accepts `w`, `h`, `f`, `r`, `vs`, and `v`. The production example below uses a separate, more restricted Template that accepts only `size` as a query field.

<span aria-hidden="true" id="how-to-use-the-demo"></span>

### How to use the demo

Choose a source, dimensions, and format. Select the **Resize strategy** option, then select **Generate preview**. Keyboard and touch changes use the same submit action. The displayed URL and measurements belong to the last submitted result, not to settings you have changed without submitting.

The observed fetch time includes receiving the preview body in your browser. It is one observation, not a controlled cold-cache or warm-cache benchmark. Browser caching, your connection, and processing can all affect it.

The delivery comparison is a separate estimate: it applies one chosen bandwidth price and request count to both files. It excludes processing, storage, request fees, subscriptions, taxes, and retries. It is not a comparison of complete Transloadit and AWS invoices. Downloading an original video is also not equivalent to displaying a still preview.

Source file

ImageVideoAudio without artworkAudio with artwork

Preview format

PNGJPEGGIF

Width (pixels)

300

Height (pixels)

200

Resize strategy

Fit within boundsPad to exact sizeCrop to exact size

Generate preview

No preview yet

<span aria-hidden="true" id="_R_npalubsnpfsnmqivb_-comparison"></span>

### Delivery comparison

Connection speed

1.5 Mb/s5 Mb/s10 Mb/s25 Mb/s100 Mb/s300 Mb/s1,000 Mb/s

Preview requests per month

Assumed delivery price (USD/GB)

Estimates use the same delivery rate for both files, a 20 ms baseline, and 1 GB = 1,000,000,000 bytes. Processing, storage, request fees, subscriptions, taxes, and retries are excluded. This is not a Transloadit price quote.

<span aria-hidden="true" id="how-to-get-started"></span>

## How to get started

<span aria-hidden="true" id="1-sign-up-for-transloadit"></span>

### 1. Sign up for Transloadit

[Create an account](/c/signup/) and review the current [plans and limits](/pricing.md).

<span aria-hidden="true" id="2-create-a-workspace"></span>

### 2. Create a Workspace

The examples use the placeholder Workspace `your-workspace`. Replace it with your own Workspace when creating URLs. The public demo Workspace is separate from your account.

<span aria-hidden="true" id="3-create-a-template"></span>

### 3. Create a Template

Create a Template named `preview`. This version deliberately fixes the output format and resize strategy and accepts only one size field. Replace `my-website.com` with an HTTPS origin you control. Publish the two sample files used below there, or change the server-owned file map to your own immutable object names.

```json
{
  "steps": {
    "imported": {
      "robot": "/http/import",
      "url": "https://my-website.com/${fields.input}"
    },
    "previewed": {
      "robot": "/file/preview",
      "use": "imported",
      "format": "png",
      "width": "${fields.size}",
      "height": "${fields.size}",
      "resize_strategy": "fit",
      "zoom": false
    },
    "served": {
      "robot": "/file/serve",
      "use": "previewed",
      "cache_duration": 3600
    }
  }
}

```

The signing program below allows only three sizes and two known inputs. The Template alone does not enforce that allowlist. Set `require_signature_auth` to `1` through the [Template API](/docs/api/templates-template-id-put.md), as a Template attribute outside `steps`. Verify that unsigned and tampered requests are rejected before publishing it. Do not expose an arbitrary import URL or a general-purpose transformation endpoint.

<span aria-hidden="true" id="4-use-the-smart-cdn"></span>

### 4. Use the Smart CDN

The unsigned URL structure for this Template is:

```plaintext
https://your-workspace.tlcdn.com/preview/photo-v1.jpg?size=320

```

The path identifies the Workspace, Template, and input. The input becomes `${fields.input}`, and the query supplies `${fields.size}`. This structural example is not a usable authorization token. Use the signed URL returned by the server-side program in the next section.

Version source filenames when changing their contents, such as `photo-v2.jpg`. Replacing an object at the same name does not make every cached derivative disappear immediately.

<span aria-hidden="true" id="5-implement-security-measures"></span>

### 5. Implement security measures

Use the Workspace's Smart-CDN-enabled Auth Key and its Auth Secret. The latter must stay on the server. Configure environment variables through your normal secret-management process, not a browser bundle or a committed file.

This is a trusted-operator CLI, not an HTTP authentication implementation. It signs a small server-owned allowlist without making a network request. Use Node.js 24 or newer and install the official SDK:

```bash
yarn add @transloadit/node@4.12.0

```

Save this as `sign-preview.mjs`:

```javascript
import { Transloadit } from '@transloadit/node'

const inputs = new Map([
  ['photo', 'photo-v1.jpg'],
  ['audio', 'audio-v1.mp3'],
])
const sizes = new Set(['160', '320', '640'])

function main() {
  const [name, size, ...extra] = process.argv.slice(2)
  const input = inputs.get(name)
  if (!input || !sizes.has(size) || extra.length !== 0) {
    throw new Error('Expected one known file name and preview size')
  }
  const authKey = process.env.TRANSLOADIT_AUTH_KEY
  const authSecret = process.env.TRANSLOADIT_AUTH_SECRET
  const workspace = process.env.TRANSLOADIT_WORKSPACE
  if (!authKey || !authSecret || !workspace || !/^[a-z0-9-]+$/.test(workspace)) {
    throw new Error('Missing or invalid server configuration')
  }
  const client = new Transloadit({ authKey, authSecret })
  const url = client.getSignedSmartCDNUrl({
    workspace,
    template: 'preview',
    input,
    urlParams: { size: Number(size) },
    expiresAt: Date.now() + 60 * 60 * 1000,
  })
  process.stdout.write(url + '\n')
}

try {
  main()
} catch {
  console.error('Could not sign preview. Check the file, size, and server configuration.')
  process.exitCode = 1
}

```

With those three environment variables configured, run:

```bash
node sign-preview.mjs photo 320

```

The output is a bearer URL: anyone who obtains it can use it during its valid lifetime. Do not put it in analytics, error reports, or public logs. This example intentionally prints it for the operator; an application should deliver it only to the authorized requester.

For an application endpoint, authenticate the user first, resolve an asset identifier through your database, and check access to that specific asset before signing. Bound allowed variants and issuance rates. Do not treat knowing a filename as proof of authorization, and do not accept caller-provided origins, Templates, signatures, or expiration times.

The SDK generates the signature and authentication query parameters. Expiration is expressed in milliseconds since the UNIX epoch. Here it is set explicitly to one hour. The effective cache lifetime is also bounded by the remaining signature lifetime; choose it according to content sensitivity and caching needs. See [signing and cache lifetime](/docs/api/authentication.md#smart-cdn) for the current contract.

<span aria-hidden="true" id="6-customize-the-behavior"></span>

### 6. Customize the behavior

Add parameters deliberately after validating them on your server. Keep the permitted combinations small to limit derivative count and cost. See [resize strategies](/docs/topics/resize-strategies.md) and the [preview strategy reference](/docs/robots/file-preview.md#strategy).

For sensitive or user-submitted content, review import access, processing limits, and what a preview may reveal. A thumbnail or extracted page can contain private information too.

<span aria-hidden="true" id="bring-your-own-storage"></span>

## Bring your own storage

Use the appropriate [import Robot](/docs/robots.md#file-importing) and [Template Credentials](/docs/topics/template-credentials.md) for private cloud storage. Keep storage credentials in that server-side configuration. Do not put bucket credentials or an arbitrary presigned source URL into a public preview link.

<span aria-hidden="true" id="bring-your-own-cdn"></span>

## Bring your own CDN

An existing CDN requires deliberate origin, cache-key, signing, and error-handling configuration. [Contact us](/support.md) about the current integration options for your workload. Do not assume that putting another CDN in front of a signed URL preserves its access-control or expiration semantics.

<span aria-hidden="true" id="preprocessing"></span>

## Preprocessing

You can also run /file/preview in a regular Assembly and export the derivatives to your own storage. That trades work at upload time for predictable availability later. It is useful when publication must wait until previews are ready or when a static CDN should serve a fixed set of files.

<span aria-hidden="true" id="coming-soon"></span>

<span aria-hidden="true" id="current-capabilities"></span>

## Current capabilities

This article no longer maintains a separate roadmap. Check the [Robot reference](/docs/robots/file-preview.md) for current output formats and strategies, including features that were experimental when this post was first published.

<span aria-hidden="true" id="pricing"></span>

## Pricing

Processing and delivery are distinct parts of the workload. Estimate them from your actual Templates, file sizes, request counts, cache behavior, and [current pricing](/pricing.md). Account limits and output restrictions vary by plan. The demo's adjustable bandwidth rate is an assumption, not a quoted Transloadit rate.

<span aria-hidden="true" id="demo-call"></span>

## Demo call

[Talk to our team](/support.md) about your file types, expected traffic, privacy requirements, and existing storage.

<span aria-hidden="true" id="conclusion"></span>

## Conclusion

Start with a few representative files and a bounded preview Template. Check the returned images, measure real response sizes, exercise failures and cache misses, and verify signed access. Expand the allowed variants once the workflow and its costs make sense for your application.

[#walkthrough](/blog/tags/walkthrough.md)[#content-delivery-service](/blog/tags/content-delivery-service.md)[#file-preview-robot](/blog/tags/file-preview-robot.md)

### Join 25k+ developers

Sign up for our [monthly newsletter](/newsletters.md) to receive direct links to 3 exclusive tech — and 2 product updates. No less, no more.

Email address

Subscribe

One email a month. Unsubscribe anytime.

## File uploading and encoding. Made simple.

Trusted by Coursera and The New York Times for a reliable API, top-notch support, and open source like [Uppy⁠](https://uppy.io) and [Tus⁠](https://tus.io).

[Try it free](/c/signup/)[Request a demo](/request-demo.md)

No credit card needed · Cancel anytime
