🌐 AI 바이브코딩 실전 교재

퍼스널 브랜딩 홈페이지 개발 과정

OpenClaw + Claude로 바이브코딩하여 퍼스널 브랜딩 홈페이지(ahnhyunsoo.com)를 만든 전 과정을 기록합니다. 콘텐츠 준비부터 Astro 배포, SEO/GEO 최적화까지.

이 교재에 대하여

이 교재는 AI 강사이자 컨설턴트인 안현수의 퍼스널 브랜딩 홈페이지를 처음부터 끝까지 만든 실전 사례입니다. 코드를 한 줄도 직접 치지 않고, AI(OpenClaw + Claude)에게 대화로 지시하는 바이브코딩 방식으로 개발했습니다.

단순히 "이렇게 만들었다"가 아니라, 왜 이렇게 결정했는지, 다른 방법은 무엇이 있었는지, 시행착오는 무엇이었는지를 함께 기록했습니다. 처음 홈페이지를 만드는 분도 이 교재를 따라가며 전체 흐름을 이해할 수 있습니다.

💡
바이브코딩이란?
개발자가 직접 코드를 작성하는 대신, AI에게 자연어로 원하는 결과를 설명하고 AI가 코드를 생성하는 방식입니다. 이 홈페이지의 모든 HTML, CSS, JavaScript, Astro 코드는 OpenClaw를 통해 Claude가 작성했습니다.
Part 1

콘텐츠 준비 및 웹페이지 개발

어떤 정보를 넣을지 정리하고, 원본 데이터를 웹에 맞게 가공하고, 페이지 구조와 디자인 시스템을 설계합니다.

1. 콘텐츠 준비

홈페이지를 만들기 전에 가장 먼저 해야 할 일은 "어떤 정보를 넣을 것인가"를 정리하는 것입니다. 디자인이나 기술보다 콘텐츠가 먼저입니다.

어떤 정보를 넣을 것인가

퍼스널 브랜딩 홈페이지에는 크게 7가지 종류의 정보가 필요했습니다.

👤

소개 (About)

20년 경력의 이야기, 엔지니어→방법론→AI 전환 스토리

📋

이력 & 자격

PMP, TRIZ Lv4, AICPA, 한양대 석사 등 전문 자격증

🏢

고객사

삼성, 현대 등 300+ 출강 기관 (엑셀 데이터 기반)

📚

커리큘럼 & 교재

실제 출강 커리큘럼 11개 + 직접 제작 교재 5종

🎬

유튜브

AI 활용 강의, 바이브코딩 등 주요 영상 10개

💻

포트폴리오

직접 만든 SaaS·앱·웹 서비스 10개

🎓

온라인 강의

gptkoreaclass.com 온라인 교육 과정 9개

About 스토리 작성 — 핵심 과정

홈페이지에서 가장 중요하면서도 어려운 부분이 자기소개 스토리였습니다. 단순한 이력서가 아니라, 방문자가 "이 사람에게 강의를 맡기고 싶다"고 느끼게 만드는 서사가 필요했습니다.

초기 문제 — "이력서 수준의 About"

첫 버전의 About 섹션은 "공학·기술경영 전공, 삼성 거침, 2013년 독립"이라는 LinkedIn 요약 수준이었습니다. 이에 대한 피드백:

💬
피드백: "단순 정보·사실·숫자 나열이라 일반적인 홍보용 기업 페이지처럼 보인다. 전문가의 정성, 얼마나 열심히 공부하는가 같은 부분이 전혀 느껴지지 않는다."

스토리 구조 설계

실제 경험을 소재로 AI와 함께 스토리를 구성했습니다. 핵심은 두 번의 전환점을 중심으로 서사를 만드는 것이었습니다.

1
전환 1: 일의 양 → 방법론
2005년 엔지니어로 시작, 3년간 야근. "열심히만 하는 것은 결코 답이 아니었습니다." PMP 발견 → "세상은 넓고 똑똑한 사람들의 노하우가 정리되어 있다"는 깨달음. 이후 10년간 PMP, TRIZ, AICPA, NPDP 등 취득.
2
전환 2: 방법론 → AI
2022년 ChatGPT 출시. "제가 그동안 공부한 이론과 방법론들이 GPT 안에 이미 다 들어있더라고요. 이건 안 쓸 수가 없었어요." 매일 사용 시작.
3
자기 증명
LMS 직접 개발, 유튜브 직접 제작, 네프콘 직접 운영, 이 홈페이지도 직접 — 모두 AI를 활용한 실전 결과물.

피드백을 반영한 문구 수정

스토리 초안을 작성한 뒤, 표현을 다듬는 과정을 거쳤습니다.

초안수정 후수정 이유
"방법이 문제였습니다." "열심히만 하는 것은 결코 답이 아니었습니다." 더 직접적인 표현
"더 효율적으로, 더 체계적으로" "더 적게 일하면서도 더 높은 성과를 내는 방법" 핵심 메시지 강조
"게임이 바뀌었습니다." "게임이 완전히 바뀌었습니다." 강조 추가
"어제도 쓴 방법" "어제도 오늘도 제가 매일 쓰고 있는 바로 그 실무 활용 방법" 현재진행형 강조

랜딩 페이지에 들어갈 짧은 소개 문구도 10개 후보를 검토한 뒤, 최종 선택:

최종 채택 문구: "20년째 일 잘하는 방법을 연구하고 전파하고 있습니다. 그리고 그 최고의 도구는 이제 AI입니다."
버튼 문구: "AI를 매일 매일 쓰는 전문가의 이야기" → "자세히 보기 →"
📌 핵심 포인트
  • 홈페이지 콘텐츠는 디자인보다 먼저 준비해야 합니다
  • About은 이력서가 아니라 전환점 중심의 스토리로 구성하세요
  • 짧은 문구도 여러 후보를 만들고 비교해서 결정하세요
  • AI가 초안을 쓰더라도, 최종 결정은 본인의 톤과 메시지로 다듬어야 합니다

2. 콘텐츠 가공

홈페이지에 넣을 정보가 정리되었으면, 다음 단계는 원본 데이터를 웹에서 사용할 수 있는 형태로 변환하는 것입니다.

엑셀 데이터 → 웹 구조로 변환

가장 대표적인 사례가 고객사 목록입니다. 원본은 레퍼런스 엑셀 파일로, I열에 강사별 표시(1)가 되어 있었습니다.

1
엑셀 파싱
엑셀 파일에서 I열 = "안현수"이고 값이 1인 행만 추출. 총 216개 고객사가 나왔습니다.
2
데이터 정제
개별 수정 적용: 현대차(중앙일보)/부산대현대자동차, 데이터랩스, C&C 삭제, 전남CEO전남CEO포럼. 최종 215개.
3
가나다 순 칩(chip) 나열
215개 고객사를 가나다 순으로 정렬하여 chip 형태로 나열. 부제목: "주 3일 강의, 주 2일 공부하며 다녀온 고객사들"

커리큘럼/교재 CMS 방식 설계

커리큘럼과 교재는 계속 추가될 예정이었기 때문에, 파일만 추가하면 자동으로 반영되는 CMS 방식이 필요했습니다.

검토된 방식들

방식원리장점단점
JSON fetch JSON 파일을 JS로 불러옴 표준적 로컬(file://)에서 CORS 오류
Notion API 외부 서비스에서 데이터 불러옴 편집 편리 외부 서비스 의존성
JS 배열 (content.js) JavaScript 파일에 데이터 직접 기재 로컬에서도 동작, 단순 빌드 없는 정적 방식

채택된 방식: content.js

프로토타입 단계에서는 content.js에 JavaScript 배열로 데이터를 관리하기로 했습니다. 로컬에서 바로 열어볼 수 있어야 했기 때문입니다.

// content.js — 커리큘럼 데이터
const CURRICULUM = [
  {
    no: '01',
    title: '교보생명 마켓센싱 AI 교육',
    desc: 'AI 활용 마켓센싱 실습...',
    hours: '20h',
    file: 'curriculum/교보생명-마켓센싱-20h.html'
  },
  // file에 경로 입력 → 자동으로 "자세히 보기" 버튼 생성
];

사용 흐름은 간단합니다:

  1. curriculum/ 폴더에 HTML 파일 추가
  2. content.js에 한 줄 추가 (file: 'curriculum/파일명.html')
  3. 카드에 "자세히 보기" 버튼 자동 생성
📌
나중에 Astro로 전환할 때, 이 content.js는 _meta.json 파일로 대체됩니다. 빌드 타임에 JSON을 읽어서 정적 HTML로 생성하는 SSG(Static Site Generation) 방식으로 전환합니다. (Chapter 8, 13에서 상세히 다룹니다.)

다운로드 차단 — 가능할까?

커리큘럼 HTML 파일의 다운로드를 차단할 수 있는지 검토했습니다.

방법효과실제 결과
우클릭 메뉴 차단⚠️ 초보자 억제개발자도구로 우회 가능
iframe 팝업 표시⚠️ 부분적URL 직접 접근 시 다운 가능
서버 인증 + 워터마크✅ 실질적 보호서버 필요 (현재 정적 사이트)

결론: 브라우저가 화면에 표시하려면 먼저 다운로드해야 하는 구조적 한계. 현재는 우클릭 차단 + iframe 모달(비전문가 억제 수준)을 적용하고, 배포 단계에서 서버 인증을 고려하기로 했습니다.

📌 핵심 포인트
  • 원본 데이터(엑셀)는 파싱 → 정제 → 정렬 과정을 거쳐 웹 데이터로 변환합니다
  • 콘텐츠가 계속 추가되는 구조라면 CMS 방식(데이터 파일 분리)을 설계하세요
  • 프로토타입에서는 단순한 방식(JS 배열)으로 시작하고, 배포 시 SSG로 전환하는 전략이 효율적입니다
  • 클라이언트 측 다운로드 차단은 완벽하지 않습니다 — 진짜 보호가 필요하면 서버 인증이 필수

3. 홈페이지 구조화

5개 페이지 설계

처음에는 모든 콘텐츠를 하나의 랜딩 페이지에 넣었지만, About 스토리가 길어지면서 멀티페이지 구조로 전환했습니다.

방안장점단점
A. 싱글 페이지단순함스크롤 과부하, SEO 불리
B. 멀티 페이지SEO 유리, 관리 편리네비게이션 필요

최종 5개 페이지 구조:

index.html

메인 랜딩 — Hero, About 요약, 강의 분야, 고객사, 유튜브, 문의

about.html

소개 — 스토리, 타임라인, 학력, 자격증, CTA

curriculum.html

커리큘럼 & 교재 — 11개 커리큘럼 + 5개 교재 갤러리

ai-sites.html

AI 도구들 — 33개 AI 사이트, 11개 카테고리

portfolio.html

포트폴리오 — 직접 만든 SaaS·앱·웹 10개

콘텐츠 업데이트를 고려한 구조

페이지 구조와 별도로, 콘텐츠가 지속적으로 추가될 영역(커리큘럼, 교재)은 별도의 데이터 관리 구조를 설계했습니다.

outputs/ ├── index.html ← 메인 랜딩 ├── about.html ← 스토리 페이지 ├── curriculum.html ← 커리큘럼 & 교재 ├── ai-sites.html ← AI 도구들 ├── portfolio.html ← 포트폴리오 ├── style.css ← 공통 스타일 ├── content.js ← 커리큘럼·교재 데이터 ├── curriculum/ ← 커리큘럼 HTML 파일들 │ ├── 교보생명-마켓센싱-20h.html │ └── ... ├── textbook/ ← 교재 HTML 파일들 │ └── OpenClaw-교재.html └── history/ ← 구버전 백업
📌 핵심 포인트
  • 콘텐츠가 많으면 멀티페이지가 SEO에 유리합니다 — 각 페이지가 별도 URL로 색인됩니다
  • 자주 추가되는 콘텐츠(커리큘럼, 교재)는 별도 폴더 + 데이터 파일로 분리하세요
  • 구버전 백업(history/)을 습관화하면 실수 시 복구가 쉽습니다

4. 디자인 시스템

컬러 & 타이포그래피

전체 디자인 시스템의 기본 컬러는 sky blue (#0ea5e9)입니다. 전문적이면서도 신뢰감을 주는 색상으로, AI·테크 분야에 적합합니다.

컬러 팔레트

sky-d
#0ea5e9
sky-m
#38bdf8
sky-l
#bae6fd
ink
#1e293b
bg
#f8fafc

타이포그래피: Pretendard Variable (한글 최적화 무료 폰트). 본문 16px, 줄간격 1.7, 제목은 weight 700~800.

컴포넌트 스타일

주요 UI 컴포넌트들의 디자인 원칙:

  • 카드: 흰 배경, 얇은 border(#e2e8f0), 최소 그림자, hover 시 border 색상만 변경
  • 버튼: sky blue 배경 + 흰 텍스트, hover 시 약간 어두워짐
  • 칩(chip): 회색 배경, 작은 패딩, 11.5px 폰트 — 고객사 나열에 사용
  • 섹션 교대: 밝음(흰) → 다크 → 밝음 패턴으로 시각적 구분
🎨
YouTube 섹션 색상 충돌 해결: 유튜브 브랜드 빨강(#ff5a5a)을 섹션 헤더에 적용했더니 sky blue 기조에서 혼자 "튀었습니다". 검토 결과, 브랜드 연상은 구독 버튼 하나로 충분하다고 판단하여 sky-d로 통일했습니다.
📌 핵심 포인트
  • 디자인 시스템(컬러·폰트·컴포넌트)을 먼저 정하면 일관성 있는 페이지를 빠르게 만들 수 있습니다
  • 외부 브랜드 색상(유튜브 빨강 등)은 최소한만 사용하세요 — 전체 기조를 해칩니다
  • Pretendard는 한글 웹사이트에 최적화된 무료 폰트입니다 (가변폰트 지원)
Part 2

웹사이트 개발 및 배포

디자인 피드백을 반영하고, 기능을 구현하고, Astro로 전환하여 Vercel에 배포합니다.

5. 디자인 개선 과정

홈페이지 개발은 한 번에 완성되지 않습니다. 피드백 → 수정 → 확인의 반복이 핵심입니다. AI 바이브코딩에서도 이 사이클은 동일합니다.

피드백 → 수정 반복

Hero 섹션 변천사

Hero 섹션(첫 화면)은 여러 차례 구조가 바뀌었습니다.

버전구조문제점 / 피드백
v03 사진(왼) + 텍스트(오) + Stats Bar "숫자 중복 — Hero와 Stats Bar에 같은 수치"
v04 사진(왼) + 텍스트(오), Stats Bar 제거 "사진이 너무 작다", "배경이 밋밋"
v05 텍스트 전용 센터 정렬 (이름 80px) 사진은 About 4단 카드로 이동

About 섹션 변천사

1
v03 — Hero 안에 3줄 요약
LinkedIn 수준의 이력서. "전문가의 정성이 느껴지지 않는다" 피드백.
2
v04 — 별도 about.html 분리
랜딩에는 3~4줄 요약 + "자세히 보기" 링크. About 페이지에 스토리 전문.
3
v05 — About 4단 카드
사진 + Education + Career + Certifications 4열 반응형 그리드. Hero 바로 다음에 배치.

고객사 chip 잔상 효과

215개 고객사를 칩으로 나열하면서, 마우스를 올렸을 때 시각적 피드백을 주기 위해 잔상 효과를 구현했습니다.

동작 원리:

  1. mouseenter → 즉시 네이비 배경으로 변경
  2. mouseleave → 네이비 상태로 2초 유지
  3. 2초 후 → 3초 linear로 원래 색상으로 페이드아웃

빠르게 고객사 목록 위를 스캔하면 마우스가 지나간 자리에 네이비 잔상이 남아 흥미로운 시각 효과를 만들어냅니다.

📌 핵심 포인트
  • 디자인은 반드시 피드백 사이클을 거칩니다 — AI 바이브코딩도 예외가 아닙니다
  • 같은 정보(숫자 등)를 여러 곳에 중복 표시하면 강조 효과가 희석됩니다
  • 작은 인터랙션(chip 잔상 등)이 사이트의 인상을 크게 바꿉니다

6. 기능 구현

모달 팝업 → 새 탭 전환

커리큘럼 카드를 클릭하면 처음에는 iframe 모달 팝업으로 상세 내용을 표시했습니다. 하지만 이 방식에는 문제가 있었습니다.

방식장점단점
iframe 모달 팝업 페이지 이동 없이 확인 SEO 불리 (iframe 안 콘텐츠 미색인), 모바일 UX 나쁨
새 탭 열기 (target="_blank") SEO 유리, 깔끔한 UX 페이지 이동 필요

SEO를 고려한 하이브리드 구조

최종적으로 <a href> + onclick 병행 구조를 채택했습니다:

<a href="curriculum/교보생명.html"
   onclick="window.open(this.href,'_blank');return false;">
  자세히 보기 →
</a>
  • 사용자 클릭 → onclick 실행 → 새 탭 열림 (return false로 href 차단)
  • 우클릭 새 탭 → href 그대로 작동
  • 구글 크롤러 → href 따라가서 커리큘럼 파일도 색인

반응형 그리드

각 섹션별 반응형 브레이크포인트를 정리하면:

섹션데스크톱태블릿 (1024px↓)모바일 (480px↓)
About 4단 카드4열2열1열
강의 분야3열2열1열
유튜브2열2열1열
온라인 강의3열2열1열
📌 핵심 포인트
  • iframe 모달은 SEO에 불리합니다 — 검색엔진은 iframe 안 콘텐츠를 색인하지 않습니다
  • <a href> + onclick 패턴으로 사용자와 크롤러 모두 대응할 수 있습니다
  • 반응형 디자인은 처음부터 고려해야 합니다 — 나중에 추가하면 공수가 2~3배 늘어납니다

7. 기술 선택: 왜 Astro인가?

프로토타입은 순수 HTML/CSS/JS로 만들었습니다. 하지만 배포 단계에서는 더 적합한 프레임워크가 필요했습니다.

프레임워크 비교

프레임워크특징적합성판정
순수 HTML 의존성 없음, 단순 5개 페이지에서 헤더/푸터 관리 어려움 ❌ 프로토타입용
Next.js React 기반, SSR/SSG 지원 이 프로젝트에는 과잉 (React 번들 불필요) ❌ 오버킬
Hugo Go 기반, 빠른 빌드 Go 템플릿 문법 학습 필요 ❌ 러닝커브
Astro 정적 우선, 제로 JS 번들, 컴포넌트 지원 HTML 그대로 사용 + Layout 분리 + 빌드 타임 SSG ✅ 최적

Astro를 선택한 이유

1
기존 HTML을 거의 그대로 사용
Astro 컴포넌트(.astro)는 HTML과 거의 동일한 문법입니다. 프로토타입에서 작성한 HTML을 최소한의 수정으로 가져올 수 있었습니다.
2
Layout 컴포넌트로 헤더/푸터 일원화
Layout.astro에 Nav, Footer를 한 번 정의하면 5개 페이지 모두 자동 적용. 헤더 수정 → 1개 파일만 고치면 끝.
3
제로 JavaScript 번들
빌드 결과물에 프레임워크 JS가 포함되지 않습니다. 순수 정적 HTML + CSS. 로딩 속도가 빠릅니다.
4
빌드 타임 데이터 처리 (SSG)
_meta.json을 빌드 시점에 읽어서 커리큘럼 카드를 정적 HTML로 생성합니다. 검색엔진 크롤러가 JS 없이도 모든 카드를 볼 수 있습니다.
💬
헤더/푸터 공유 방법에 대한 질문: "페이지가 늘어날수록 헤더/푸터 수정이 어렵지 않나? 전문가들은 어떻게 해?"

검토된 방법: ① 하드코딩 복붙 → ② JS fetch/include → ③ Web Components → ④ Astro/Next.js Layout

결정: "지금은 하드코딩으로 빠르게 만들고, 배포할 때 Astro로 한 번에 전환하자."
📌 핵심 포인트
  • 프로토타입은 순수 HTML로 빠르게, 배포용은 프레임워크로 전환하는 전략이 효율적입니다
  • Astro는 "정적 사이트 + 컴포넌트 분리"가 필요할 때 최적의 선택입니다
  • Next.js는 동적 기능(로그인, DB 등)이 필요할 때, Hugo는 Go에 익숙할 때 적합합니다
  • 프레임워크 선택 기준: "이 프로젝트에 필요한 최소한의 도구가 무엇인가"

8. HTML → Astro 변환

Layout, Nav, Footer 컴포넌트 분리

Astro 프로젝트를 초기화하고 컴포넌트를 분리했습니다.

프로젝트 초기화
$ npm create astro@latest site -- --template minimal
✔ Project created!

컴포넌트 구조:

site/src/ ├── layouts/ │ └── Layout.astro ← Nav + slot + Footer, 폰트, CSS ├── components/ │ ├── Nav.astro ← 5개 메뉴 + 강의 문의 버튼 │ └── Footer.astro ← 로고 이미지 링크 ├── pages/ │ ├── index.astro ← 1152줄 │ ├── about.astro ← 557줄 │ ├── curriculum.astro ← SSG 렌더링 │ ├── ai-sites.astro ← 카테고리 스크롤 │ └── portfolio.astro ← 이미지 갤러리 └── styles/ └── global.css ← 공통 스타일 (style.css에서 복사)

Layout.astro의 핵심 구조:

---
// Layout.astro (프론트매터)
import Nav from '../components/Nav.astro';
import Footer from '../components/Footer.astro';
const { title, description } = Astro.props;
---
<html lang="ko">
<head>
  <meta charset="UTF-8">
  <title>{title}</title>
  <meta name="description" content={description}>
  <link rel="preconnect" href="https://fonts.googleapis.com">
</head>
<body>
  <Nav currentPath={Astro.url.pathname} />
  <slot />  <!-- 각 페이지의 콘텐츠가 여기에 삽입됩니다 -->
  <Footer />
</body>
</html>

페이지 변환 시 주의사항

HTML → Astro 변환 과정에서 만난 실제 이슈들입니다.

🐛 scrollTo 함수명 충돌

ai-sites.html에서 카테고리 이동에 scrollTo() 함수를 정의했는데, 브라우저 내장 window.scrollTo와 이름이 충돌했습니다.

해결: scrollToscrollToCat으로 함수명 변경.

🐛 커리큘럼 경로 중복

content.js의 file이 curriculum/파일명.html인데 JS에서 /curriculum/을 또 붙여서 경로가 이중으로 적용.

해결: href="/" + item.file 절대경로로 변경.

🐛 style vs style is:global

Astro의 <style>은 기본적으로 scoped(해당 컴포넌트에만 적용)입니다. JS로 동적 생성한 요소에는 스타일이 적용되지 않았습니다.

해결: <style is:global>로 변경하여 전역 스타일 적용.

📌 핵심 포인트
  • Astro 변환 시 가장 흔한 실수: 브라우저 내장 함수와 이름 충돌, 경로 중복, scoped 스타일
  • Layout.astro의 <slot />이 핵심입니다 — 각 페이지 내용이 이 자리에 삽입됩니다
  • JS로 동적 생성하는 요소에는 is:global 스타일이 필요합니다

9. 배포

GitHub 리포지토리 생성

GitHub 리포 생성 & 푸시
$ cd site
$ git init
$ git add .
$ git commit -m "Initial Astro site - hyunsoo-homepage v05"
$ gh repo create hyunsoo-7/hyunsoo-homepage --public --push
✓ Created repository hyunsoo-7/hyunsoo-homepage on GitHub

Vercel 연동

Vercel은 정적 사이트 배포에 최적화된 플랫폼입니다. GitHub 리포와 연결하면 push할 때마다 자동 배포됩니다.

Vercel 배포
$ vercel --prod
🔗 Linked to hyunsoo7/hyunsoo-homepage
📦 Built 5 pages in 2.41s
✅ Production: https://site-gilt-one-13.vercel.app

커스텀 도메인 연결

Vercel이 자동 생성한 URL(site-gilt-one-13.vercel.app)은 기억하기 어렵습니다. 가비아에서 ahnhyunsoo.com 도메인을 구매하여 연결했습니다. (DNS 설정은 Chapter 13에서 상세히 다룹니다.)

📌 핵심 포인트
  • GitHub + Vercel 조합은 정적 사이트 배포의 표준입니다 — push만 하면 자동 배포
  • 첫 배포는 vercel --prod 수동 배포로 시작, 이후 GitHub 연동으로 자동화
  • 커스텀 도메인은 사이트의 전문성을 높입니다 — 개인 브랜딩에 필수
Part 3

SEO와 GEO

검색엔진 최적화(SEO)와 AI 검색 최적화(GEO)를 통해 홈페이지의 발견 가능성을 높입니다.

10. SEO/GEO 진단

사이트 전체 점검 보고서

배포 직후, 사이트 전체를 SEO/GEO 관점에서 진단했습니다. 결과는 11개 항목으로 분류됩니다.

📋
진단 지시: "구글 SEO, GEO 관점에서 사이트 전체를 점검하고, 개선이 필요한 부분에 대해서 보고서를 제출해라."

🔴 심각 — 즉시 수정 필요

#항목현재 상태영향
1robots.txt미생성크롤링 범위 미명시
2sitemap.xml미생성페이지 목록 전달 불가
3페이지별 description기본값 공유검색 결과 표시 불량
4OG + Twitter Card없음SNS 링크 미리보기 불가
5canonical URL없음중복 페이지 판별 불가

🟡 중요 — 빠른 시일 내 수정

#항목현재 상태영향
6JSON-LD 구조화 데이터없음리치 결과 미노출
7커리큘럼 SSG 전환JS 동적 렌더링크롤러가 빈 페이지로 인식
8모달 잔여 코드잔존불필요 코드 증가

🟢 개선하면 좋음

#항목현재 상태
9성능 최적화 (preconnect, preload)미적용
10커스텀 faviconAstro 기본값
11이미지 alt 텍스트일부 부족

우선순위별 실행 계획

순위작업예상 시간효과
1robots.txt + sitemap.xml5분🔴 크롤링 기본
2페이지별 description10분🔴 검색 결과 표시
3OG + Twitter Card15분🔴 링크 미리보기
4canonical URL5분🔴 중복 방지
5JSON-LD 구조화 데이터20분🟡 리치 결과
6커리큘럼 SSG 전환30분🟡 크롤러 대응
7성능 최적화10분🟢 웹 바이탈
📌 핵심 포인트
  • 배포 후 반드시 SEO/GEO 진단을 실시하세요 — 배포만으로는 검색에 노출되지 않습니다
  • 심각도별로 분류하면 작업 우선순위를 객관적으로 결정할 수 있습니다
  • 가장 큰 효과 대비 적은 공수: robots.txt + sitemap.xml (5분 작업)

11. 기본 SEO 설정

robots.txt + sitemap.xml

robots.txt는 검색엔진 크롤러에게 "어디를 크롤링해도 되는지" 알려주는 파일입니다. sitemap.xml은 사이트의 모든 페이지 목록을 제공합니다.

# public/robots.txt
User-agent: *
Allow: /
Sitemap: https://ahnhyunsoo.com/sitemap.xml
<!-- public/sitemap.xml -->
<?xml version="1.0" encoding="UTF-8"?>
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
  <url>
    <loc>https://ahnhyunsoo.com/</loc>
    <priority>1.0</priority>
  </url>
  <url>
    <loc>https://ahnhyunsoo.com/about</loc>
    <priority>0.9</priority>
  </url>
  <url>
    <loc>https://ahnhyunsoo.com/curriculum</loc>
    <priority>0.9</priority>
  </url>
  <url>
    <loc>https://ahnhyunsoo.com/portfolio</loc>
    <priority>0.8</priority>
  </url>
  <url>
    <loc>https://ahnhyunsoo.com/ai-sites</loc>
    <priority>0.7</priority>
  </url>
</urlset>

페이지별 description 설계 원칙

모든 페이지가 같은 description을 공유하고 있었습니다. 구글 검색 결과에는 이 description이 그대로 노출되기 때문에, 각 페이지별 고유한 문장이 필요합니다.

설계 원칙

  • 팩트 + 숫자 중심: "300+ 기업 AI 교육" 처럼 검증 가능한 정보
  • 페이지별 고유 정보: 다른 페이지와 겹치지 않는 핵심 내용
  • 자연문장에 키워드 포함: 키워드 나열이 아닌 읽을 수 있는 문장
  • 150자 이내: 구글이 잘라내지 않는 적정 길이

각 페이지별 description

페이지description
㈜알앤비디파트너스 대표 컨설턴트. 삼성전자·현대자동차 등 300+ 기업 AI 실무 교육. 20년 기술혁신 컨설팅 경력. 한국GPT협회 상임이사.
소개삼성그룹 자동화 엔지니어에서 시작해 20년간 PMP, TRIZ Level 4, AICPA 등을 취득하며...
커리큘럼AI 활용 기본·심화, 바이브코딩, MS 오피스 자동화... 실제 출강 커리큘럼 11개와 직접 제작한 교재 5종 공개.
AI 도구들ChatGPT, Claude, Gemini 등 LLM부터... 강의에서 직접 사용하는 AI 사이트 30개+.
포트폴리오마크다운 편집기, PDF 번역기... AI와 바이브코딩으로 직접 만든 10개 서비스 모음.

canonical URL

canonical URL은 검색엔진에게 "이 페이지의 정식 주소가 이것이다"라고 알려줍니다. www 버전과 non-www 버전이 다른 페이지로 인식되는 것을 방지합니다.

<!-- Layout.astro에서 자동 생성 -->
<link rel="canonical" href={`https://ahnhyunsoo.com${currentPath}`} />
📌 핵심 포인트
  • robots.txt + sitemap.xml은 SEO의 "입장권"입니다 — 없으면 검색 등록이 어렵습니다
  • description은 구글 검색 결과에 직접 노출됩니다 — 광고 카피처럼 신중하게 작성하세요
  • canonical URL로 중복 색인을 방지하세요 — www vs non-www, HTTP vs HTTPS 등

12. OG 메타태그 & 구조화 데이터

OG + Twitter Card

OG(Open Graph) 메타태그는 카카오톡, 슬랙, 텔레그램 등에서 링크를 공유할 때 미리보기 카드를 만들어줍니다. 이것이 없으면 URL 텍스트만 표시됩니다.

<!-- Layout.astro에 추가 -->
<meta property="og:title" content={title} />
<meta property="og:description" content={description} />
<meta property="og:image" content="https://ahnhyunsoo.com/og-image.jpg" />
<meta property="og:url" content={`https://ahnhyunsoo.com${currentPath}`} />
<meta property="og:locale" content="ko_KR" />
<meta property="og:site_name" content="안현수 AI 강사" />

<meta name="twitter:card" content="summary_large_image" />
<meta name="twitter:title" content={title} />
<meta name="twitter:description" content={description} />
<meta name="twitter:image" content="https://ahnhyunsoo.com/og-image.jpg" />

OG 이미지 디자인 과정

OG 이미지(1200×630)는 링크 공유 시 가장 먼저 보이는 요소입니다. 여러 차례 수정을 거쳤습니다.

1
1차 — 기본 레이아웃
프로필 사진 + 이름 + 소속. 피드백: "글자가 작고 고객사 이름 나열은 불필요"
2
2차 — 교육 테마 칩
글자 확대, 고객사 → 교육 테마 칩으로 교체. 피드백: "이름 옆에 '대표' 추가"
3
3차 — 최종
프로필 사진 + 이름(대표) + "300+ 기업 / 20년 경력" + 12개 교육 테마 2줄 (ChatGPT, Gemini, Claude, Copilot, Perplexity, 노트북LM, Codex, Claude Code, 바이브코딩, Agent 개발, OpenClaw, AX 컨설팅)

제작 방법: og-preview.html로 디자인 → 로컬에서 확인 → Playwright로 1200×630 캡처 → og-image.jpg 저장

💡
카톡 미리보기 이슈: 홈 description에서 이름이 중복됨 — title이 "안현수"이고 description 첫 단어도 "안현수"라서 어색. description에서 이름을 제거하고 바로 팩트로 시작하도록 수정.

JSON-LD 구조화 데이터

JSON-LD는 검색엔진에게 "이 사이트가 누구의 사이트이고, 어떤 조직에 속하는지"를 기계가 읽을 수 있는 형태로 알려줍니다. 리치 결과(검색 결과에 부가 정보 표시)의 기반이 됩니다.

홈페이지에 @graph로 3개 스키마를 삽입했습니다:

<script type="application/ld+json">
{
  "@context": "https://schema.org",
  "@graph": [
    {
      "@type": "WebSite",
      "name": "안현수 AI 강사",
      "url": "https://ahnhyunsoo.com"
    },
    {
      "@type": "Person",
      "name": "안현수",
      "alternateName": "Ahn Hyunsoo",
      "jobTitle": ["AI 활용 강사", "기술혁신 컨설턴트"],
      "affiliation": [
        {"@type": "Organization", "name": "㈜알앤비디파트너스"},
        {"@type": "Organization", "name": "한국GPT협회"}
      ],
      "alumniOf": [
        {"@type": "CollegeOrUniversity", "name": "고려대학교"},
        {"@type": "CollegeOrUniversity", "name": "한양대학교 기술경영대학원"}
      ],
      "hasCredential": ["PMP", "TRIZ Level 4", "AICPA", "CMA", "NPDP"],
      "knowsAbout": ["AI", "ChatGPT", "바이브코딩", "TRIZ", "PMP",
                      "데이터 분석", "디지털 혁신", "노코드 자동화"],
      "sameAs": [
        "https://www.youtube.com/@버프TV",
        "https://contents.premium.naver.com/chatgpt/buff",
        "https://gptkoreaclass.com",
        "https://kgpt.or.kr"
      ]
    },
    {
      "@type": "Organization",
      "name": "㈜알앤비디파트너스",
      "url": "https://ahnhyunsoo.com"
    }
  ]
}
</script>
📌 핵심 포인트
  • OG 메타태그는 SNS 공유의 첫인상입니다 — 반드시 설정하세요
  • OG 이미지는 1200×630px이 표준입니다 — HTML로 디자인 후 캡처하면 쉽습니다
  • JSON-LD는 구글의 "지식패널" 표시의 기반입니다 — Person 스키마가 가장 중요합니다
  • sameAs에 공식 채널(유튜브, 네이버 등) 링크를 넣으면 검색엔진이 같은 사람으로 인식합니다

13. SSG 전환 & DNS 설정

커리큘럼 SSG 전환

가장 중요한 SEO 개선 작업 중 하나입니다. content.js로 클라이언트에서 동적으로 생성하던 커리큘럼 카드를 Astro 빌드 타임에 정적 HTML로 생성하는 방식으로 전환했습니다.

왜 SSG가 중요한가

방식크롤러가 보는 것결과
JS 동적 렌더링 (content.js) <div id="curriculum-grid"></div> ❌ 커리큘럼 카드 0개 색인
Astro SSG (빌드 타임) 16개 카드가 모두 포함된 완성 HTML ✅ 커리큘럼 카드 16개 색인

구현 방법

---
// curriculum.astro (프론트매터 — 서버 사이드)
import fs from 'node:fs';
const metaPath = './public/_meta.json';
const meta = JSON.parse(fs.readFileSync(metaPath, 'utf-8'));
const curricula = meta.curriculum;
const textbooks = meta.textbook;
---

<!-- 빌드 시점에 정적 HTML로 생성됨 -->
{curricula.map(item => (
  <a href={`/curriculum/${item.file}`} class="ccl-card">
    <h4>{item.title}</h4>
    <p>{item.desc}</p>
    <span class="hours">{item.hours}</span>
  </a>
))}

이 전환 후 content.js 파일은 삭제되었습니다. 모든 데이터는 _meta.json 한 파일로 관리합니다.

DNS 설정 (가비아)

가비아에서 도메인을 구매한 후, DNS 레코드를 설정하여 Vercel과 연결했습니다.

타입호스트용도
A@76.76.21.21Vercel 서버 IP
CNAMEwwwcname.vercel-dns.com.www 서브도메인
TXT@(Google 인증 코드)Search Console 인증
💡
A 레코드 vs CNAME: A 레코드는 IP 주소를 직접 가리키고, CNAME은 다른 도메인을 가리킵니다. 루트 도메인(@)에는 A 레코드를, www에는 CNAME을 사용하는 것이 표준입니다.

Google Search Console 등록

마지막으로, Google Search Console에 사이트를 등록하고 sitemap.xml을 제출했습니다.

1
소유권 인증
가비아 DNS에 Google 제공 TXT 레코드 추가 → 소유권 확인 완료
2
Sitemap 제출
https://ahnhyunsoo.com/sitemap.xml 을 Search Console에 제출 → 5개 페이지 색인 요청
3
개별 URL 색인 요청
5개 페이지 URL을 각각 입력하여 "색인 생성 요청" → 빠른 색인 유도
Bing도 함께: Bing Webmaster Tools에서 "Google Search Console에서 가져오기"를 누르면 별도 인증 없이 바로 등록됩니다. Bing + Copilot 검색 대응까지 한 번에 완료.

성능 최적화

마지막으로 웹 성능을 높이기 위해 리소스 로딩을 최적화했습니다.

Layout.astro
<!-- Google Fonts preconnect -->
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>

<!-- Font Awesome: preload로 렌더 블로킹 제거 -->
<link rel="preload" href="...font-awesome/all.min.css"
      as="style" onload="this.onload=null;this.rel='stylesheet'">
💡
preconnect vs preload: preconnect는 DNS+TCP+TLS 연결을 미리 맺고, preload는 리소스 다운로드를 즉시 시작합니다. 폰트처럼 외부 서버 리소스는 preconnect가, CSS 파일은 preload가 효과적입니다.

마무리

이 교재에서는 퍼스널 브랜딩 홈페이지를 기획 → 디자인 → 개발 → 배포 → SEO/GEO 최적화까지 전 과정을 다뤘습니다.

핵심은 세 가지입니다:

  1. 콘텐츠가 먼저 — 기술보다 "어떤 정보를 어떻게 전달할지"가 더 중요합니다
  2. AI와 함께 만들기 — OpenClaw + Claude를 활용한 바이브코딩으로, 전문 개발자 없이도 프로덕션 수준의 사이트를 만들 수 있습니다
  3. 만든 후가 시작 — SEO, GEO, 성능 최적화는 배포 이후에 하는 것이 아니라, 처음부터 설계에 포함되어야 합니다
🎯
이 홈페이지는 지금도 진화 중입니다.
커리큘럼 추가, 포트폴리오 업데이트, 블로그 연동 등 — _meta.json 수정 + git push만으로 지속적으로 업데이트되고 있습니다.

실제 사이트: ahnhyunsoo.com