From d2f3a96ddfd84739b7afa24611829da90022ef78 Mon Sep 17 00:00:00 2001 From: payacom <59262811+payacom@users.noreply.github.com> Date: Tue, 15 Sep 2026 18:40:45 +0330 Subject: [PATCH] Enable Next.js image optimization across ~60 remaining unoptimized spots MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Remove `unoptimized` from every Image that was pointing at a real remote/ static file (Reels image carousel, story avatars/viewer, shop product grids/details, chat shared-post/product/story bubbles, notification/ visitor rows, tag/mention pickers, etc.) so Next's own resize+avif/webp pipeline (already configured in next.config.ts) actually applies — previously only a handful of components used it, everything else shipped full-resolution originals regardless of the tiny thumbnail size shown - Add a `sizes` prop wherever `fill` was used without one, so the optimizer picks an appropriately small srcset entry instead of defaulting to 100vw - Fix ProfileAvatar to request the actual displayed size instead of always requesting 280x280 regardless of the `size` prop - Left `unoptimized` on the handful of genuinely local/ephemeral sources (blob:/data: URIs from in-progress uploads, third-party QR API images, static SVG icons) where Next's optimizer can't or shouldn't apply - Add next-story prefetch to StoryViewer (previously only Reels prefetched upcoming media; swiping to the next story always cold-started before) - Fix .claude/launch.json's dev server port (3000 -> 3004) to match package.json's actual `next dev --port 3004` Verified via `tsc --noEmit` (no new errors) and by diffing this app's console/network behavior against a git-stashed baseline in the browser preview — the one pre-existing hydration warning and 401s (unauthenticated session) are present on both, and /_next/image requests now succeed for avatars/thumbnails that previously bypassed optimization entirely. Co-Authored-By: Claude Sonnet 5 --- .claude/launch.json | 2 +- .../(projects)/projects/specialists/page.tsx | 2 -- src/app/settings/edit/archive/page.tsx | 1 - src/app/settings/edit/blocked-users/page.tsx | 2 +- .../[shopId]/products/[listingId]/page.tsx | 1 - src/app/shops/checkout/[orderId]/page.tsx | 1 - .../[listingId]/ListingDetailClient.tsx | 1 - src/app/shops/orders/[orderId]/page.tsx | 1 - src/app/shops/product/[catalogId]/page.tsx | 1 - .../profile/[shopId]/ShopProfileClient.tsx | 1 - .../MainBillboardCard/MainBillboardCard.tsx | 1 - src/components/chat/SharedPostBubble.tsx | 2 +- src/components/chat/SharedProductBubble.tsx | 2 +- src/components/chat/SharedStoryBubble.tsx | 2 +- src/components/explore/ExploreVideoThumb.tsx | 1 - src/components/explore/ReelsAcademyCard.tsx | 2 +- src/components/main/ProfileAvatar.tsx | 5 ++-- src/components/main/Services/ServiceItem.tsx | 1 - .../models/AppearanceColorSelect.tsx | 4 +-- .../models/MainModelCard/MainModelCard.tsx | 2 +- .../models/MainModelCard/SwipeImageSlider.tsx | 1 - .../models/ModelPage/ModelContentPosts.tsx | 2 -- .../models/ModelPage/ProfileUserListModal.tsx | 2 +- src/components/posts/PostLinkPicker.tsx | 2 +- src/components/posts/ReelsImageCarousel.tsx | 4 +-- src/components/posts/ReelsPostActions.tsx | 2 +- .../posts/ReelsPostAnalyticsModal.tsx | 2 +- src/components/posts/ReelsPostCard.tsx | 4 +-- src/components/posts/SendPostModal.tsx | 4 +-- src/components/posts/TagUsersPicker.tsx | 4 +-- .../projects/SpecialistCarousel.tsx | 2 -- .../projects/SpecialistsSearchModal.tsx | 2 -- src/components/settings/ActivityPostGrid.tsx | 1 - src/components/settings/NotificationRow.tsx | 2 +- src/components/settings/VisitorRow.tsx | 2 +- src/components/shops/ProductImageLightbox.tsx | 1 - src/components/shops/SendProductModal.tsx | 4 +-- .../shops/ShopProductCommentsModal.tsx | 2 +- src/components/shops/ShopProductListRow.tsx | 1 - src/components/shops/ShopReelsView.tsx | 1 - src/components/stories/SendStoryModal.tsx | 4 +-- src/components/stories/StoriesBar.tsx | 1 - src/components/stories/StoryMentionPicker.tsx | 2 +- src/components/stories/StoryViewer.tsx | 26 ++++++++++++++++--- 44 files changed, 54 insertions(+), 59 deletions(-) diff --git a/.claude/launch.json b/.claude/launch.json index 9ddb903..bc5aa17 100644 --- a/.claude/launch.json +++ b/.claude/launch.json @@ -5,7 +5,7 @@ "name": "modstagram-next-dev", "runtimeExecutable": "npm", "runtimeArgs": ["run", "dev"], - "port": 3000 + "port": 3004 } ] } diff --git a/src/app/(projects)/projects/specialists/page.tsx b/src/app/(projects)/projects/specialists/page.tsx index 12eacb9..bfe7fdb 100644 --- a/src/app/(projects)/projects/specialists/page.tsx +++ b/src/app/(projects)/projects/specialists/page.tsx @@ -97,7 +97,6 @@ function SpecialistCard({ fill className="object-cover" sizes={isMain ? "280px" : "120px"} - unoptimized /> ) ) : ( @@ -144,7 +143,6 @@ function SpecialistCard({ fill className="object-cover" sizes={isMain ? "64px" : "36px"} - unoptimized /> ) : (
diff --git a/src/app/settings/edit/archive/page.tsx b/src/app/settings/edit/archive/page.tsx index a3ff7ba..9acd654 100644 --- a/src/app/settings/edit/archive/page.tsx +++ b/src/app/settings/edit/archive/page.tsx @@ -152,7 +152,6 @@ function ArchivePage() { fill className="object-cover" sizes="50vw" - unoptimized /> )} diff --git a/src/app/settings/edit/blocked-users/page.tsx b/src/app/settings/edit/blocked-users/page.tsx index 9f13734..5feeb55 100644 --- a/src/app/settings/edit/blocked-users/page.tsx +++ b/src/app/settings/edit/blocked-users/page.tsx @@ -66,8 +66,8 @@ function BlockedUsersPage() { } alt="" fill + sizes="44px" className="object-cover" - unoptimized />
diff --git a/src/app/shops/[shopId]/products/[listingId]/page.tsx b/src/app/shops/[shopId]/products/[listingId]/page.tsx index 92c5781..9f97aac 100644 --- a/src/app/shops/[shopId]/products/[listingId]/page.tsx +++ b/src/app/shops/[shopId]/products/[listingId]/page.tsx @@ -296,7 +296,6 @@ export default function ProductManagePage() { fill className="object-cover" sizes="400px" - unoptimized />
))} diff --git a/src/app/shops/checkout/[orderId]/page.tsx b/src/app/shops/checkout/[orderId]/page.tsx index acf3815..22f63bc 100644 --- a/src/app/shops/checkout/[orderId]/page.tsx +++ b/src/app/shops/checkout/[orderId]/page.tsx @@ -96,7 +96,6 @@ export default function CheckoutPage() { fill className="object-cover" sizes="64px" - unoptimized /> )} diff --git a/src/app/shops/listing/[listingId]/ListingDetailClient.tsx b/src/app/shops/listing/[listingId]/ListingDetailClient.tsx index 40239db..ab54326 100644 --- a/src/app/shops/listing/[listingId]/ListingDetailClient.tsx +++ b/src/app/shops/listing/[listingId]/ListingDetailClient.tsx @@ -347,7 +347,6 @@ export default function ListingDetailClient() { fill className="object-cover" sizes="400px" - unoptimized /> ))} diff --git a/src/app/shops/orders/[orderId]/page.tsx b/src/app/shops/orders/[orderId]/page.tsx index 51bc082..b3ea7d8 100644 --- a/src/app/shops/orders/[orderId]/page.tsx +++ b/src/app/shops/orders/[orderId]/page.tsx @@ -356,7 +356,6 @@ export default function OrderDetailPage() { fill className="object-cover" sizes="64px" - unoptimized /> )} diff --git a/src/app/shops/product/[catalogId]/page.tsx b/src/app/shops/product/[catalogId]/page.tsx index df08b0e..d851c3f 100644 --- a/src/app/shops/product/[catalogId]/page.tsx +++ b/src/app/shops/product/[catalogId]/page.tsx @@ -85,7 +85,6 @@ export default function ProductComparisonPage() { fill className="object-cover" sizes="64px" - unoptimized /> {discountPercent != null && ( )} diff --git a/src/components/billboards/MainBillboardCard/MainBillboardCard.tsx b/src/components/billboards/MainBillboardCard/MainBillboardCard.tsx index 7cada18..47a204e 100644 --- a/src/components/billboards/MainBillboardCard/MainBillboardCard.tsx +++ b/src/components/billboards/MainBillboardCard/MainBillboardCard.tsx @@ -138,7 +138,6 @@ function MainBillboardCard({ height={120} alt={billboard?.title} src={`${IMAGE_BASE_URL}${billboard.images[0]}`} - unoptimized /> ) : (
diff --git a/src/components/chat/SharedPostBubble.tsx b/src/components/chat/SharedPostBubble.tsx index 7b8fc49..86ba5bf 100644 --- a/src/components/chat/SharedPostBubble.tsx +++ b/src/components/chat/SharedPostBubble.tsx @@ -52,8 +52,8 @@ export default function SharedPostBubble({ data }: { data: SharedPostPayload }) src={preview} alt="" fill + sizes="240px" className="object-cover" - unoptimized /> )}
diff --git a/src/components/chat/SharedProductBubble.tsx b/src/components/chat/SharedProductBubble.tsx index 87e5133..59ec736 100644 --- a/src/components/chat/SharedProductBubble.tsx +++ b/src/components/chat/SharedProductBubble.tsx @@ -38,7 +38,7 @@ export default function SharedProductBubble({ data }: { data: SharedProductPaylo > {preview && (
- +
)}
diff --git a/src/components/chat/SharedStoryBubble.tsx b/src/components/chat/SharedStoryBubble.tsx index 0ff1368..5642657 100644 --- a/src/components/chat/SharedStoryBubble.tsx +++ b/src/components/chat/SharedStoryBubble.tsx @@ -79,8 +79,8 @@ export default function SharedStoryBubble({ src={preview} alt="" fill + sizes="120px" className="object-cover" - unoptimized /> )}
diff --git a/src/components/explore/ExploreVideoThumb.tsx b/src/components/explore/ExploreVideoThumb.tsx index ec2ee81..62bf759 100644 --- a/src/components/explore/ExploreVideoThumb.tsx +++ b/src/components/explore/ExploreVideoThumb.tsx @@ -96,7 +96,6 @@ export default function ExploreVideoThumb({ fill className="object-cover" sizes="50vw" - unoptimized /> ) : !frameReady ? (
diff --git a/src/components/explore/ReelsAcademyCard.tsx b/src/components/explore/ReelsAcademyCard.tsx index 70ccaa7..9e67115 100644 --- a/src/components/explore/ReelsAcademyCard.tsx +++ b/src/components/explore/ReelsAcademyCard.tsx @@ -321,8 +321,8 @@ export default function ReelsAcademyCard({ src={buildStorageUrl(item.profile_image)} alt="" fill + sizes="40px" className="object-cover" - unoptimized /> ) : null}
diff --git a/src/components/main/ProfileAvatar.tsx b/src/components/main/ProfileAvatar.tsx index 324ca61..53c0125 100644 --- a/src/components/main/ProfileAvatar.tsx +++ b/src/components/main/ProfileAvatar.tsx @@ -67,9 +67,8 @@ function ProfileAvatar({ {alt} = ({ service, onDelete }) => { height={50} src={buildStorageUrl(image) || image} alt={title} - unoptimized className="min-w-[50px] min-h-[50px] rounded-lg object-cover" /> ) : ( diff --git a/src/components/models/AppearanceColorSelect.tsx b/src/components/models/AppearanceColorSelect.tsx index 69aa74c..ff2e6cf 100644 --- a/src/components/models/AppearanceColorSelect.tsx +++ b/src/components/models/AppearanceColorSelect.tsx @@ -43,8 +43,8 @@ export default function AppearanceColorSelect({ src={selected.src} alt={selected.label} fill + sizes="36px" className="object-cover" - unoptimized /> ) : ( @@ -93,8 +93,8 @@ export default function AppearanceColorSelect({ src={opt.src} alt={opt.label} fill + sizes="56px" className="object-cover" - unoptimized /> {opt.label} diff --git a/src/components/models/MainModelCard/MainModelCard.tsx b/src/components/models/MainModelCard/MainModelCard.tsx index 3f64c60..f9e620b 100644 --- a/src/components/models/MainModelCard/MainModelCard.tsx +++ b/src/components/models/MainModelCard/MainModelCard.tsx @@ -222,9 +222,9 @@ function MainModelCard({ } alt={user_name} fill + sizes="72px" className="aspect-square rounded-2xl object-cover" priority - unoptimized /> diff --git a/src/components/models/MainModelCard/SwipeImageSlider.tsx b/src/components/models/MainModelCard/SwipeImageSlider.tsx index c5f97fe..799ce17 100644 --- a/src/components/models/MainModelCard/SwipeImageSlider.tsx +++ b/src/components/models/MainModelCard/SwipeImageSlider.tsx @@ -120,7 +120,6 @@ const SwipeImageSlider: React.FC = ({ loading={idx === 0 ? "eager" : "lazy"} className="min-h-[30vh] w-full rounded-2xl object-contain shadow-lg transition-opacity duration-300" onLoadingComplete={() => setImageLoading?.(false)} - unoptimized /> )} diff --git a/src/components/models/ModelPage/ModelContentPosts.tsx b/src/components/models/ModelPage/ModelContentPosts.tsx index 898d322..5faf812 100644 --- a/src/components/models/ModelPage/ModelContentPosts.tsx +++ b/src/components/models/ModelPage/ModelContentPosts.tsx @@ -143,7 +143,6 @@ function ModelContentPosts({ height={300} className="h-full w-full object-cover transition-transform duration-300 group-hover:scale-105 group-active:scale-100" loading="lazy" - unoptimized /> ) : poster ? ( ) : (