ImageError: Unable to optimize image and unable to fallback to upstream image.
Answered
fardeen awais posted this in #help-forum
Hey guys i'm using i8n routing to make language switcher in my application. I use middleware. Every thing is fine in development. But when i deploy my application. In production, the image is not showing up. I can only see the alt text in production but in development i can see image with this error:
ImageError: Unable to optimize image and unable to fallback to upstream image.
Here is my config in my middleware.ts:
ImageError: Unable to optimize image and unable to fallback to upstream image.
Here is my config in my middleware.ts:
export const config = {
// Matcher ignoring/_next/and/api/matcher: ['/((?!api|_next/static|_next/image|favicon.ico).*)'],
}Answered by joulev
import lightLogo from "./path/to/xxx_light.webp"
<Image src={lightLogo} alt="Logo" />16 Replies
please make a minimal reproduction repository
This is my file structure. I just make an lang route to implement language internationalization. It is working fine but the image is not working in production. Only work in developement
Here is my middleware: import { NextResponse } from 'next/server'
import type { NextRequest } from 'next/server'
import { i18n } from './i18n-config'
import { match as matchLocale } from '@formatjs/intl-localematcher'
import Negotiator from 'negotiator'
function getLocale(request: NextRequest): string | undefined {
// Negotiator expects plain object so we need to transform headers
const negotiatorHeaders: Record<string, string> = {}
request.headers.forEach((value, key) => (negotiatorHeaders[key] = value))
// console.log(negotiatorHeaders);
// @ts-ignore locales are readonly
const locales: string[] = i18n.locales
// Use negotiator and intl-localematcher to get best locale
let languages = new Negotiator({ headers: negotiatorHeaders }).languages(
locales
)
// console.log(languages)
// console.log(
// console.log(
const locale = matchLocale(languages, locales, i18n.defaultLocale)
// console.log(
return locale
}
export function middleware(request: NextRequest) {
const pathname = request.nextUrl.pathname
// Check if there is any supported locale in the pathname
const pathnameIsMissingLocale = i18n.locales.every(
(locale) => !pathname.startsWith(
)
// console.log(pathnameIsMissingLocale);
// Redirect if there is no locale
if (pathnameIsMissingLocale) {
const locale = getLocale(request)
// e.g. incoming request is /products
// The new URL is now /en-US/products
return NextResponse.redirect(
new URL(
request.url
)
)
}
}
export const config = {
// Matcher ignoring
matcher: ['/((?!api|_next/static|_next/image|favicon.ico).*)'],
}
import type { NextRequest } from 'next/server'
import { i18n } from './i18n-config'
import { match as matchLocale } from '@formatjs/intl-localematcher'
import Negotiator from 'negotiator'
function getLocale(request: NextRequest): string | undefined {
// Negotiator expects plain object so we need to transform headers
const negotiatorHeaders: Record<string, string> = {}
request.headers.forEach((value, key) => (negotiatorHeaders[key] = value))
// console.log(negotiatorHeaders);
// @ts-ignore locales are readonly
const locales: string[] = i18n.locales
// Use negotiator and intl-localematcher to get best locale
let languages = new Negotiator({ headers: negotiatorHeaders }).languages(
locales
)
// console.log(languages)
// console.log(
Your locales : ${locales})// console.log(
Your locales : ${i18n.defaultLocale})const locale = matchLocale(languages, locales, i18n.defaultLocale)
// console.log(
Your locales : ${locale})return locale
}
export function middleware(request: NextRequest) {
const pathname = request.nextUrl.pathname
// Check if there is any supported locale in the pathname
const pathnameIsMissingLocale = i18n.locales.every(
(locale) => !pathname.startsWith(
/${locale}/) && pathname !== /${locale})
// console.log(pathnameIsMissingLocale);
// Redirect if there is no locale
if (pathnameIsMissingLocale) {
const locale = getLocale(request)
// e.g. incoming request is /products
// The new URL is now /en-US/products
return NextResponse.redirect(
new URL(
/${locale}${pathname.startsWith('/') ? '' : '/'}${pathname},request.url
)
)
}
}
export const config = {
// Matcher ignoring
/_next/ and /api/matcher: ['/((?!api|_next/static|_next/image|favicon.ico).*)'],
}
@joulev please make a minimal reproduction repository
I can see my image with this error. I can see my image incl logo and hero image in developement with this error but when i deploy it to the production i only see alt text which means images is not working
as i said, a minimal reproduction repository
@fardeen awais https://github.com/Fardeen-Awais/Alfarnex.com
this is indeed due to the middleware redirecting where it shouldn't have. im not confident with my regex skills though so can't edit that middleware, but you can check whether the request with
.webp or other image file extensions in the middleware body and use NextResponse.next()if (pathname.endsWith(".webp"))
return NextResponse.next()for example
Yeah i use webp formate in my logo
Does this make the problem:
@fardeen awais Does this make the problem:
if you don't want to change the existing middleware, you can also [import the image files statically](https://nextjs.org/docs/app/building-your-application/optimizing/images#local-images) which will work
import lightLogo from "./path/to/xxx_light.webp"
<Image src={lightLogo} alt="Logo" />Answer