From 1a18096cf6e67f56f2c0a865a9273b1955f733bc Mon Sep 17 00:00:00 2001 From: Leander Furumo Date: Fri, 30 Oct 2026 23:42:21 +0100 Subject: [PATCH] Apply Sanity crop and hotspot to images Fetch the full image objects instead of only the asset URL so the URL builder can apply the crop and hotspot set in the Studio, crop the Open Graph image around the hotspot, and add sizes to full-width blog images. Closes #27 Co-Authored-By: Claude Opus 5.5 --- src/app/[locale]/blog/[slug]/page.tsx | 23 +++++++++++-------- src/components/page-sections/boardMembers.tsx | 17 ++++---------- src/lib/imageUrlBuilder.ts | 6 +++++ src/lib/sanity.ts | 21 +++-------------- 4 files changed, 27 insertions(+), 40 deletions(-) diff --git a/src/app/[locale]/blog/[slug]/page.tsx b/src/app/[locale]/blog/[slug]/page.tsx index 80024bd..25fa1f1 100644 --- a/src/app/[locale]/blog/[slug]/page.tsx +++ b/src/app/[locale]/blog/[slug]/page.tsx @@ -2,7 +2,7 @@ import Footer from "@/components/page-sections/footer" import { generateSeoMetadata } from "@/components/seo" import Back from "@/components/ui/back" -import { urlFor } from "@/lib/imageUrlBuilder" +import { type SanityImage, urlFor } from "@/lib/imageUrlBuilder" import { getBlogPost } from "@/lib/sanity" import { PortableText, PortableTextComponents } from "@portabletext/react" @@ -20,11 +20,7 @@ interface BlogPageParams { }> } -interface ImageValue { - asset?: { - _id: string - url: string - } +type ImageValue = Partial & { alt?: string caption?: string } @@ -67,7 +63,10 @@ export async function generateMetadata({ path: `/blog/${slug}`, title: data.title, description: data.excerpt, - imageURL: data.mainImage?.asset?.url, + // Cropped around the hotspot to the size link previews expect + imageURL: data.mainImage?.asset + ? urlFor(data.mainImage).width(1200).height(630).url() + : undefined, author: data.author?.name, publishedTime: data._createdAt, }) @@ -80,10 +79,13 @@ const components: PortableTextComponents = { return (
{value.alt {value.caption && ( @@ -144,10 +146,11 @@ const BlogPost = async ({ params }: BlogPageParams) => {
{data.mainImage && ( {data.title} )} @@ -158,7 +161,7 @@ const BlogPost = async ({ params }: BlogPageParams) => { {data.author.name} diff --git a/src/components/page-sections/boardMembers.tsx b/src/components/page-sections/boardMembers.tsx index 851df97..242da5f 100644 --- a/src/components/page-sections/boardMembers.tsx +++ b/src/components/page-sections/boardMembers.tsx @@ -1,4 +1,4 @@ -import { urlFor } from "@/lib/imageUrlBuilder" +import { type SanityImage, urlFor } from "@/lib/imageUrlBuilder" import { getBoardMembers } from "@/lib/sanity" import { getLocale, getTranslations } from "next-intl/server" @@ -14,12 +14,7 @@ interface BoardMember { no: string en: string } - image?: { - asset?: { - _id: string - url: string - } - } + image: SanityImage | null bio?: { no: string en: string @@ -44,11 +39,9 @@ const BoardMembers = async () => { > { name, - image { - asset-> { - _id, - url - } - } - }, - mainImage { - asset-> { - _id, - url - } + image }, + mainImage, excerpt, body } @@ -119,12 +109,7 @@ export async function getBoardMembers() { no, en }, - image { - asset->{ - _id, - url - } - }, + image, bio { no, en