Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Bug]: Using Image component and image server returns error #128

Open
1 task
bnjns opened this issue Apr 2, 2024 · 5 comments
Open
1 task

[Bug]: Using Image component and image server returns error #128

bnjns opened this issue Apr 2, 2024 · 5 comments
Labels
@astro-aws/adapter @astro-aws/constructs bug Something isn't working enhancement New feature or request

Comments

@bnjns
Copy link

bnjns commented Apr 2, 2024

💻

  • Would you like to work on a fix?

Input code

Something like this:

---
import { Image } from 'astro:assets'
import exampleImg from '../assets/image.png'
---
 
<Image src={exampleImg} />

Current and expected behavior

During build the src attribute is correctly set to use the image server (eg, /_image?href=%2F_astro%2Fimage.Y0Z6qWya.png&f=webp), but when rendering the lambda returns a 500 error, rather than the image itself.

In the server logs, we see this error:

[ERROR] TypeError: Component.render is not a function
    at Object.renderToStaticMarkup (file:///var/task/entry.mjs:55:30)
    at renderFrameworkComponent (file:///var/task/entry.mjs:1554:68)
    at async renderComponent (file:///var/task/entry.mjs:1744:10)
    at async renderComponentToString (file:///var/task/entry.mjs:1787:28)
    at async renderPage (file:///var/task/entry.mjs:1950:17)
    at async lastNext (file:///var/task/entry.mjs:23261:25)
    at async callMiddleware (file:///var/task/entry.mjs:22622:10)
    at async _RenderContext.render (file:///var/task/entry.mjs:23284:22)
    at async _NodeApp.render (file:///var/task/entry.mjs:23777:18)
    at async handler2 (file:///var/task/entry.mjs:27026:22)

Environment

  • Astro AWS version: 0.6.0
  • Astro version: 4.5.13
  • Node.js: 20.11.1
  • Yarn: 1.22.19
  • AWS CDK: N/A (don't use the CDK constructs)

Possible solution

No response

Additional context

I originally wondered if this was an issue with using sharp or swoosh, so followed the docs to just use a passthrough service but that didn't seem to help.

For now, we're able to bypass this by using an img tag and referencing the src attribute:

---
import exampleImg from '../assets/image.png'
---

<img src={exampleImg.src} />
@bnjns bnjns added bug Something isn't working needs triage labels Apr 2, 2024
Copy link
Owner

lukeshay commented Apr 4, 2024

We do not support Sharp or Squoosh yet. Because of that, image optimization does not work. I will add this to the backlog.

Related #93 #94

@bnjns
Copy link
Author

bnjns commented Apr 4, 2024

I was aware of those 2 issues, so I didn't expect it to work with sharp or swoosh, however I'm surprised it doesn't work with the passthrough image service as that doesn't/shouldn't do any image optimisation?

Admittedly, I know nothing about the internals of astro though!

Copy link
Owner

lukeshay commented Apr 4, 2024

It looks like we will have to implement ExternalImageService. I will have to do some research on how we should approach this.

@bnjns
Copy link
Author

bnjns commented Apr 8, 2024

I've just realised that of course this doesn't work - the default image service sets the url to /_image?href=%2F_astro... which routes to the SSR server, but that doesn't have access to the underlying images as those are exported in the client directory during build and so uploaded to S3.

This probably just needs a custom image service which replaces the url with just what's used for the href query parameter - this will just match the CloudFront routing rule for the static objects in S3. This obviously wouldn't allow any optimisation because it's bypassing the SSR lambda, but that might be okay until this adapter supports sharp/swoosh?

I'll try to throw a PoC together to give this a try.

@bnjns
Copy link
Author

bnjns commented Apr 8, 2024

I've managed to throw together a very barebones POC that works for us (stick this file in your astro root alongside your astro config file):

// image_service.ts
import type { ExternalImageService } from "astro";

const imageService: ExternalImageService<{}> = {
  getURL(options, imageConfig) {
    // Because this doesn't support transforming, we can discard anything that isn't the src attribute
    return typeof options.src === "object" ? options.src.src : options.src;
  },
  getHTMLAttributes(options, imageConfig) {
    const { src, format, quality, ...attributes } = options;
    return {
      ...attributes,
      loading: options.loading ?? "lazy",
      decoding: options.decoding ?? "async",
    };
  },
};

export default imageService;

Then updated our astro.config.mjs to use:

export default defineConfig({
  ...
  image: {
    service: {
      entrypoint: "./image_service",
    },
  },
})

Hopefully this helps for building an actual solution!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
@astro-aws/adapter @astro-aws/constructs bug Something isn't working enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

2 participants