skills/integrate-asset-delivery-with-transloadit-smartcdn-in-nextjs/SKILL.md
Add Transloadit Smart CDN URL signing to a Next.js App Router project (server-side signing route + optional client demo page).
npx skillsauth add transloadit/skills integrate-asset-delivery-with-transloadit-smartcdn-in-nextjsInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
4 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
TRANSLOADIT_KEY, TRANSLOADIT_SECRETTRANSLOADIT_SMARTCDN_WORKSPACE, TRANSLOADIT_SMARTCDN_TEMPLATE, TRANSLOADIT_SMARTCDN_INPUTFor local dev, put these in .env.local. Never expose TRANSLOADIT_SECRET to the browser.
npm i @transloadit/utils
Pick the root:
src/app, use src/app/...app/...Create app/api/smartcdn/route.ts (or src/app/api/smartcdn/route.ts if you use src/):
import { NextResponse } from 'next/server'
import { getSignedSmartCdnUrl } from '@transloadit/utils/node'
export const runtime = 'nodejs'
function reqEnv(name: string): string {
const v = process.env[name]
if (!v) throw new Error(`Missing required env var: ${name}`)
return v
}
export async function GET() {
try {
const authKey = reqEnv('TRANSLOADIT_KEY')
const authSecret = reqEnv('TRANSLOADIT_SECRET')
const workspace = process.env.TRANSLOADIT_SMARTCDN_WORKSPACE || 'demo'
const template = process.env.TRANSLOADIT_SMARTCDN_TEMPLATE || 'serve-preview'
const input = process.env.TRANSLOADIT_SMARTCDN_INPUT || 'example.jpg'
const url = getSignedSmartCdnUrl({ workspace, template, input, authKey, authSecret })
return NextResponse.json({ url, workspace, template, input })
} catch (err) {
const message = err instanceof Error ? err.message : 'Unknown error'
return NextResponse.json({ error: message }, { status: 500 })
}
}
Create app/smartcdn/page.tsx (or src/app/smartcdn/page.tsx):
import SmartCdnDemo from './smartcdn-demo'
export default function SmartCdnPage() {
return (
<main style={{ padding: 24 }}>
<h1 style={{ fontSize: 20, fontWeight: 600 }}>Smart CDN Signed URL</h1>
<SmartCdnDemo />
</main>
)
}
Create app/smartcdn/smartcdn-demo.tsx (or src/app/smartcdn/smartcdn-demo.tsx):
'use client'
import { useEffect, useState } from 'react'
export default function SmartCdnDemo() {
const [payload, setPayload] = useState<unknown>(null)
useEffect(() => {
let cancelled = false
fetch('/api/smartcdn', { cache: 'no-store' })
.then(async (res) => res.json())
.then((json) => {
if (!cancelled) setPayload(json)
})
.catch((err) => {
if (!cancelled) setPayload({ error: String(err) })
})
return () => {
cancelled = true
}
}, [])
return (
<pre data-testid="smartcdn-json">
{payload ? JSON.stringify(payload, null, 2) : '(loading)'}
</pre>
)
}
/smartcdn or fetch /api/smartcdn.url and your { workspace, template, input }.https://github.com/transloadit/skills/tree/main/scenarios/integrate-asset-delivery-with-transloadit-smartcdn-in-nextjsTested with (see the scenario lockfile for the exact versions):
tools
One-off AI image upscaling (local image -> upscaled image) using Transloadit via the `transloadit` CLI. Prefer the `image upscale` intent and use `--output` for a deterministic path.
development
Launch and steer a sibling Codex agent in a new tmux pane using the same or explicitly requested model, reasoning effort, sandbox, approval policy, and working directory. Use when the user asks to open a new tmux pane/window, start another Codex, delegate a bounded task to it, communicate with that Codex, monitor it, or make future parallel Codex handoffs smoother. Also use when the user mentions ACP for local Codex-to-Codex coordination but tmux interaction is sufficient or more reliable.
tools
One-off polaroid-stack photo collage (N local images -> single image) using the official `@transloadit/node` CLI. Uses the `/image/merge` Robot's `polaroid-stack` effect and downloads the result to an explicit output path via `--output`.
tools
One-off justified mosaic photo collage (N local images -> single image) using the official `@transloadit/node` CLI. Uses the `/image/merge` Robot's `mosaic` effect to build a tiled layout that keeps every photo fully visible, and downloads the result to an explicit output path via `--output`.