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

No image processing occurs after deployment (Cloudflare Pages) #1061

Open
AaronBeaudoin opened this issue Oct 19, 2023 · 29 comments
Open

No image processing occurs after deployment (Cloudflare Pages) #1061

AaronBeaudoin opened this issue Oct 19, 2023 · 29 comments

Comments

@AaronBeaudoin
Copy link

AaronBeaudoin commented Oct 19, 2023

Info

  • Operating System: Darwin
  • Node Version: v18.18.2
  • Nuxt Version: 3.8.0
  • CLI Version: 3.9.1
  • Nitro Version: 2.7.0
  • Package Manager: [email protected]
  • Builder: -
  • User Config: modules, nitro, experimental
  • Runtime Modules: @nuxt/[email protected]
  • Build Modules: -

Reproduction

https://github.com/AaronBeaudoin/nuxt-image-issue-1

Description of Issue

In the reproduction above there is a minimal app.vue like this:

<template>
  <div>
    <h1>Nuxt Image Test</h1>
    <NuxtImg src="/cat.jpg" width="1024" quality="1"/>
  </div>
</template>

As you can see, the quality is set to 1. This is so that you can see very obviously that image processing is occurring. If you run npm run dev you'll see that the image looks like crap, so you know that IPX is working great.

aryse local_3000_

But now, deploy the reproduction to Cloudflare Pages. After doing so, go to the deployed URL and you'll see this:

nuxt-image-issue-1 pages dev_

Obviously image processing is not working.

@DavidDeSloovere
Copy link

What's the url of the images in production? Is it something like /_ipx/... ?

@AaronBeaudoin
Copy link
Author

No, the URL is still just /cat.jpg.

The reproduction is right there. Deploy it and see for yourself.

@DavidDeSloovere
Copy link

Indeed.

Deployed to Cloudflare: not working, are rather the src was not changed
<img src="/cat.jpg" onerror="this.setAttribute('data-error', 1)" width="1024" data-nuxt-img="" srcset="/cat.jpg 1x, /cat.jpg 2x">

Deployed to Vercel: working
<img src="/_vercel/image?url=/cat.jpg&amp;w=1024&amp;q=1" onerror="this.setAttribute('data-error', 1)" width="1024" data-nuxt-img="" srcset="/_vercel/image?url=/cat.jpg&amp;w=1024&amp;q=1 1x, /_vercel/image?url=/cat.jpg&amp;w=1536&amp;q=1 2x">

Maybe IPX doesn't run on CF runtime?
Maybe something here with the baseUrl? https://github.com/nuxt/image/blob/58c5139106ed1552a98d318b5ca281e298c36180/src/runtime/providers/ipx.ts#L28C1-L30C4

@adamskyle
Copy link

We're having the same issue with Deno Deploy and Cloudflare Pages combined with the IPX provider. Works fine with self hosted PM2 & Vercel for example.

Have managed to solve this somehow using a different configuration or setting?

@AaronBeaudoin
Copy link
Author

@adamskyle My current alternative until this is fixed is the following Custom Provider for Cloudflare Images:

import { encodeQueryItem, joinURL } from "ufo";
import { createOperationsGenerator } from "#image";
import type { ProviderGetImage } from "@nuxt/image";

const operationsGenerator = createOperationsGenerator({
  keyMap: {
    width: "w",
    height: "h"
  },
  joinWith: ",",
  formatter: (key: string, value: string) => {
    return encodeQueryItem(key, value);
  }
});

export const getImage: ProviderGetImage = (src, options) => {
  const base = "https://imagedelivery.net/<YOUR_ACCOUNT_HASH>";
  const operations = operationsGenerator(options.modifiers);
  return { url: joinURL(base, src, operations) };
};

Replace <YOUR_ACCOUNT_HASH> with your value from the Cloudflare Images dashboard page. Also, you should be able to add options in addition to width and height to the keyMap config by following the docs here.

Managing the images this way is a lot more tedious than just storing them in the repository though.

@shayr1
Copy link

shayr1 commented Oct 31, 2023

I am not using cloudflare, but I had a similar problem with SSR and PM2, where images were not loading. I installed sharp as a dev dependency (e.g. yarn add -D sharp) and after build it worked.

@rahulkumarsingh73690
Copy link

Same problem

@cfab
Copy link

cfab commented Dec 8, 2023

same here with netlify !

@Bjornftw
Copy link

Bjornftw commented Dec 8, 2023

Any updates about this bug?

@adamskyle
Copy link

Just using the workaround suggested by @AaronBeaudoin at the moment.

Would love to contribute but I'm afraid this is a bit ambitious for a first PR here for me. Could be a bug in nuxt-image, but I can't rule out ipx or even nitro.

Some insights / attention from the nuxt team would be really great, the reproduction speaks for itself I think.

@nathanchase
Copy link
Contributor

Same here. If I have a <NuxtImg provider="cloudflare">, it resizes using Cloudflare fine, but if I have a <NuxtImg provider="ipx">, it does not work. The HTML renders out a path to /_ipx/..., but the image is 404. It works perfectly fine locally - it just breaks when deployed on Cloudflare pages.

@nathanchase
Copy link
Contributor

FWIW, I believe this is a Sharp limitation: lovell/sharp#2863

@DavidDeSloovere
Copy link

DavidDeSloovere commented Dec 30, 2023

Looks like it is indeed sharp (or unjs/ipx which uses sharp)
See also unjs/ipx#190 where it is also noted as following:
It is still Node.js only. Workers without thread support do not work!

CF Workers and Pages seems to be single threaded.

@youkei-zzz
Copy link

I unexpectedly ran into the same issue when I tried to deploy a page on GitHub pages

@DavidDeSloovere
Copy link

@nathanchase What's your workaround like with the provider="cloudflare" ? Or is it the same as #1061 (comment) where you need to upload the images to cloudflare separately?

@nathanchase
Copy link
Contributor

@nathanchase What's your workaround like with the provider="cloudflare" ? Or is it the same as #1061 (comment) where you need to upload the images to cloudflare separately?

My workaround at the moment is to not use ipx in production if deployed to Cloudflare Pages, but use some other image provider (like Cloudflare themselves, or weserv, or imagekit, or any others that do the processing elsewhere).

@Fifciu
Copy link

Fifciu commented Mar 17, 2024

Doesn't the following comment solve an issue for you?

@jbgosselin
Copy link

I'm also experiencing this issue, I would like to not build an entirely static website and want to benefits of ipx pre-rendered images. I think I found a temporary solution for it.
Following the documentation of this page https://image.nuxt.com/advanced/static-images, it seems that if the route of the images are declared as pre-rendered it will work.
I found a way to autogenerate them by using this configuration in nuxt.config.ts

{
    image: {
        provider: 'ipxStatic',
    },
    modules: [
        "@nuxt/image",
        "nitro-cloudflare-dev",
    ],
    nitro: {
        preset: "cloudflare-pages",
        prerender: {
            routes: ['/'],
            crawlLinks: true,
        },
    },
}

By defining ipxStatic as a provider, it forces @nuxt/image to create the pages for the images and with crawlLinks: true and a sensible routes configuration, it will crawl all the images and pre-render them.

It would be great that we could have a config that just automatically tags the ipx images as pre-rendered but that's all I found for now.

@mattgrah-am
Copy link

has anyone come up with a solution for this?

@rahulkumarsingh73690
Copy link

Any update? Even Cloudflare workers paid plan doesn't help.

@zonistefano
Copy link

I'm having the same problem. Already tried all the suggested fixes but nothing worked.

@DavidDeSloovere
Copy link

Looks like it is indeed sharp (or unjs/ipx which uses sharp) See also unjs/ipx#190 where it is also noted as following: It is still Node.js only. Workers without thread support do not work!

CF Workers and Pages seems to be single threaded.

@cf-wasm/photon might work as replacement for IPX on workers

@duncandejong
Copy link

Same issue here. Hopefully someone finds a solution.

@andreyquerino
Copy link

andreyquerino commented Aug 9, 2024

I managed to solve the problem by changing the build command from npm run build to npm run generate.

If you are building a static site using nuxt generate, Nuxt Image will optimize and save your images locally when your site is generated - and deploy them alongside your generated pages. Nuxt Images

nuxt ^3.12.4
@nuxt/image ^1.7.0

My project is a simple blog using @nuxt/content.

@laborb-hs
Copy link

Any news on that issue? I'm using a headless API and serving the content to a nuxt 3 app.

Locally I'm using the image provider ipx which is working fine with npm run dev.

Deployed to CF Pages I tried ipx, ipxStatic, cloudflare as providers, the last two worked in that manner, as they changed the images path. But no images are generated at all.
Provider ipx didn't throw an error but also didn't do anything.
I added both domains local and remote to the config.

"@nuxt/image": "^1.8.1",
"nuxt": "^3.13.2",

The resulting links always end in 404s.

As I understand the docs even this minimal config

    image: {
        format: ['webp'],
        quality: 80,
        domains: ['https://local-domain', 'https://remote-domain']
    },

should work, as the default provider is IPX.

`

16:23:55.367 ✨ Upload complete!
16:23:57.572 Success: Assets published!
16:24:03.999 Success: Your site was deployed!

`
But the image urls remain original and are not processed on the deployed site.

As I've read, maybe it will never work on CF (with ipx and ipxStatic), because it is single-threaded und we would need at least one other thread for the ipx-resizing server?

Ok, then I would like to use https://image.nuxt.com/providers/cloudflare so the CF image provider, as we are already using the Pages Provider there.

It says: "To use this provider you just need to specify the base url (zone) of your service"
So in CF in "Images/Transformations" I activated one "zone". This has a normal url.
and adjusted the image config in the nuxt-config:

image: { provider: process.env.ENV === 'local' ? "ipx" : "cloudflare", cloudflare: { baseURL: 'https://zone-url' }, format: ['webp'], quality: 80, domains: ['https://local-domain', 'https://remote-domain', 'https://zone-url'] },
When deployed i get links like "https://[zone-url]/cdn-cgi/image/w=628,f=webp,q=80/https://[remote-domain]/assets/img-ci8t2q1gfag2i8k21wc7pmug.png"
which result in a 404.

Has anyone got the Nuxt-Image module working on CF?

@andreyquerino
Copy link

@laborb-hs

In a recent project, I managed to use R2 Object Storage together with Cloudflare Images.

I created a bucket in R2 with the images, in the settings:

  • I've enabled public access.
  • I configured a domain (img.example.com), or I could use the domain provided by Cloudflare R2.
  • I configured the CORS policy to allow the connected domain.
// CORS policy

[
  {
    "AllowedOrigins": [
      "http://localhost:3000",
      "https://img.example.com"
    ],
    ...
  }
]

In Cloudflare Images, I chose the free plan (1,000 source image requests) and enabled it to be used in the bucket created in R2.

I was then able to manipulate the images.
exemple: https://img.example.com/cdn-cgi/image/w=400,f=webp/avatar.png

Configuration in Nuxt js

// nuxt.config.ts
image: {
  cloudflare: {
    baseURL: 'https://img.example.com',
  },
},
<!-- app.vue -->
<NuxtImg
  src="/avatar.png" alt="test image" width="400"
  provider="cloudflare" format="webp" loading="lazy" :modifiers="{ fit: 'contain' }"
/>

Output

<img alt="test image" loading="lazy" data-nuxt-img="" src="https://img.example.com/cdn-cgi/image/w=400,f=webp/avatar.png">

@laborb-hs
Copy link

laborb-hs commented Oct 24, 2024

Thanks for the explanation, in our case the images are uploaded and managed in a third party CMS outside of Cloudflare.

I'm getting the absolute urls of the images passed to the nuxt app.

I activated the paid plan for testing, got an https://imagedelivery.net/<account-hash>/<image_id>/<variant_name> Image Delivery URL.

Here would be the correct part in the docs, as we are just trying to transform images while serving: https://developers.cloudflare.com/images/transform-images/transform-via-url/

Which is understandable per se - but I found no documentation of how to use the transformation service from CF in the nuxt-config for the image module. Because the Nuxt-Image Module would be the one, who would concatenate the correct urls with its parameters.

If I'm following the CF docs I would then create my own nuxt-image service, which is not the intention of using the nuxt-image module...

@danielunited
Copy link

I was dealing with this issue for days. Finally got it working by setting:

  • npm run generate for deploy
  • ipx as the image provider
  • Cleared the preset for Nitro (e.g. Cloudflare Pages)

@mradenkovic
Copy link

I was dealing with this issue for days. Finally got it working by setting:

  • npm run generate for deploy
  • ipx as the image provider
  • Cleared the preset for Nitro (e.g. Cloudflare Pages)

Thats the solution, finally thanks !!!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests