Skip to content

feat: add cover image display for article detail and list pages - #28

Merged
xkcoding merged 1 commit into
masterfrom
feature/add-cover-image-display
Jan 19, 2026
Merged

xkcoding merged 1 commit into
masterfrom
feature/add-cover-image-display

Conversation

@xkcoding

Copy link
Copy Markdown
Owner

Summary

  • 在文章详情页标题上方展示配置的 ogImage 头图,支持 hover 效果
  • 在文章列表卡片中展示缩略图(响应式布局:移动端堆叠,桌面端左图右文)
  • RSS feed 中通过 enclosure 标签支持头图,自动检测 MIME 类型

Test plan

  • 本地预览文章详情页,确认头图正确显示在标题上方
  • 验证头图 hover 效果(阴影加深 + 轻微放大)
  • 本地预览文章列表页,确认缩略图显示在描述左侧
  • 验证列表缩略图 hover 效果
  • 检查响应式布局(移动端/桌面端)
  • 验证 RSS feed 中的 enclosure 标签正确输出

🤖 Generated with Claude Code

- Display ogImage on article detail page above title with hover effects
- Add thumbnail in article list cards (responsive layout)
- Support cover image in RSS feed via enclosure tag
- Auto-detect MIME type for RSS enclosure

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Copilot AI review requested due to automatic review settings January 19, 2026 13:46
@xkcoding
xkcoding merged commit 91d19d8 into master Jan 19, 2026
5 checks passed
@xkcoding
xkcoding deleted the feature/add-cover-image-display branch January 19, 2026 13:47

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR adds visual cover image display functionality to article pages, leveraging the existing ogImage frontmatter field. Previously, ogImage was only used for Open Graph metadata; now it's also displayed on the article detail page (above the title) and as thumbnails in article list cards.

Changes:

  • Added cover image display in article detail pages with hover effects and responsive sizing
  • Implemented thumbnail images in article list cards with responsive layout (mobile: stacked, desktop: left-side)
  • Extended RSS feed to include cover images via enclosure tags with automatic MIME type detection

Reviewed changes

Copilot reviewed 8 out of 8 changed files in this pull request and generated 8 comments.

Show a summary per file
File Description
src/pages/rss.xml.ts Added helper functions for ogImage URL parsing and MIME type detection, integrated cover images into RSS feed enclosures
src/layouts/PostDetails.astro Added conditional cover image display above article content with hover effects and responsive max-height constraints
src/components/Card.astro Implemented thumbnail display in list cards with responsive flex layout and hover scale effects
src/data/blog/2026-01-17.extend-claude-code-with-slash-command.md Added example ogImage field demonstrating feature usage
openspec/changes/archive/2026-01-19-add-cover-image-display/* Comprehensive documentation including proposal, design decisions, specs, and task breakdown

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread src/pages/rss.xml.ts
Comment on lines +35 to +36
};
return mimeTypes[ext || ""] || "image/jpeg";

Copilot AI Jan 19, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The MIME type detection logic is limited and may not accurately handle all image formats. Consider adding support for additional formats like 'avif', 'bmp', and 'ico'. Also, the fallback to 'image/jpeg' may be incorrect for other file types. Consider defaulting to 'application/octet-stream' for unknown types or adding a warning.

Suggested change
};
return mimeTypes[ext || ""] || "image/jpeg";
avif: "image/avif",
bmp: "image/bmp",
ico: "image/x-icon",
};
return mimeTypes[ext || ""] || "application/octet-stream";

Copilot uses AI. Check for mistakes.
Comment thread src/pages/rss.xml.ts
...(ogImageUrl && {
enclosure: {
url: ogImageUrl,
type: getImageMimeType(ogImageUrl),

Copilot AI Jan 19, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The length property is hardcoded to 0, which is technically valid for RSS but not ideal. RSS enclosures should include the file size in bytes when possible. Consider either fetching the actual file size or documenting why this is set to 0 (e.g., "length set to 0 as file size is not known at build time").

Suggested change
type: getImageMimeType(ogImageUrl),
type: getImageMimeType(ogImageUrl),
// length set to 0 as file size is not known at build time

Copilot uses AI. Check for mistakes.
Comment thread src/pages/rss.xml.ts
Comment on lines +18 to +20
if (ogImage.src) {
// 本地 asset
return new URL(ogImage.src, site).href;

Copilot AI Jan 19, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The getOgImageUrl function doesn't handle the case where ogImage is a local asset but lacks a .src property. While this might be unlikely, adding explicit validation or type checking would make the code more robust. Consider adding a check to ensure the object has the expected structure before accessing .src.

Suggested change
if (ogImage.src) {
// 本地 asset
return new URL(ogImage.src, site).href;
if (
typeof ogImage === "object" &&
ogImage !== null &&
"src" in ogImage &&
typeof (ogImage as { src: unknown }).src === "string"
) {
// 本地 asset
return new URL((ogImage as { src: string }).src, site).href;

Copilot uses AI. Check for mistakes.
Comment thread src/components/Card.astro
alt={title}
class="h-24 w-full object-cover transition-transform duration-300 group-hover/thumb:scale-105 sm:h-24 sm:w-40"
loading="lazy"
decoding="async"

Copilot AI Jan 19, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Consider adding width and height attributes to the img tag to prevent layout shift during image loading. This helps with Cumulative Layout Shift (CLS) metrics and improves user experience. For the thumbnail, you could use width="160" height="96" to match the aspect ratio of the sm:w-40 sm:h-24 classes.

Suggested change
decoding="async"
decoding="async"
width="160"
height="96"

Copilot uses AI. Check for mistakes.
Comment thread src/pages/rss.xml.ts
Comment on lines +8 to +23
// 解析 ogImage URL
function getOgImageUrl(
ogImage: CollectionEntry<"blog">["data"]["ogImage"],
site: string
): string | undefined {
if (!ogImage) return undefined;
if (typeof ogImage === "string") {
// 远程 URL 直接返回,相对路径拼接 site
return ogImage.startsWith("http") ? ogImage : new URL(ogImage, site).href;
}
if (ogImage.src) {
// 本地 asset
return new URL(ogImage.src, site).href;
}
return undefined;
}

Copilot AI Jan 19, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The ogImage URL parsing logic here duplicates similar logic in PostDetails.astro (lines 51-55) and Card.astro (lines 31-35). Consider extracting this into a shared utility function in a file like @/utils/getOgImageUrl.ts to maintain consistency and reduce code duplication.

Copilot uses AI. Check for mistakes.
<div class="group/cover mb-6 overflow-hidden rounded-xl border border-foreground/10 shadow-lg shadow-foreground/5 transition-shadow duration-300 hover:shadow-xl hover:shadow-foreground/10">
<img
src={ogImageUrl}
alt={title}

Copilot AI Jan 19, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

While the alt attribute is set to the article title, this may not be the most descriptive alternative text for screen readers. Consider using a more descriptive alt text that describes what the cover image actually depicts, or use an empty alt (alt="") if the image is purely decorative and doesn't add meaningful content beyond what the title already conveys.

Suggested change
alt={title}
alt=""

Copilot uses AI. Check for mistakes.
Comment thread src/components/Card.astro
<div class="group/thumb shrink-0 overflow-hidden rounded-md border border-foreground/10 shadow-sm">
<img
src={ogImageUrl}
alt={title}

Copilot AI Jan 19, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

While the alt attribute is set to the article title, this may not be the most descriptive alternative text for screen readers. Consider using a more descriptive alt text that describes what the thumbnail image actually depicts, or use an empty alt (alt="") if the image is purely decorative and doesn't add meaningful content beyond what the title already conveys.

Suggested change
alt={title}
alt=""

Copilot uses AI. Check for mistakes.
Comment on lines +105 to +111
<img
src={ogImageUrl}
alt={title}
class="h-auto max-h-[250px] w-full object-cover transition-transform duration-300 group-hover/cover:scale-[1.02] sm:max-h-[400px]"
loading="lazy"
decoding="async"
/>

Copilot AI Jan 19, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Consider adding width and height attributes to the img tag to prevent layout shift during image loading. This helps with Cumulative Layout Shift (CLS) metrics and improves user experience. Since the image uses object-cover, you can set explicit dimensions that match the container's aspect ratio.

Copilot uses AI. Check for mistakes.
xkcoding added a commit that referenced this pull request Jan 20, 2026
- Add avif MIME type support in RSS feed
- Add comment explaining enclosure length: 0 rationale
- Add width/height attributes to Card thumbnail to prevent CLS

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
xkcoding added a commit that referenced this pull request Jan 20, 2026
* fix: address Copilot review suggestions for PR #28

- Add avif MIME type support in RSS feed
- Add comment explaining enclosure length: 0 rationale
- Add width/height attributes to Card thumbnail to prevent CLS

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* feat: add view source link and CC license declaration

- Add viewSource config for raw markdown link (GitHub raw URL)
- Add license config for CC BY-NC-SA 4.0 declaration
- Create ViewSource.astro component with GitHub icon
- Create License.astro component with official CC badge and post URL
- Integrate components into PostDetails layout
- Simplify BackToTopButton and move to TOC sidebar
- Add tech stack info to Footer (Astro & AstroPaper)
- Remove ShareLinks from post details
- Update TableOfContents to support slot for BackToTopButton

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* fix: 修复无头图文章错误显示动态 OG 图片的问题

- 分离 coverImageUrl(页面显示)和 ogImageUrl(meta 标签)
- 页面封面图只在用户明确设置 ogImage 时才显示
- 动态 OG 图片仅用于 meta 标签,不影响页面显示

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* docs: 更新项目文档并归档 OpenSpec proposal

- 更新 README.md,添加特性列表和配置说明
- 完善 openspec/project.md 项目上下文
- 归档 add-source-link-and-license proposal
- 创建 post-details spec

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* chore: 添加小红书文案生成命令和忽略配置

- 新增 .claude/commands/xhs-copy.md 小红书文案生成命令
- .gitignore 添加 xhs-images/ 目录

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* fix: 为 CC 协议徽章添加 width/height 属性

避免页面加载时的布局偏移 (CLS)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants