Images not loading in preview and production environments

Ever since we got this new toolbar at the top, sandbox, and dev server I’m noticing that everything is breaking.

For example, something as simple as having a blob storage url previously being able to work (in the old ui interface) no longer working in the new interface.

This is only when creating a new chat within an existing project already, duplicating the chat retains the previous ui. It also gives me this new UI in v0 when creating an entire new chat.

Can you share an example of a blob URL that works in old UI but fails in new? :pray: Are you seeing any specific error messages in the browser console?

Definitely, https://dffvbjym0pzmbkew.public.blob.vercel-storage.com/Website%20Template%203%20Images/3.%20Services/NEW_Hero_Service_ChiropracticAdjustments-compressed.webp

Here’s a screenshot of what I can see from my end in the builder as well.

An additional screenshot included of it confirming that the url is being used properly in the code.

Gotcha, let me pass it to our v0 engineering team.

Is it also the same on production or just the v0 preview?

It was initially only in development, but it’s now not displaying in production after publishing.

This is only occurring with the new UI

Gotcha - thanks for the info!

When you duplicate the chat, is it the same issue?

I’m curious, do you have a production environment I can look at?

It is the same issue even when duplicating the chat.

I also cannot restore a previous version of the project in the new UI…. Getting a An unexpected error occurred.

The original version has working images and then the bottom version is the new published version with the error (new ui)

Here’s the page in development env

I guess in production it is showing them, but I should be able to see them load in development too.

It keeps suggesting swapping to this but it’s not resolving the issue as well.

Tell the other chat to check its next.config.mjs and add one of these:

Option A (quick fix):

images: {
  unoptimized: true,
}

Option B (more precise):

images: {
  remotePatterns: [
    {
      protocol: "https",
      hostname: "abhlesfddt1bn11w.public.blob.vercel-storage.com",
    },
  ],
}

The giveaway in your screenshot is that you can see the alt text rendered (“Auto injury rehabilitation treatment”) but no image. That’s the classic sign of next/image blocking an external domain – it renders the <img> tag, the browser tries to load it through Next.js’s image optimization proxy, the proxy rejects it because the hostname isn’t allowed, and you’re left with a broken image showing alt text.

I believe I’ve identified the issue. This wasn’t a problem before, and I think it should be something within v0 that handles this for everyone who uses Blob storage, rather than having to set up images in a specific way.

Thinking about this, updating all the projects that use v0—around 90 pages across different projects—will take hours and cost a lot of tokens.

While resolving the issue is good news, I’d love to get it working again like it has for months. I’m 12k prompts deep into v0 right now, and today is the first time I’ve encountered this error.

The Root Cause: Next.js Image Optimization Proxy

When you use the Next.js <Image> component without unoptimized, it doesn’t load the image directly from the source URL. Instead, it routes the request through Next.js’s built-in image optimization API at /_next/image?url=...&w=...&q=.... This proxy fetches the original image, resizes/compresses it, converts it to modern formats (like WebP/AVIF), and then serves the optimized version to the browser.

The Problem: URL Encoding with Special Characters

Your Vercel Blob URLs contain complex path segments with encoded characters:

  • %20 for spaces (e.g., “Placeholder Images” becomes Placeholder%20Images)
  • %26 for ampersands (e.g., “Services & Conditions” becomes Services%20%26%20Conditions)

When the Next.js image optimizer receives this URL as a query parameter, it needs to double-encode it (since the URL itself becomes a parameter value in /_next/image?url=<encoded-blob-url>). This double-encoding process can mangle the %26 (ampersand) in particular, because the optimizer may interpret it as a query parameter separator (&) rather than a literal part of the path. The result is that the optimizer requests a subtly different (broken) URL from Vercel Blob, gets a 400/404 back, and the image fails to load.

What unoptimized Does

Adding unoptimized tells Next.js: “Skip the optimization proxy entirely. Just put the raw src URL directly into the HTML <img> tag.” The browser then fetches the image straight from Vercel Blob, which handles its own URL encoding perfectly fine. No double-encoding issue, no proxy in the middle - the image loads directly.

Trade-off: You lose automatic resizing/format conversion from Next.js, but since Vercel Blob is already serving compressed .webp files, the practical impact is minimal. The images are already optimized at the source.

images: {
unoptimized: true
}

This also fixes it.

1 Like

All right, a little update on this. I went ahead and published the changes for like three different projects that we’re having the same issue with the solution that I gave you the message above and I’m still experiencing the issues so I’m going to say that it’s probably not resolving the problem, but it did temporarily resolve it for one project

@pawlean just wanted to follow up on this to see if you had any udpates.

Thanks for sharing the workaround and digging deep on this, Andrew! :folded_hands:

I’ve passed this onto the v0 team who will continue to improve the experience for everyone :slight_smile: Hang tight!

Hey! To help debug your v0 project, could you share your v0 chat link?
It looks like https://v0.app/chat/... — you can copy it from your browser’s address bar while in the chat.

You’ll also need to unlist the chat so our team can view it — here’s how: Sharing | v0 Docs

This helps the team reproduce what you’re seeing much faster. Thanks!