Skip to content

fix(@astrojs/cloudflare): fix imageService: 'compile' silent noop with prerenderEnvironment: 'node'#17347

Open
astrobot-houston wants to merge 2 commits into
mainfrom
triagebot/fix-17346
Open

fix(@astrojs/cloudflare): fix imageService: 'compile' silent noop with prerenderEnvironment: 'node'#17347
astrobot-houston wants to merge 2 commits into
mainfrom
triagebot/fix-17346

Conversation

@astrobot-houston

Copy link
Copy Markdown
Contributor

Summary

Fixes a bug where imageService: 'compile' produced unoptimized images (byte-for-byte source copies with incorrect extensions, e.g. PNG bytes in a .webp file) when prerenderEnvironment was set to 'node'. No warning or error was emitted — the build completed silently.

Closes #17346

Root Cause

Two interacting issues:

  1. collectStaticImages only existed on the workerd prerenderer. This method installs sharp (or a user-configured image service) into globalThis.astroAsset.imageService before the image generation pipeline runs. When prerenderEnvironment: 'node', the default Node prerenderer was used instead — which had no collectStaticImages, so image transforms fell back to the workerd passthrough stub, returning input buffers unchanged.

  2. The default prerender entrypoint was skipped when setPrerenderer was called. Astro skips setting the prerender entrypoint when settings.prerenderer is truthy, so restoring it manually was also required.

Fix

In packages/integrations/cloudflare/src/index.ts:

  • astro:build:start hook — Added an else if (hasBuildImageService) branch for prerenderEnvironment: 'node'. Wraps the default prerenderer with a collectStaticImages method that installs sharp (or the user's custom service) before image generation runs, mirroring the existing workerd prerenderer behavior.

  • astro:build:setup hook — Restores the default prerender entrypoint when prerenderEnvironment: 'node' and hasBuildImageService are both true, since it gets skipped when setPrerenderer is called.

Before: (before: 12kB, after: 12kB) — output .webp is actually PNG bytes
After: (before: 12kB, after: 0kB) — proper WebP output (~494 bytes)

Testing

Added packages/integrations/cloudflare/test/compile-image-service.test.ts with tests covering:

  • imageService: 'compile' with prerenderEnvironment: 'node' (the bug scenario)
  • User-configured custom image service with prerenderEnvironment: 'node'

All existing tests continue to pass.

… node (#17346)

When `imageService: 'compile'` was used with `prerenderEnvironment: 'node'`,
images were silently copied without optimization (PNG bytes in .webp files).

The root cause was that `collectStaticImages` — which installs sharp for
build-time transforms — only ran in the workerd prerenderer path. The node
prerender path used the workerd passthrough stub instead.

Fix: wrap the default prerenderer with a `collectStaticImages` method that
installs sharp (or the user's custom service) before image generation runs,
and restore the default prerender entrypoint that gets skipped when
`settings.prerenderer` is set.
@changeset-bot

changeset-bot Bot commented Jul 10, 2026

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: fffb454

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

This PR includes changesets to release 40 packages
Name Type
@astrojs/cloudflare Patch
@test/astro-cloudflare-node-prerender-mdx Patch
@test/astro-cloudflare Patch
@test/astro-cloudflare-allowed-hosts Patch
@test/astro-cloudflare-astro-dev-platform Patch
@test/astro-cloudflare-astro-env Patch
@test/astro-cloudflare-binding-image-service Patch
@test/astro-cloudflare-cache-provider-wait-until Patch
@test/astro-cloudflare-cache-provider Patch
@test/astro-cloudflare-client-address Patch
@test/astro-cloudflare-compile-custom-image-service Patch
@test/astro-cloudflare-compile-image-service Patch
@test/astro-cloudflare-custom-entryfile Patch
@test/astro-cloudflare-dev-image-endpoint Patch
@test/astro-cloudflare-external-image-service Patch
@test/astro-cloudflare-external-redirects Patch
@test/astro-cloudflare-internal-redirects Patch
@test/astro-cloudflare-no-output Patch
@test/astro-cloudflare-prerender-node-env Patch
@test/astro-cloudflare-prerender-queue-consumers Patch
@test/astro-cloudflare-prerender-styles Patch
@test/astro-cloudflare-prerenderer-errors Patch
@test/astro-cloudflare-prerenderer-render-error Patch
@test/routing-priority-cloudflare Patch
@test/cf-server-entry Patch
@test/astro-cloudflare-server-island-prerender-framework Patch
@test/astro-cloudflare-sessions Patch
@test/astro-cloudflare-sql-import Patch
@test/cf-ssr-deps Patch
@test/astro-cloudflare-static Patch
@test/astro-cloudflare-svelte-rune-deps Patch
@test/astro-cloudflare-top-level-return Patch
@test/cf-user-optimize-deps Patch
@test/astro-cloudflare-vite-plugin Patch
@test/astro-cloudflare-with-base Patch
@test/astro-cloudflare-with-react Patch
@test/astro-cloudflare-with-solid-js Patch
@test/astro-cloudflare-with-svelte Patch
@test/astro-cloudflare-with-vue Patch
@test/astro-cloudflare-wrangler-preview-platform 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

@github-actions github-actions Bot added the pkg: integration Related to any renderer integration (scope) label Jul 10, 2026
@ematipico ematipico self-assigned this Jul 10, 2026

@adamchal adamchal 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.

@ematipico embarrassed I missed this one. Got a little fixated on the workerd prerenderer!

Read through the fix and it seems logical and the tests look good.

I also tested this fix locally to make sure that it does not regress anything in #17099 or #17285 on the workerd side.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

fix verified Reporter confirmed the triage bot fix works pkg: integration Related to any renderer integration (scope)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

@astrojs/cloudflare: imageService: 'compile' is a silent noop with prerenderEnvironment: 'node'

3 participants