Skip to content

feat(cloudinary): performant preview images#1233

Open
stipsan wants to merge 4 commits into
mainfrom
cursor/port-cloudinary-performant-previews-ef0e
Open

feat(cloudinary): performant preview images#1233
stipsan wants to merge 4 commits into
mainfrom
cursor/port-cloudinary-performant-previews-ef0e

Conversation

@stipsan

@stipsan stipsan commented Jun 18, 2026

Copy link
Copy Markdown
Member

Ports sanity-io/sanity-plugin-cloudinary#92 ("feat: performant preview images") by @ChrisLaRocque into the monorepo.

What changed

  • Added @cloudinary/url-gen as a dependency of sanity-plugin-cloudinary.
  • assetUrl(asset, cloudName?) now builds an optimized, scaled preview URL (c_scale,w_400) via @cloudinary/url-gen when a cloudName and public_id are available, instead of loading the full-size original. It falls back to the existing derived/secure_url/url selection when no cloud name is provided.
  • AssetPreview and AssetDiff read the configured cloudName from plugin secrets (useSecrets) and pass it to assetUrl.
  • AssetPreview additionally lets the block layout fill its container width (the default layout stays capped at 80px).
  • Added src/utils.test.ts covering the new behavior, and a small AGENTS.md clarification about the Node version needed for a full build (discovered while verifying).

Walkthrough

Preview rendering end-to-end in the test studio: the Cloudinary asset field renders the optimized, scaled image (the rendered <img src> is https://res.cloudinary.com/demo/image/upload/c_scale,w_400/sample, intrinsic size 400×267px).

cloudinary_performant_preview_demo.mp4

Rendered Cloudinary asset preview in the Studio
DevTools showing the preview img src contains c_scale,w_400

Porting notes

  • The original PR also added @cloudinary/react to dependencies, but it is never imported anywhere in the diff. It was omitted here to keep the dependency surface minimal and pass knip. The feature is implemented entirely with @cloudinary/url-gen.
  • Behavior preserved from the PR: AssetPreview returns null until a cloudName secret is available (the diff view still falls back to the stored URL). In practice cloudName is required to select Cloudinary assets via the media library, so it is configured whenever a cloudinary.asset exists.
  • Adapted to monorepo conventions (inline type imports, import ordering, deduped the PDF-thumbnail <img> between layouts).

Credit

Original author: @ChrisLaRocque. The feature commit preserves their Git authorship, and the changeset adds an author: directive so the release notes thank them.

Testing

  • pnpm format
  • pnpm lint
  • pnpm build (49/49)
  • pnpm test run (885 tests)
  • pnpm knip (only pre-existing warnings)
  • src/utils.test.ts (5 cases) covering url-gen scaling and the fallback paths.
  • ✅ Manual GUI test in pnpm dev: seeded a demo-cloud asset + cloudName secret, confirmed the preview renders via the c_scale,w_400 url-gen URL, then removed the seeded data.

Note: the full pnpm build/pnpm test require Node ≥ 22.18 (this monorepo's tooling, tsdown, needs native TS config loading); the VM default Node 22.14 fails at @repo/generators. Switching to the preinstalled Node 22.22.2 resolves it (now documented in AGENTS.md).

To show artifacts inline, enable in settings.

Open in Web Open in Cursor 

ChrisLaRocque and others added 2 commits June 18, 2026 13:06
Port sanity-io/sanity-plugin-cloudinary#92 by @ChrisLaRocque.

Asset previews and diffs now build a scaled 400px-wide preview URL with
@cloudinary/url-gen when a cloud name is configured, instead of loading
the full-size original. Falls back to the stored asset URL when no cloud
name is available.
Verify url-gen scaling is used when a cloud name and public id are
present, and that the existing derived/secure_url/url fallbacks remain
intact otherwise.
@vercel

vercel Bot commented Jun 18, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
plugins-studio Ready Ready Preview, Comment Jun 19, 2026 1:39pm

Request Review

@changeset-bot

changeset-bot Bot commented Jun 18, 2026

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: 081c735

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 1 package
Name Type
sanity-plugin-cloudinary Minor

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@stipsan stipsan added the 🤖 bot label Jun 18, 2026 — with Cursor
@socket-security

socket-security Bot commented Jun 18, 2026

Copy link
Copy Markdown

Review the following changes in direct dependencies. Learn more about Socket for GitHub.

Diff Package Supply Chain
Security
Vulnerability Quality Maintenance License
Addednpm/​@​cloudinary/​url-gen@​1.22.09910010082100

View full report

The default cloud VM Node (22.14) fails `@repo/generators` build because
tsdown can't load its TS config without native TS support or the optional
unrun/tsx loader. Document switching to the preinstalled 22.22.2.
@stipsan stipsan marked this pull request as ready for review June 18, 2026 14:05
@stipsan stipsan requested a review from a team as a code owner June 18, 2026 14:05
@stipsan stipsan requested review from Copilot and juice49 and removed request for a team June 18, 2026 14:05

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Ports the Cloudinary “performant preview images” feature into the monorepo by generating scaled preview URLs (400px wide) for Cloudinary assets when the plugin’s cloudName secret is available, reducing large image downloads in Studio previews/diffs.

Changes:

  • Add @cloudinary/url-gen and use it in assetUrl() to build scaled preview URLs when cloudName + public_id are present.
  • Update AssetPreview/AssetDiff to read cloudName from @sanity/studio-secrets and pass it through to assetUrl(), plus adjust block layout preview sizing.
  • Add unit tests for the new URL behavior and document Node version requirements in AGENTS.md.

Reviewed changes

Copilot reviewed 7 out of 8 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
pnpm-lock.yaml Locks @cloudinary/url-gen (and related) dependencies for the monorepo.
plugins/sanity-plugin-cloudinary/package.json Adds @cloudinary/url-gen dependency to the Cloudinary plugin.
plugins/sanity-plugin-cloudinary/src/utils.ts Implements url-gen scaled preview URL generation in assetUrl().
plugins/sanity-plugin-cloudinary/src/utils.test.ts Adds tests covering url-gen path and fallback URL selection.
plugins/sanity-plugin-cloudinary/src/components/AssetPreview.tsx Reads cloudName from secrets and adjusts preview rendering/layout behavior.
plugins/sanity-plugin-cloudinary/src/components/AssetDiff.tsx Reads cloudName from secrets and passes it to assetUrl() for diff previews.
AGENTS.md Documents Node >= 22.18 requirement for full build/test in this repo.
.changeset/cloudinary-performant-previews.md Minor release notes for the Cloudinary plugin with author attribution.
Files not reviewed (1)
  • pnpm-lock.yaml: Generated file

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.


export function assetUrl(asset: Partial<Pick<CloudinaryAsset, 'url' | 'secure_url' | 'derived'>>) {
export function assetUrl(
asset: Partial<Pick<CloudinaryAsset, 'url' | 'secure_url' | 'derived' | 'public_id' | 'format'>>,
Comment on lines +20 to +24
if (cloudName && asset.public_id) {
return new CloudinaryImage(asset.public_id, new CloudConfig({cloudName}))
.resize(scale().width(400))
.toURL()
}
Comment on lines +41 to +45
test('falls back to the original url when secure_url is absent', () => {
const url = assetUrl({url: 'http://res.cloudinary.com/demo/image/upload/v1/folder/sample.jpg'})

expect(url).toBe('http://res.cloudinary.com/demo/image/upload/v1/folder/sample.jpg')
})
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants