Skip to content

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

Description

@kitschpatrol

Astro Info

Astro                    v7.0.7
Node                     v26.4.0
System                   macOS (arm64)
Package Manager          pnpm
Output                   static
Adapter                  @astrojs/cloudflare
Integrations             none

If this issue only occurs in one browser, which browser is a problem?

No response

Describe the Bug

With imageService: 'compile' (or { build: 'compile', runtime: 'passthrough' }) and prerenderEnvironment: 'node', the build performs no image optimization: every generated variant is just a no-op copy of the source written under the requested format's extension — e.g. PNG bytes in a .webp file. No warning or error; the build completes normally.

The docs say compile:

Uses the configured image service or falls back to a combination of internal dependencies to transform images locally at build time for prerendered routes. The noop passthrough option is configured for on-demand rendered pages.

Explicitly configuring sharp by setting image.service.entrypoint to "astro/assets/services/sharp" doesn't help: hasUserImageService() treats astro/assets/services/sharp as not user-configured and discards it.

Workaround: imageService: 'custom' with an explicit image.service sharp entrypoint, but this is not ideal since the sharp node path won't work with runtime images, and 'custom' is not a valid value for the imageService.build key, so there's no way to define custom imageService.runtime behavior alongside a custom image service.

What's the expected result?

I'd expect a config like this to process images using Sharp via Node at build time, and then to use 'cloudflare-binding' via Workerd at runtime.

import { defineConfig } from "astro/config";
import cloudflare from "@astrojs/cloudflare";

export default defineConfig({
  adapter: cloudflare({
    prerenderEnvironment: "node",
    imageService: {
      build: "compile",
      runtime: "cloudflare-binding",
    },
  }),
  image: {
    service: {
      entrypoint: "astro/assets/services/sharp",
    },
  },
});

(Also the difference between custom and compile feels a bit murky. (It's like compile is implicitly custom if and only if a custom image service is defined?)

Link to Minimal Reproducible Example

https://github.com/kitschpatrol/repro-astro-cloudflare-image

Participation

  • I am willing to submit a pull request for this issue.

Metadata

Metadata

Assignees

No one assigned

    Labels

    - P3: minor bugAn edge case that only affects very specific usage (priority)pkg: cloudflareRelated to the Cloudflare adaptertriage: fix verifiedReporter confirmed the triage bot fix works

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions