I decided to use NextJS for faster routing & image optimization. Unfortunately, some images won’t load properly on iOS devices. I have a scrollable horizontal container with Product Images.
Some of the images fall outside the visible area, therefore you need to scroll to see them.
On the web, it works without an issue. But when I test it on my iPhone (iOS 16)’s Safari browser, I noticed the images outside the visible area are not rendered at all. Let me show what I mean.
How it should be (Chrome Device Tool):
How it actually is on iOS 16:
Weird thing is, if I rotate my phone, it actually renders images.
I am using the Image/Next component with priority and unoptimized props set true. I’ve tried with and without both, but nothing changed.
I am using the latest NextJS for the front end. No other libraries at all. Backend is an express server but it only provides image pathways etc. The server is Nginx with reverse proxy.
Here is the React code:
import styles from "../styles/ProductItem.module.css";
import priceFormat from "../Helpers/priceFormat";
import Image from "next/image";
import Percentage from "./icons/Percentage";
import { useRouter } from "next/router";
function ProductItem(props) {
const router = useRouter();
let marginStyle = {};
if (props.noLeftMargin) marginStyle.marginLeft = 0;
if (props.noRightMargin) marginStyle.marginRight = 0;
return (
<div
className={`${styles.itemContainer} ${props.className}`}
style={marginStyle}
onClick={() => router.push("/product/" + props.data.id)}
>
<div className={styles.imageContainer}>
<Image
className={styles.productImg}
src={props.data.imgSmall}
width={160}
height={160}
alt={props.data.name}
priority={true}
unoptimized={true}
/>
{props.data.salePercentage > 0 && (
<div className={styles.percentageContainer}>
<Percentage className={styles.percentageSvg} />
<div className={styles.percentageOffText}>
{`%${props.data.salePercentage}`}
<br />
OFF
</div>
</div>
)}
</div>
<div className={styles.priceLabel}>
{props.data.salePercentage
? `$${priceFormat(
props.data.price * ((100 - props.data.salePercentage) / 100)
)}`
: `$${priceFormat(props.data.price)}`}
</div>
{props.data.salePercentage > 0 && (
<div className={styles.oldPrice}>{`$${priceFormat(
props.data.price
)}`}</div>
)}
<div className={styles.productName}>
{props.data.brand} {props.data.name}
</div>
</div>
);
}
export default ProductItem;
Here is the {data}
provided via props:
{
id: "ca629a01-7c58-49f1-949e-fad574c28b3e",
imgLarge: "/images/products/electronics_smartphone_1.jpg",
imgSmall: "/images/products/electronics_smartphone_1_small.jpg",
brand: "Chip",
options: [
{
name: "Storage",
values: ["64GB", "128GB", "256GB"],
affectsPrice: 1,
},
{
name: "Color",
values: ["black", "white", "gray", "red", "gold", "silver"],
affectsPrice: 0,
},
],
name: "Smartphone",
price: 684,
salePercentage: 0,
saleReason: "",
viewCount: 10438,
soldCount: 4706,
maincategory: "electronics",
rating: "3.60",
warranty: 2,
availableColors: ["silver", "gold", "red", "white"],
subcategory: "electronics_smartphone",
sellers: [....]
}
You can test my app here: Ertuway.com
2
Answers
For anyone in the future struggling with the same issue :
If you wrap the Image/Next within a container and if you give filter:drop-shadow effect to the container element, for some weird reason, Safari browsers won't render the images properly. Simply remove the filter: drop-shadow and you are good to go.
I struggled with this for 2 weeks now.
Remove any modification on
overflow-x
onbody,html,#__next
elements (or any parent elements)I dont know what was happening but I suspect that apple did something in the last ios update that caused this. (as the same site was working fine before)
Anyway removing
overflow-x: clip
from said elements fixed this for me.Hope it helps you too!