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

How to support local images on nextjs deploy? #94

Closed
jaisharx opened this issue Dec 18, 2021 · 7 comments · Fixed by #95
Closed

How to support local images on nextjs deploy? #94

jaisharx opened this issue Dec 18, 2021 · 7 comments · Fixed by #95
Labels
bug Something isn't working enhancement New feature or request question Question about usage of the library
Milestone

Comments

@jaisharx
Copy link

jaisharx commented Dec 18, 2021

I have been trying to get this image optimizer work for some of my side projects and it works for the externals urls with the domain added to the terraform and nextjs config files, but I also use images inside my public folder and they are not working.

The url params is like this for these requests: ?url=/static/learn/image-1.png&w=3840&q=75. But the endpoint just throws the error url" parameter is valid but upstream response is invalid which I've seen when the domain is not added.

I suspect one workaround for this would be to move to absolute urls for these, and then add the project url to the next config, but I don't want to go this route because locally imported images have nice placeholderBlur to them, and also switching to absolute urls would look ugly.

How does one work this out? I see that the nextjs example uses assets.vercel.com which I've already tried adding. But it still doesn't work. I thought that this issue might only be locally, and I pushed the local branch to the vercel, but the issue is still the same cause the url param above is the same I guess.

I love this custom image optimizer you guys have made, it is so simple to get started with and compared to the current pricing for vercel image optimization makes much more sense. But please help me out with this!!

@ofhouse
Copy link
Member

ofhouse commented Dec 18, 2021

Hi, yes our Next.js example should be exactly what you are looking for.

Looking at the code from the image-optimizer the error message appears for absolute paths only when the origin responds with a status code other than 200:
https://github.com/vercel/next.js/blob/3e83205eab208a5b4f53d4590e5ba33f42564a39/packages/next/server/image-optimizer.ts#L227

Can you check the origin file at <your-domain.com>/static/learn/image-1.png and verify that it responds with a 200 HTTP status?

@ofhouse ofhouse added the question Question about usage of the library label Dec 18, 2021
@jaisharx
Copy link
Author

Hey, thanks for replying so quickly!

Yes the image is indeed available under my own website URL, I've rechecked it with navigating to the url you suggested with real website domain. So something like this: www.mywebsitedomain.com/static/learn/image-1.png.

Does the images needs to be under the cloudfront domain that is generated by terraform? If yes how can I make my /public images be available under that??

@ofhouse
Copy link
Member

ofhouse commented Dec 20, 2021

No, the website domain with the original image is simply grabbed via fetch over http or https.
So there is no need to put the original image under the same CloudFront domain.

The module currently finds the domain for absolute paths with the Host-Header that is sent when an embedded image <img src="..." /> from your site is requested.

So the full request for an image must be:

Request URL: https://xyz.cloudfont.net/_next/image?url=%2Fstatic%2Flearn%2Fimage-1.png
Host: www.mywebsitedomain.com

The module then calculates the full URL for the the image from these two parameters and resolves it to: www.mywebsitedomain.com/static/learn/image-1.png.

On requests directly against the CloudFront distribution the Host header is the same as in the request, so opening https://xyz.cloudfont.net/_next/image?url=%2Fstatic%2Flearn%2Fimage-1.png directly in the browser would send the following request:

Request URL: https://xyz.cloudfont.net/_next/image?url=%2Fstatic%2Flearn%2Fimage-1.png
Host: xyz.cloudfont.net

From which the module then calculates the invalid original source URL: xyz.cloudfont.net/static/learn/image-1.png.


Since this behaviour is very confusing I plan to bring a new option to the module where you can define the baseDomain for absolute paths directly from the Terraform config instead of relying on the Host header.

@ofhouse ofhouse added this to the v12.0.1 milestone Dec 20, 2021
@ofhouse ofhouse added the enhancement New feature or request label Dec 20, 2021
@ofhouse ofhouse mentioned this issue Dec 20, 2021
2 tasks
@ofhouse ofhouse added the bug Something isn't working label Dec 20, 2021
@ofhouse
Copy link
Member

ofhouse commented Dec 20, 2021

Actually there is a bug in how the Host of the original image is determined.
I created a new example with next export and S3 to get more insight and saw a similar problem to what you reported.

Will try to get a fix published by tomorrow: #95

@jaisharx
Copy link
Author

Hey, thanks for being so humble through it.

One more question I've is there a way this module can support the locally imported images as well?
It is a recent feature in nextjs and tbh it is quite handy, the syntax for it is something like this:

import Image from 'next/image'
import profilePic from '../public/me.png'

function Home() {
  return (
    <>
      <h1>My Homepage</h1>
      <Image
        src={profilePic}
        alt="Picture of the author"
        // width={500} automatically provided
        // height={500} automatically provided
        // blurDataURL="data:..." automatically provided
        // placeholder="blur" // Optional blur-up while loading
      />
      <p>Welcome to my homepage!</p>
    </>
  )
}

Although it's not a big deal, but when importing images like this we get the nice placeholder blur, and width and height automatically. By the way I did do a little bit of debugging and the reason this way of importing is not working at the moment is because nextjs is appending some hash value after the image file path, so something like: "image-2.1e15263b" (where original name of the file is just image-2).

@ofhouse
Copy link
Member

ofhouse commented Dec 21, 2021

Yes, good point 👍
I will update the Next.js examples to also include samples for the blur option.

My hope is that they work out of the box once the bug is fixed, but we'll see 😅

@ofhouse
Copy link
Member

ofhouse commented Dec 21, 2021

Okay I've now released v12.0.1 that should fix the issue.

From my understanding it should work for you after upgrading to this release without further configuration.
If it still doesn't work, you could try the new next_image_base_origin option where you can statically define the base URL where absolute image paths should be resolved to:

module "next_image_optimizer" {
  source = "milliHQ/next-js-image-optimization/aws"

+ next_image_base_origin = "https://www.mywebsitedomain.com"
}

Feel free to reopen or comment to this issue if the problem still exists.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working enhancement New feature or request question Question about usage of the library
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants