Skip to content

fix(import): emit relative URLs from WordPress media import (#657)#673

Merged
ascorbic merged 1 commit intoemdash-cms:mainfrom
mvanhorn:fix/657-wordpress-import-relative-media-urls
Apr 27, 2026
Merged

fix(import): emit relative URLs from WordPress media import (#657)#673
ascorbic merged 1 commit intoemdash-cms:mainfrom
mvanhorn:fix/657-wordpress-import-relative-media-urls

Conversation

@mvanhorn
Copy link
Copy Markdown
Contributor

What does this PR do?

Fixes /_emdash/api/import/wordpress/media so it returns the same relative /_emdash/api/media/file/{key} URL form every other media endpoint uses, instead of pinning an absolute URL built from request.url.

Two failure modes followed from the divergence (see #657):

  1. INTERNAL_MEDIA_PREFIX = "/_emdash/api/media/file/" is matched with url.startsWith(...) in packages/core/src/media/normalize.ts, so absolute URLs fell through to the external-media branch and skipped the local provider's enrichment (dimensions, storage key, etc.).
  2. The absolute URL was pinned to whatever origin request.url carried at import time. In dev that's whichever port Astro auto-selected (4322 when 4321 was busy), so later renders on 4321 got ERR_CONNECTION_REFUSED. Behind a reverse proxy it pins the internal origin rather than the public one.

The fix follows option 1 from the issue: drop baseUrl, return the relative form, and remove the now-unused requestUrl parameter from importMediaWithProgress. The existingUrl (content-hash dedup reuse) branch gets the same treatment.

Closes #657

Type of change

  • Bug fix
  • Feature (requires maintainer-approved Discussion)
  • Refactor (no behavior change)
  • Translation
  • Documentation
  • Performance improvement
  • Tests
  • Chore (dependencies, CI, tooling)

Checklist

  • I have read CONTRIBUTING.md
  • pnpm typecheck passes (packages/core; upstream/main has unrelated failures in packages/admin and packages/cloudflare)
  • pnpm lint passes (28 pre-existing diagnostics, none introduced by this change)
  • pnpm test passes (3 unrelated pre-existing test failures on upstream/main in auth/passkey-verify-route and invite)
  • pnpm format has been run
  • I have added/updated tests for my changes (if applicable)
  • User-visible strings in the admin UI are wrapped for translation and pnpm locale:extract has been run (if applicable)
  • I have added a changeset (if this PR changes a published package)
  • New features link to an approved Discussion: https://github.com/emdash-cms/emdash/discussions/...

Note on tests: the route handler has no existing unit-test harness (the wordpress-import.test.ts integration test covers the CLI commands, not the HTTP route), and importMediaWithProgress is not exported. Happy to add a targeted test if you'd like - the cleanest path is probably to export the helper or spin up a minimal route harness. Let me know which direction fits the codebase.

AI-generated code disclosure

  • This PR includes AI-generated code

Screenshots / test output

N/A - change is URL format only.

…ms#657)

`/_emdash/api/import/wordpress/media` was building absolute URLs for
imported media by reading `request.url`, unlike every other media
endpoint which returns the relative `/_emdash/api/media/file/{key}`
form. Two failure modes followed:

1. `INTERNAL_MEDIA_PREFIX = "/_emdash/api/media/file/"` is matched with
   `url.startsWith(...)` in `media/normalize.ts`, so an absolute URL
   fell through to the external-media branch and skipped the local
   provider's enrichment (dimensions, storage key, etc.).
2. The absolute URL was pinned to whatever origin `request.url` carried
   at import time. In dev this is whichever port Astro auto-selected
   (4322 when 4321 was busy), so later renders on 4321 got
   `ERR_CONNECTION_REFUSED`. Behind a reverse proxy the origin is the
   internal one rather than the public one.

The fix follows option 1 from the issue: drop `baseUrl`, return the
relative form, and remove the now-unused `requestUrl` parameter from
`importMediaWithProgress`. The same fix applies to the `existingUrl`
branch (content-hash dedup reuse).
@changeset-bot
Copy link
Copy Markdown

changeset-bot Bot commented Apr 20, 2026

🦋 Changeset detected

Latest commit: 2a98c0e

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

This PR includes changesets to release 12 packages
Name Type
emdash Patch
@emdash-cms/cloudflare Patch
@emdash-cms/fixture-perf-site Patch
@emdash-cms/perf-demo-site Patch
@emdash-cms/cache-demo-site Patch
@emdash-cms/admin Patch
@emdash-cms/auth Patch
@emdash-cms/blocks Patch
@emdash-cms/gutenberg-to-portable-text Patch
@emdash-cms/x402 Patch
create-emdash Patch
@emdash-cms/plugin-embeds Patch

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

@pkg-pr-new
Copy link
Copy Markdown

pkg-pr-new Bot commented Apr 20, 2026

Open in StackBlitz

@emdash-cms/admin

npm i https://pkg.pr.new/@emdash-cms/admin@673

@emdash-cms/auth

npm i https://pkg.pr.new/@emdash-cms/auth@673

@emdash-cms/blocks

npm i https://pkg.pr.new/@emdash-cms/blocks@673

@emdash-cms/cloudflare

npm i https://pkg.pr.new/@emdash-cms/cloudflare@673

emdash

npm i https://pkg.pr.new/emdash@673

create-emdash

npm i https://pkg.pr.new/create-emdash@673

@emdash-cms/gutenberg-to-portable-text

npm i https://pkg.pr.new/@emdash-cms/gutenberg-to-portable-text@673

@emdash-cms/x402

npm i https://pkg.pr.new/@emdash-cms/x402@673

@emdash-cms/plugin-ai-moderation

npm i https://pkg.pr.new/@emdash-cms/plugin-ai-moderation@673

@emdash-cms/plugin-atproto

npm i https://pkg.pr.new/@emdash-cms/plugin-atproto@673

@emdash-cms/plugin-audit-log

npm i https://pkg.pr.new/@emdash-cms/plugin-audit-log@673

@emdash-cms/plugin-color

npm i https://pkg.pr.new/@emdash-cms/plugin-color@673

@emdash-cms/plugin-embeds

npm i https://pkg.pr.new/@emdash-cms/plugin-embeds@673

@emdash-cms/plugin-forms

npm i https://pkg.pr.new/@emdash-cms/plugin-forms@673

@emdash-cms/plugin-webhook-notifier

npm i https://pkg.pr.new/@emdash-cms/plugin-webhook-notifier@673

commit: 2a98c0e

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Fixes the WordPress media import API to return relative internal media URLs (consistent with the rest of core media endpoints), avoiding incorrect “external media” handling and origin/port pinning.

Changes:

  • Update /_emdash/api/import/wordpress/media to emit /_emdash/api/media/file/{key} (relative) for both newly imported and dedup-reused media.
  • Remove the now-unused request.url parameter from importMediaWithProgress.
  • Add a changeset documenting the patch fix.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 1 comment.

File Description
packages/core/src/astro/routes/api/import/wordpress/media.ts Stops building absolute URLs from request.url; always returns relative internal media file URLs.
.changeset/fifty-moments-grab.md Adds release note for the WordPress media import URL normalization fix.

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

Comment on lines +235 to 236
const existingUrl = `/_emdash/api/media/file/${existing.storageKey}`;
result.urlMap[attachment.url] = existingUrl;
Copy link

Copilot AI Apr 24, 2026

Choose a reason for hiding this comment

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

Consider adding a unit test to lock in the regression fix that this endpoint emits relative /_emdash/api/media/file/{key} URLs (both for dedup-reuse and newly uploaded media). The repo already unit-tests Astro route handlers by importing GET/POST directly (e.g. packages/core/tests/unit/astro/routes.test.ts), but there’s currently no coverage preventing this from drifting back to absolute URLs and breaking normalizeMediaValue’s internal-media detection.

Copilot uses AI. Check for mistakes.
Copy link
Copy Markdown
Collaborator

@ascorbic ascorbic left a comment

Choose a reason for hiding this comment

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

Thanks!

@ascorbic ascorbic merged commit 5a581d9 into emdash-cms:main Apr 27, 2026
33 checks passed
@emdashbot emdashbot Bot mentioned this pull request Apr 27, 2026
0aveRyan pushed a commit to 0aveRyan/emdash that referenced this pull request Apr 27, 2026
…ms#657) (emdash-cms#673)

`/_emdash/api/import/wordpress/media` was building absolute URLs for
imported media by reading `request.url`, unlike every other media
endpoint which returns the relative `/_emdash/api/media/file/{key}`
form. Two failure modes followed:

1. `INTERNAL_MEDIA_PREFIX = "/_emdash/api/media/file/"` is matched with
   `url.startsWith(...)` in `media/normalize.ts`, so an absolute URL
   fell through to the external-media branch and skipped the local
   provider's enrichment (dimensions, storage key, etc.).
2. The absolute URL was pinned to whatever origin `request.url` carried
   at import time. In dev this is whichever port Astro auto-selected
   (4322 when 4321 was busy), so later renders on 4321 got
   `ERR_CONNECTION_REFUSED`. Behind a reverse proxy the origin is the
   internal one rather than the public one.

The fix follows option 1 from the issue: drop `baseUrl`, return the
relative form, and remove the now-unused `requestUrl` parameter from
`importMediaWithProgress`. The same fix applies to the `existingUrl`
branch (content-hash dedup reuse).

Co-authored-by: Matt Van Horn <455140+mvanhorn@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

WordPress import: media endpoint returns absolute URLs, breaking internal-media recognition and port/origin changes

3 participants