Fetch og images without CORS to fix pre-rendering bugs

This commit is contained in:
Sam Becker 2026-02-16 23:25:30 -06:00
parent 3607d51c06
commit 7c9b99bff0
2 changed files with 34 additions and 10 deletions

View File

@ -7,6 +7,7 @@ import {
doAllPhotosHaveOptimizedFiles, doAllPhotosHaveOptimizedFiles,
getOptimizedPhotoUrl, getOptimizedPhotoUrl,
} from '@/photo/storage'; } from '@/photo/storage';
import { fetchBase64ImageFromUrl } from '@/utility/image';
export default async function ImagePhotoGrid({ export default async function ImagePhotoGrid({
photos, photos,
@ -53,7 +54,24 @@ export default async function ImagePhotoGrid({
const doOptimizedFilesExist = await doAllPhotosHaveOptimizedFiles(photos); const doOptimizedFilesExist = await doAllPhotosHaveOptimizedFiles(photos);
const renderPhoto = ({ id, url }: Photo, width: number, height: number) => const photoData = await Promise.all(photos.map(async ({ id, url }) => {
const data = await fetchBase64ImageFromUrl(
getOptimizedPhotoUrl({
imageUrl: url,
size: nextImageWidth,
addBypassSecret: IS_PREVIEW,
compatibilityMode: !doOptimizedFilesExist,
}),
{ mode: 'no-cors' },
);
return { id, data };
}));
const renderPhoto = (
{ id, data }: typeof photoData[number],
width: number,
height: number,
) =>
<div <div
key={id} key={id}
style={{ style={{
@ -65,12 +83,7 @@ export default async function ImagePhotoGrid({
}} }}
> >
<img {...{ <img {...{
src: getOptimizedPhotoUrl({ src: data,
imageUrl: url,
size: nextImageWidth,
addBypassSecret: IS_PREVIEW,
compatibilityMode: !doOptimizedFilesExist,
}),
style: { style: {
...imageStyle, ...imageStyle,
width: '100%', width: '100%',
@ -100,7 +113,7 @@ export default async function ImagePhotoGrid({
width: cellWidth, width: cellWidth,
height: cellHeight * 2, height: cellHeight * 2,
}}> }}>
{renderPhoto(photos[0], cellWidth, cellHeight * 2)} {renderPhoto(photoData[0], cellWidth, cellHeight * 2)}
</div> </div>
{/* Small images (R) */} {/* Small images (R) */}
<div style={{ <div style={{
@ -109,12 +122,12 @@ export default async function ImagePhotoGrid({
width: cellWidth, width: cellWidth,
height: cellHeight, height: cellHeight,
}}> }}>
{photos.slice(1).map(photo => {photoData.slice(1).map(photo =>
renderPhoto(photo, cellWidth, cellHeight), renderPhoto(photo, cellWidth, cellHeight),
)} )}
</div> </div>
</> </>
: photos.slice(0, count).map(photo => : photoData.slice(0, count).map(photo =>
renderPhoto(photo, cellWidth, cellHeight), renderPhoto(photo, cellWidth, cellHeight),
)} )}
</div> </div>

View File

@ -1,3 +1,14 @@
export const removeBase64Prefix = (base64: string) => { export const removeBase64Prefix = (base64: string) => {
return base64.match(/^data:image\/[a-z]{3,4};base64,(.+)$/)?.[1] ?? base64; return base64.match(/^data:image\/[a-z]{3,4};base64,(.+)$/)?.[1] ?? base64;
}; };
export const fetchBase64ImageFromUrl = (
url: string,
fetchOptions?: RequestInit,
) =>
fetch(url, fetchOptions)
.then(async response => {
const blob = await response.arrayBuffer();
// eslint-disable-next-line max-len
return `data:${response.headers.get('content-type')};base64,${Buffer.from(blob).toString('base64')}`;
});