From ae9c3c236a1e6eb84bacf0ec180960a68970e973 Mon Sep 17 00:00:00 2001 From: pkupuk Date: Sat, 13 Dec 2025 07:56:37 +0800 Subject: [PATCH] refactor(media): improve image URL handling and add cleanup workflow - Enhance ImageMedia component to properly handle absolute and relative URLs, avoiding ENV mismatches - Update next.config.js to filter invalid URLs and add error handling for image remote patterns - Add new workflow to remove AI-generated inconsistencies from branch diffs --- .agent/workflows/remove-slop.md | 11 +++++++++ next.config.js | 22 +++++++++++------ src/components/Media/ImageMedia/index.tsx | 30 +++++++++++++++++------ 3 files changed, 48 insertions(+), 15 deletions(-) create mode 100644 .agent/workflows/remove-slop.md diff --git a/.agent/workflows/remove-slop.md b/.agent/workflows/remove-slop.md new file mode 100644 index 0000000..2a4037a --- /dev/null +++ b/.agent/workflows/remove-slop.md @@ -0,0 +1,11 @@ +--- +description: Check the diff against main and remove all AI generated slop introduced in this branch. +--- +1. Run `git diff --name-only main...HEAD` to identify the files modified in the current branch. +2. For each modified file, compare it against the version in `main` to identify changes. +3. Review the changes and remove the following "AI slop": + - Extra comments that a human wouldn't add or that are inconsistent with the rest of the file. + - Extra defensive checks or try/catch blocks that are abnormal for that area of the codebase (especially if called by trusted/validated codepaths). + - Casts to `any` used to get around type issues. + - Any other style that is inconsistent with the file. +4. Report at the end with only a 1-3 sentence summary of what you changed. diff --git a/next.config.js b/next.config.js index d7e685a..7958813 100644 --- a/next.config.js +++ b/next.config.js @@ -11,14 +11,22 @@ const nextConfig = { output: 'standalone', images: { remotePatterns: [ - ...[NEXT_PUBLIC_SERVER_URL /* 'https://example.com' */].map((item) => { - const url = new URL(item) + ...[NEXT_PUBLIC_SERVER_URL, process.env.NEXT_PUBLIC_SERVER_URL] + .filter(Boolean) + .map((item) => { + const urlString = item.startsWith('http') ? item : `https://${item}` - return { - hostname: url.hostname, - protocol: url.protocol.replace(':', ''), - } - }), + try { + const url = new URL(urlString) + return { + hostname: url.hostname, + protocol: url.protocol.replace(':', ''), + } + } catch (_) { + return null + } + }) + .filter(Boolean), ], }, webpack: (webpackConfig) => { diff --git a/src/components/Media/ImageMedia/index.tsx b/src/components/Media/ImageMedia/index.tsx index 8a1dc10..76e446b 100644 --- a/src/components/Media/ImageMedia/index.tsx +++ b/src/components/Media/ImageMedia/index.tsx @@ -9,7 +9,7 @@ import React from 'react' import type { Props as MediaProps } from '../types' import { cssVariables } from '@/cssVariables' -import { getMediaUrl } from '@/utilities/getMediaUrl' +import { getMediaUrl as _getMediaUrl } from '@/utilities/getMediaUrl' const { breakpoints } = cssVariables @@ -35,16 +35,30 @@ export const ImageMedia: React.FC = (props) => { let alt = altFromProps let src: StaticImageData | string = srcFromProps || '' - if (!src && resource && typeof resource === 'object') { - const { alt: altFromResource, height: fullHeight, url, width: fullWidth } = resource + if (!src && resource) { + if (typeof resource === 'string') { + src = resource + } else if (typeof resource === 'object') { + const { alt: altFromResource, height: fullHeight, url, width: fullWidth } = resource - width = fullWidth! - height = fullHeight! - alt = altFromResource || '' + width = fullWidth ?? undefined + height = fullHeight ?? undefined + alt = altFromResource || '' - const cacheTag = resource.updatedAt + const cacheTag = resource.updatedAt - src = getMediaUrl(url, cacheTag) + // If we have a URL, decide if we need to absolute-ize it. + // For NextImage, relative URLs (starting with /) are preferred for internal assets. + // They automatically use the current domain, avoiding ENV var mismatches. + + if (url) { + if (url.startsWith('http') || url.startsWith('//')) { + src = cacheTag ? `${url}?${cacheTag}` : url + } else { + src = url + } + } + } } const loading = loadingFromProps || (!priority ? 'lazy' : undefined)