Skip to content

Static builds bypass the ImageKit fast-path: <Image> emits local /_astro/ URLs then fails with ENOENT #4

Description

@subblue

Environment

  • @imagekit/astro 1.0.1
  • astro 6.4.5
  • output: 'static'

Summary

In static builds, ImageKit-path srcs passed to <Image /> are never turned into ImageKit URLs.

Dev behaves as documented; astro build instead routes every image through Astro's build-time generation, emits a local /_astro/... URL, and fails with ENOENT because the source file doesn't exist locally.

Reproduction

// astro.config.mjs
import { defineConfig } from "astro/config"
import imagekit from "@imagekit/astro/integration"

export default defineConfig({
  integrations: [imagekit({ urlEndpoint: "https://ik.imagekit.io/<id>" })],
})
---
import { Image } from "astro:assets"
---
<Image src="/some-folder/photo.jpg" width={800} height={600} alt="test" />

(/some-folder/photo.jpg exists in the ImageKit media library, not locally.)

Dev output (correct):

<img src="https://ik.imagekit.io/<id>/some-folder/photo.jpg?tr=c-at_max,w-800" ...>

Build output (wrong), followed by a hard failure:

<img src="/_astro/photo_1u4BnC.jpg" ...>
Error generating image for /some-folder/photo.jpg: 
ENOENT: no such file or directory, open '<project>/dist/some-folder/photo.jpg'

Root cause

The service registers sharp's transform/parseURL hooks for non-ImageKit srcs, so Astro core's isLocalService() classifies it as a local service.

In prerendered builds, getImage() (astro/dist/assets/internal.js, the isLocalService(service) && globalThis.astroAsset.addStaticImage branch) then re-routes every non-http(s) src into addStaticImage(), discarding the URL getURL() returned and queueing local generation that reads from dist/ — hence the ENOENT. The dev/SSR /_image endpoint flow never hits this branch, which is why dev works.

Full https://ik.imagekit.io/... srcs are also affected: getURL() returns a transformed URL different from the src, so they fail the initialImageURL === validatedOptions.src escape hatch and get downloaded and re-optimized locally by sharp instead of being served from the CDN.

Expected behaviour

Static builds should emit the same ImageKit CDN URLs as dev/SSR for fast-path srcs.

Workaround

Bypass astro:assets and build URLs directly with buildSrc from @imagekit/javascript in a custom component.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    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