Skip to content

fix(image): emit /_next/image URLs#1562

Merged
james-elicx merged 3 commits into
mainfrom
fix/next-image-path
May 26, 2026
Merged

fix(image): emit /_next/image URLs#1562
james-elicx merged 3 commits into
mainfrom
fix/next-image-path

Conversation

@james-elicx
Copy link
Copy Markdown
Member

@james-elicx james-elicx commented May 22, 2026

Refs #1513 — URL prefix rename only. Follow-up issue: #1570.

Summary

  • Switch the default next/image loader, optimization endpoint route match, and generated Cloudflare Workers entries from /_vinext/image to /_next/image so emitted URLs and the server route match Next.js canonical behavior.
  • IMAGE_OPTIMIZATION_PATH constant now exports /_next/image.
  • Examples (apps/web, examples/app-router-cloudflare, examples/app-router-playground) and README updated to the new prefix.

Out of scope (tracked in #1570)

  • On-the-fly image optimization at /_next/image (or Cloudflare Images proxy). The endpoint currently still returns 400 / text/html; only the URL rename is in this PR.

Do not close #1513 when this PR merges — close it when #1570 also lands.

Test plan

  • Added a focused reproduction test (tests/image-component.test.ts → "default loader emits /_next/image URLs (issue next/image: default loader emits /_vinext/image instead of /_next/image optimization endpoint #1513)") asserting imageOptimizationUrl() and <Image> SSR src use the /_next/image prefix.
  • Updated existing test fixtures across tests/shims.test.ts, tests/image-component.test.ts, tests/image-optimization-parity.test.ts, tests/deploy.test.ts, and tests/pages-router.test.ts.
  • vp check passes.

Closes #1513

The default image loader and optimization endpoint switched from the
vinext-specific /_vinext/image path to Next.js's canonical /_next/image.
This unblocks the deploy suite tests that import Next.js's expected
URL shape (/_next/image?url=...&w=...&q=...).
@james-elicx
Copy link
Copy Markdown
Member Author

/bigbonk review

@pkg-pr-new
Copy link
Copy Markdown

pkg-pr-new Bot commented May 22, 2026

Open in StackBlitz

npm i https://pkg.pr.new/vinext@1562

commit: caa2906

@github-actions
Copy link
Copy Markdown

Example Preview Production Original
app-router-cloudflare preview production
pages-router-cloudflare preview production
app-router-playground preview production original
realworld-api-rest preview production
nextra-docs-template preview production
benchmarks preview production
hackernews preview production original
web preview production

Copy link
Copy Markdown
Contributor

@ask-bonk ask-bonk Bot left a comment

Choose a reason for hiding this comment

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

Clean, mechanical rename — LGTM.

Verified:

  • Zero remaining /_vinext/image references in production code. The 3 remaining occurrences in tests/image-component.test.ts are intentional negative assertions (regression guards for #1513).
  • IMAGE_OPTIMIZATION_PATH constant updated correctly.
  • TPR filter change in tpr.ts is correct: the old single-underscore /_vinext/ prefix no longer exists anywhere in the codebase, so replacing it with /__vinext/ (double underscore, used for internal prerender endpoints) keeps the filter accurate.
  • All hardcoded comparison sites (index.ts, deploy.ts, app-rsc-handler.ts) are updated consistently.

One minor observation (not blocking): index.ts:2800, deploy.ts:505,641, and app-rsc-handler.ts:447 hardcode "/_next/image" instead of importing IMAGE_OPTIMIZATION_PATH. prod-server.ts already uses the constant. Not worth blocking on since this PR is a focused rename, but worth consolidating later to avoid future drift.

@ask-bonk
Copy link
Copy Markdown
Contributor

ask-bonk Bot commented May 22, 2026

Review posted and approved on PR #1562. Here's the summary:

Approved — clean, mechanical rename with no issues found.

Key things verified:

  • Zero remaining /_vinext/image in production code (3 occurrences in tests are intentional negative assertions)
  • IMAGE_OPTIMIZATION_PATH constant updated correctly
  • TPR filter change (/_vinext/ -> /__vinext/) is correct — the old single-underscore prefix is fully gone from the codebase; double-underscore is used for internal prerender endpoints
  • All hardcoded comparison sites across index.ts, deploy.ts, app-rsc-handler.ts updated consistently

Left a non-blocking note about consolidating the hardcoded "/_next/image" strings to use the IMAGE_OPTIMIZATION_PATH constant (like prod-server.ts already does) to avoid future drift.

github run

…ll sites

Replace hardcoded "/_next/image" strings in index.ts, app-rsc-handler.ts,
and the generated worker entry templates in deploy.ts with the
IMAGE_OPTIMIZATION_PATH constant from server/image-optimization, matching
the pattern already used in prod-server.ts. Prevents future drift if the
path ever changes again.
…izer

Add a VINEXT_IMAGE_OPTIMIZATION_PATH constant and an
isImageOptimizationPath() helper, then route through every match site
(prod-server, dev server passthrough, app RSC handler, generated worker
templates, and shipped example workers). Apps that wire image URLs to
either prefix now hit the same handler; new URLs are still emitted via
IMAGE_OPTIMIZATION_PATH.
@james-elicx
Copy link
Copy Markdown
Member Author

/bigbonk review

Copy link
Copy Markdown
Contributor

@ask-bonk ask-bonk Bot left a comment

Choose a reason for hiding this comment

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

LGTM — clean rename with good backward compatibility.

What changed across the 3 commits:

  1. Commit 1 (8092463): Mechanical rename from /_vinext/image to /_next/image across all production code, examples, and tests.
  2. Commit 2 (51c7cef): Consolidates the remaining hardcoded "/_next/image" strings in index.ts, app-rsc-handler.ts, and deploy.ts to use isImageOptimizationPath() — addressing the non-blocking note from the first review.
  3. Commit 3 (caa2906): Adds VINEXT_IMAGE_OPTIMIZATION_PATH constant and isImageOptimizationPath() helper to accept both /_next/image and /_vinext/image at all match sites, providing backward compat for apps wired to the old prefix.

Verified:

  • Zero hardcoded "/_next/image" or "/_vinext/image" string comparisons remain in production code outside image-optimization.ts. All match sites use isImageOptimizationPath().
  • imageOptimizationUrl() in shims/image.tsx:274 correctly emits /_next/image for newly generated URLs — only the server-side acceptors are dual-path.
  • tpr.ts:468 filter change is correct: old /_vinext/ prefix (single underscore) no longer exists in the codebase; replaced with /__vinext/ (double underscore) which is the internal prerender endpoint prefix used throughout build/prerender.ts, server/prod-server.ts, server/pages-i18n.ts, and server/app-rsc-request-normalization.ts.
  • The /_next/ filter in tpr.ts now covers the image optimization path since it was renamed from /_vinext/image to /_next/image.
  • All remaining /_vinext/image references (10 total) are in test files — either testing the backward-compat alias, asserting VINEXT_IMAGE_OPTIMIZATION_PATH, or negative assertions guarding against regression (#1513).
  • The isImageOptimizationPath helper correctly uses strict equality (no prefix matching) so it won't accidentally match /_next/image.png or /_next/image/.
  • Worker entry examples (apps/web, app-router-cloudflare, app-router-playground) and generated entries (deploy.ts) all switched from inline string comparison to the helper import.

CI is green on all completed checks (Check, E2E, deploys, smoke tests). Vitest shards still in progress but no concerns given the mechanical nature of the changes.

@ask-bonk
Copy link
Copy Markdown
Contributor

ask-bonk Bot commented May 26, 2026

Review posted and approved on PR #1562.

Summary: This is a well-structured 3-commit PR that renames the image optimization endpoint from /_vinext/image to /_next/image (matching Next.js canonical behavior), consolidates all match sites to use a shared isImageOptimizationPath() helper, and adds backward compatibility for the old /_vinext/image prefix. No issues found — the rename is complete, the backward compat is properly scoped (accept both, emit only /_next/image), and the TPR filter update is correct.

github run

@james-elicx james-elicx merged commit 61cf2e7 into main May 26, 2026
38 checks passed
@james-elicx james-elicx deleted the fix/next-image-path branch May 26, 2026 09:28
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

next/image: default loader emits /_vinext/image instead of /_next/image optimization endpoint

1 participant