feat(cloudinary): performant preview images#1233
Conversation
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.
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
🦋 Changeset detectedLatest commit: 081c735 The changes in this PR will be included in the next version bump. This PR includes changesets to release 1 package
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 |
|
Review the following changes in direct dependencies. Learn more about Socket for GitHub.
|
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.
There was a problem hiding this comment.
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-genand use it inassetUrl()to build scaled preview URLs whencloudName+public_idare present. - Update
AssetPreview/AssetDiffto readcloudNamefrom@sanity/studio-secretsand pass it through toassetUrl(), plus adjustblocklayout 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'>>, |
| if (cloudName && asset.public_id) { | ||
| return new CloudinaryImage(asset.public_id, new CloudConfig({cloudName})) | ||
| .resize(scale().width(400)) | ||
| .toURL() | ||
| } |
| 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') | ||
| }) |
Ports sanity-io/sanity-plugin-cloudinary#92 ("feat: performant preview images") by @ChrisLaRocque into the monorepo.
What changed
@cloudinary/url-genas a dependency ofsanity-plugin-cloudinary.assetUrl(asset, cloudName?)now builds an optimized, scaled preview URL (c_scale,w_400) via@cloudinary/url-genwhen acloudNameandpublic_idare available, instead of loading the full-size original. It falls back to the existing derived/secure_url/urlselection when no cloud name is provided.AssetPreviewandAssetDiffread the configuredcloudNamefrom plugin secrets (useSecrets) and pass it toassetUrl.AssetPreviewadditionally lets theblocklayout fill its container width (thedefaultlayout stays capped at 80px).src/utils.test.tscovering the new behavior, and a smallAGENTS.mdclarification about the Node version needed for a full build (discovered while verifying).Walkthrough
Preview rendering end-to-end in the test studio: the
Cloudinary assetfield renders the optimized, scaled image (the rendered<img src>ishttps://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
@cloudinary/reacttodependencies, but it is never imported anywhere in the diff. It was omitted here to keep the dependency surface minimal and passknip. The feature is implemented entirely with@cloudinary/url-gen.AssetPreviewreturnsnulluntil acloudNamesecret is available (the diff view still falls back to the stored URL). In practicecloudNameis required to select Cloudinary assets via the media library, so it is configured whenever acloudinary.assetexists.typeimports, 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 formatpnpm lintpnpm 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.pnpm dev: seeded ademo-cloud asset +cloudNamesecret, confirmed the preview renders via thec_scale,w_400url-gen URL, then removed the seeded data.To show artifacts inline, enable in settings.