fix(admin): load resized thumbnails in media library and picker (#1488)#1507
Merged
Conversation
The media library, library list, and picker modal loaded every grid item's full-size original through the media proxy, so opening the library and searching for older items waited on full-resolution downloads (1 min+ on large libraries). Route same-origin raster images through Astro's runtime image endpoint (/_image) to request a small resized rendition instead. Where no runtime image service transforms (passthrough config, or the endpoint rejects the request) the original is served as before, so nothing renders worse. Items with unknown dimensions still load the original so onLoad can backfill true dimensions rather than the thumbnail's.
🦋 Changeset detectedLatest commit: 6a94cb6 The changes in this PR will be included in the next version bump. This PR includes changesets to release 14 packages
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 |
Deploying with
|
| Status | Name | Latest Commit | Updated (UTC) |
|---|---|---|---|
| ✅ Deployment successful! View logs |
docs | 6a94cb6 | Jun 16 2026, 02:39 PM |
@emdash-cms/admin
@emdash-cms/auth
@emdash-cms/auth-atproto
@emdash-cms/blocks
@emdash-cms/cloudflare
@emdash-cms/contentful-to-portable-text
emdash
create-emdash
@emdash-cms/gutenberg-to-portable-text
@emdash-cms/plugin-cli
@emdash-cms/plugin-types
@emdash-cms/registry-client
@emdash-cms/registry-lexicons
@emdash-cms/sandbox-workerd
@emdash-cms/x402
@emdash-cms/plugin-ai-moderation
@emdash-cms/plugin-atproto
@emdash-cms/plugin-audit-log
@emdash-cms/plugin-color
@emdash-cms/plugin-embeds
@emdash-cms/plugin-field-kit
@emdash-cms/plugin-forms
@emdash-cms/plugin-webhook-notifier
commit: |
Deploying with
|
| Status | Name | Latest Commit | Updated (UTC) |
|---|---|---|---|
| ✅ Deployment successful! View logs |
emdash-playground | 6a94cb6 | Jun 16 2026, 02:40 PM |
Deploying with
|
| Status | Name | Latest Commit | Updated (UTC) |
|---|---|---|---|
| ✅ Deployment successful! View logs |
emdash-demo-cache | 6a94cb6 | Jun 16 2026, 02:40 PM |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What does this PR do?
The media library, library list, and the media picker modal loaded every grid item's full-size original through the media proxy (
/_emdash/api/media/file/{key}). On large libraries this made opening the library and searching for older items wait on full-resolution downloads (the 1 min+ in the issue). Media search itself is already server-side (since #1227); the bottleneck was the thumbnails, not the query.This routes same-origin raster images through Astro's runtime image endpoint (
/_image) to request a small resized rendition for the grid/list instead of the original. EmDash already wires this pipeline (the integration registers animage.remotePatternsentry scoped to the media route), so no new route or serving path is added.Behavior by environment:
@astrojs/cloudflarev13cloudflare-binding, auto-provisionedIMAGESbinding): the grid gets lightweight thumbnails.passthroughconfig) or the endpoint rejects the request (e.g. a site with no build-timesiteUrl, so the production remote pattern isn't registered):/_imageserves the original, and anonErrorhandler falls back to the original URL. Nothing renders worse than before.Details:
getMediaThumbnailUrl()builds the/_imageURL for same-origin raster images and passes through non-images (an icon renders), SVGs (vector), and external/provider URLs (already remote renditions).onLoaddimension backfill reads truenaturalWidth/naturalHeightrather than the thumbnail's.Because the thumbnails ride Astro's
/_imagepipeline, any future improvement to same-origin image transforms (for example making them work behind Cloudflare Access) benefits these thumbnails with no further change here.Closes #1488
Type of change
Checklist
pnpm typecheckpassespnpm lintpassespnpm testpasses (or targeted tests for my change)pnpm formathas been runAI-generated code disclosure
Screenshots / test output
pnpm lint:json0 diagnostics,pnpm typecheckclean,pnpm formatrun.