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

Image Optimization API broken if loaderFile specified, even with loader: "default" #53415

Closed
1 task done
goguda opened this issue Aug 1, 2023 · 5 comments · Fixed by #53417
Closed
1 task done

Image Optimization API broken if loaderFile specified, even with loader: "default" #53415

goguda opened this issue Aug 1, 2023 · 5 comments · Fixed by #53417
Labels
bug Issue was opened via the bug report template. Image (next/image) Related to Next.js Image Optimization. locked

Comments

@goguda
Copy link
Contributor

goguda commented Aug 1, 2023

Verify canary release

  • I verified that the issue exists in the latest Next.js canary release

Provide environment information

Operating System:
      Platform: linux
      Arch: x64
      Version: #1 SMP PREEMPT_DYNAMIC Tue Jul 25 04:42:30 UTC 2023 (55520bc)
    Binaries:
      Node: 20.3.1
      npm: 9.8.1
      Yarn: 1.22.19
      pnpm: N/A
    Relevant Packages:
      next: 13.4.13-canary.8
      eslint-config-next: 13.4.12
      react: 18.2.0
      react-dom: 18.2.0
      typescript: 5.1.6
    Next.js Config:
      output: N/A

Which area(s) of Next.js are affected? (leave empty if unsure)

Image optimization (next/image, next/legacy/image)

Link to the code that reproduces this issue or a replay of the bug

https://codesandbox.io/p/sandbox/purple-pine-t7hhgl?file=%2Fnext.config.js%3A3%2C25

To Reproduce

Create an image-loader.js file with the following contents:

export default function loader({ src, width, quality }) {
  const defaultLoader = `/_next/image/?url=${encodeURIComponent(src)}&w=${Math.min(width, 1080)}&q=${quality || 75}`;

  return defaultLoader;
}

Specify default image loader with loaderFile in next.config.js:

...
images: {
  loader: 'default',
  loaderFile: 'image-loader.js'
}
...

Try loading an image in the browser with Image component. It will not load because of 404 errors (/_next/image does not exist).

You can also simply navigate to /_next/image in your browser, and instead of the API you are presented with the 404 HTML page.

Describe the Bug

Image Optimization API gets disabled even when specifying loader: 'default' with a custom loaderFile in next.config.js. Any calls to /_next/image result in a 404 error, in both development and production.

Expected Behavior

Image Optimization API should stay enabled when loader is explicitly set to 'default' (or undefined?).

Which browser are you using? (if relevant)

All Browsers

How are you deploying your application? (if relevant)

No response

@goguda goguda added the bug Issue was opened via the bug report template. label Aug 1, 2023
@github-actions github-actions bot added the Image (next/image) Related to Next.js Image Optimization. label Aug 1, 2023
@goguda
Copy link
Contributor Author

goguda commented Aug 1, 2023

I've found the culprit in packages/next/src/server/config.ts:338

images.loader is being overridden to 'custom' if a loaderFile is provided, even if 'default' is explicitly specified in next.config.js.

This is happening before the server API routes are getting initialized, hence the image optimization routes don't get initialized, resulting in the 404 errors above.

Removing this line has the API working as expected again.

This line is also unnecessary due to the check on line 327 anyways.

PR #53417

@styfle
Copy link
Member

styfle commented Aug 1, 2023

This is expected behavior because loaderFile is for 3rd party image optimization and therefore must disable built-in image optimization.

@styfle styfle closed this as not planned Won't fix, can't repro, duplicate, stale Aug 1, 2023
@goguda
Copy link
Contributor Author

goguda commented Aug 1, 2023

This is expected behavior because loaderFile is for 3rd party image optimization and therefore must disable built-in image optimization.

I think perhaps this behavior should be reconsidered and issue re-opened.

Maybe only actually disable the optimization API if loader is explicitly set to 'custom'. If it's 'default' or undefined, but a loaderFile is specified, it should remain enabled in my opinion.

What if someone wants to use the Image Optimization API for conversions, with a cache in front of it like CloudFront? A custom loader file makes sense in this case, while leaving the Image Optimization API enabled.

For example, consider this loaderFile:

export default function loader({ src, width, quality }) {

  return `https://mycloudfrontcdn.cloudfront.net/_next/image/?url=${encodeURIComponent(src)}&w=${Math.min(width, 1080)}&q=${quality || 75}`;
}

Where CloudFront points to the next.js servers.

We've been running our website this way for the past year with next-image-loader, but this package is now deprecated.

We were excited to find out this feature is now built-in, but were disappointed when we discovered it disables the image optimization API completely when a custom loaderFile is specified with no way to re-enable it. As such we've held off upgrading to the latest version of Next.js.

Again, please reconsider due to the situation above. I doubt it's just us that will run into this as more people try to adopt caching CDNs, but want to use the Next.js server to perform the optimizations themselves. Thank you 🙏

@github-actions
Copy link
Contributor

This closed issue has been automatically locked because it had no new activity for a month. If you are running into a similar issue, please create a new issue with the steps to reproduce. Thank you.

@github-actions github-actions bot locked as resolved and limited conversation to collaborators Aug 16, 2023
@styfle
Copy link
Member

styfle commented Aug 16, 2023

See my latest response on your PR here: #53417 (comment)

@kodiakhq kodiakhq bot closed this as completed in #53417 Aug 18, 2023
kodiakhq bot pushed a commit that referenced this issue Aug 18, 2023
…t` (#53417)

Image Optimization API currently does not work if a custom loaderFile is specified in next.config.js, even if loader is explicitly set to 'default', because it is currently being overridden to 'custom' simply because a loaderFile is specified. This is unnecessary and causing the Image Optimization API routes not to be initialized since the change to the config happens before the routes are initialized.

[Sandbox Reproduction](https://codesandbox.io/p/sandbox/purple-pine-t7hhgl?file=%2Fimage-loader.js%3A8%2C1)

- Fixes #53415
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
bug Issue was opened via the bug report template. Image (next/image) Related to Next.js Image Optimization. locked
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants