Skip to content

Commit b1c6c99

Browse files
Dev-HyunSangclaude
andcommitted
feat: 글 상단에 AI 요약 표시 기능 추가
posts 콘텐츠 스키마에 aiSummary optional 필드를 추가하고, 값이 있으면 글 헤더와 본문 사이에 요약 박스를 렌더링한다. 정적 사이트라 빌드/배포 시점의 실시간 API 호출이 불가능해 글 작성 시점에 요약을 직접 채워 넣는 방식으로 구현. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
1 parent 640c669 commit b1c6c99

7 files changed

Lines changed: 68 additions & 0 deletions

File tree

CLAUDE.md

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
# dev-hyunsang.github.io
2+
3+
Astro 기반 정적 블로그 (GitHub Pages 배포, 서버/어댑터 없음).
4+
5+
## 새 포스트 작성 시
6+
7+
`src/content/posts/**/index.md`에 새 글을 쓰거나 기존 글의 본문을 크게 수정하면,
8+
frontmatter에 `aiSummary` 필드를 2~3문장으로 채워 넣는다. 글 상단에 자동으로 렌더링된다
9+
(`src/components/AISummary.astro`, `src/layouts/SingleLayout.astro`).
10+
11+
- 정적 사이트라 빌드/배포 시점에 실시간 API 호출이 불가능하므로, 글 작성 시점에 직접 생성해 저장하는 방식이다.
12+
- 예시:
13+
```yaml
14+
aiSummary: "PyCon Korea 2026 미디어팀 리드로 활동한 경험을 돌아보며, 커뮤니케이션과 팀워크에 대한 고민을 정리한 회고."
15+
```
16+
- 필드가 비어 있으면 요약 박스는 표시되지 않는다(optional).

src/components/AISummary.astro

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
---
2+
interface Props {
3+
summary: string;
4+
}
5+
6+
const { summary } = Astro.props;
7+
---
8+
9+
<div class="ai-summary">
10+
<div class="ai-summary-label">
11+
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M9.937 15.5A2 2 0 0 0 8.5 14.063l-6.135-1.582a.5.5 0 0 1 0-.962L8.5 9.936A2 2 0 0 0 9.937 8.5l1.582-6.135a.5.5 0 0 1 .963 0L14.063 8.5A2 2 0 0 0 15.5 9.937l6.135 1.582a.5.5 0 0 1 0 .963L15.5 14.063a2 2 0 0 0-1.437 1.437l-1.582 6.135a.5.5 0 0 1-.963 0z"/></svg>
12+
<span>AI 요약</span>
13+
</div>
14+
<p class="ai-summary-text">{summary}</p>
15+
</div>

src/content.config.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ const posts = defineCollection({
1313
showDate: z.boolean().optional(),
1414
showAuthor: z.boolean().optional(),
1515
toc: z.boolean().optional(),
16+
aiSummary: z.string().optional(),
1617
}),
1718
});
1819

src/content/posts/PyCon-KR-2026/index.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ date: 2026-08-17
55
draft: false
66
categories: ["개발자 커뮤니티 활동", "회고"]
77
tags: ["PyCon Korea", "PyCon Korea 2026"]
8+
aiSummary: "저자가 파이콘준비위원회 신설 미디어팀 리드로서 PyCon Korea 2026을 준비하며 겪은 장비·송출·촬영 운영 경험과, 그 과정에서 성장한 커뮤니케이션 역량을 돌아보는 회고."
89
---
910

1011
안녕하세요. 박현상입니다.

src/layouts/SingleLayout.astro

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
import type { MarkdownHeading } from 'astro';
33
import BaseLayout from './BaseLayout.astro';
44
import TableOfContents from '../components/TableOfContents.astro';
5+
import AISummary from '../components/AISummary.astro';
56
import { site } from '../site.config';
67
import { formatDateKo, isoDate } from '../lib/date';
78
import { urlize } from '../lib/slug';
@@ -16,6 +17,7 @@ interface Props {
1617
showAuthor?: boolean;
1718
toc?: boolean;
1819
headings?: MarkdownHeading[];
20+
aiSummary?: string;
1921
}
2022
2123
const {
@@ -28,6 +30,7 @@ const {
2830
showAuthor = true,
2931
toc = true,
3032
headings = [],
33+
aiSummary,
3134
} = Astro.props;
3235
3336
const showToc = toc && headings.some((h) => h.depth >= 2 && h.depth <= 3);
@@ -59,6 +62,8 @@ const showToc = toc && headings.some((h) => h.depth >= 2 && h.depth <= 3);
5962
</div>
6063
</div>
6164

65+
{aiSummary && <AISummary summary={aiSummary} />}
66+
6267
<div class="post-body">
6368
<slot />
6469
</div>

src/pages/posts/[...slug].astro

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ const { Content, headings } = await render(post);
2424
showAuthor={post.data.showAuthor}
2525
toc={post.data.toc}
2626
headings={headings}
27+
aiSummary={post.data.aiSummary}
2728
>
2829
<Content />
2930
</SingleLayout>

src/styles/global.css

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -330,6 +330,35 @@ main {
330330
background: var(--border-subtle);
331331
}
332332

333+
/* AI Summary */
334+
.ai-summary {
335+
background-color: var(--bg-card);
336+
border: 1px solid var(--border);
337+
border-left: 4px solid var(--accent);
338+
border-radius: 4px;
339+
padding: 16px 20px;
340+
margin-bottom: 30px;
341+
}
342+
343+
.ai-summary-label {
344+
display: flex;
345+
align-items: center;
346+
gap: 6px;
347+
color: var(--accent);
348+
font-size: 0.8rem;
349+
font-weight: 700;
350+
text-transform: uppercase;
351+
letter-spacing: 0.05em;
352+
margin-bottom: 8px;
353+
}
354+
355+
.ai-summary-text {
356+
color: var(--text-secondary);
357+
font-size: 0.95rem;
358+
line-height: 1.7;
359+
margin: 0;
360+
}
361+
333362
/* Post Body */
334363
.post-body {
335364
font-size: 1.1rem;

0 commit comments

Comments
 (0)