1. 개요

본 문서는 GitHub Pages 블로그 자동화 시스템 초기 구축 이후 진행된 기능 고도화 작업에 대한 회고 보고서이다. 성공적으로 구현된 기능뿐 아니라 시도하였으나 실패하거나 한계에 부딪힌 사례도 함께 기록하여, 실제 개발 과정을 있는 그대로 남긴다.


2. 고도화 항목 목록

항목 결과
Netlify CMS + Cloudflare Workers OAuth ✅ 성공
Weight 기반 글 정렬 자동화 ✅ 성공
URL 파라미터 기반 카테고리 네비게이션 ✅ 성공
홈페이지 최신순 정렬 ✅ 성공
CSS 커스터마이징 ✅ 성공
GitHub Actions Pages 배포 방식 전환 ✅ 성공
CMS 에디터에서 초성 입력 지원 ❌ 부분 성공 (한계 존재)
카테고리별 prev/next 완전 자동화 ⚠️ 구현하였으나 불완전

3. 기능별 상세 내용 및 트러블슈팅

3-1. 블로그 관리 UI (Netlify CMS + Cloudflare Workers)

도입 이유 GitHub Issue 방식 외에 블로그 내에서 직접 글을 작성·수정·삭제할 수 있는 GUI가 필요하였다.

트러블 1. Netlify OAuth 엔드포인트 Not Found GitHub Pages는 Netlify 인프라를 사용하지 않으므로 api.netlify.com OAuth 엔드포인트가 동작하지 않았다. 대안으로 sveltia-cms-auth 오픈소스 프록시를 시도하였으나 해당 서버가 운영 중단 상태였다. → 해결: Cloudflare Workers에 GitHub OAuth 프록시를 직접 구축하였다.


3-2. CMS 에디터 초성 입력 문제 (부분 실패)

시도 이유 한글 초성만으로 메모를 작성하는 것은 블러팅의 특성상 자연스러운 입력 방식이다. CMS 에디터에서도 초성 입력이 가능해야 한다고 판단하였다.

시도한 방법들

1차 시도: Rich Text 에디터에서 초성 입력 → CMS가 완성되지 않은 문자로 인식하여 저장 자체를 차단하였다.

2차 시도: config.yml에서 내용 필드를 required: false로 설정 → 필드 자체를 비워도 저장은 되나, 초성 입력 시 여전히 동일한 문제가 발생하였다.

3차 시도: modes: ["raw"], default_mode: "raw" 설정으로 Markdown 모드를 기본값으로 지정 → Markdown 모드는 순수 텍스트 입력창으로 동작하므로 초성 입력이 가능해졌다. 단, Markdown 모드에서도 초성만 입력된 상태로 저장 시 일부 환경에서 렌더링 문제가 발생할 수 있다.

결론 Netlify CMS 자체의 한글 초성 처리 방식이 근본적인 원인으로, CMS 소스 코드를 직접 수정하지 않는 한 완전한 해결은 불가능하다. Markdown 모드로 전환하는 것이 현재 가능한 최선의 대안이다.


3-3. 글 정렬 자동화 (Weight 자동 부여)

도입 이유 초기에는 날짜 기준으로 정렬을 시도하였으나, /admin에서 글 작성 시 날짜를 수동으로 수정할 수 있어 순서가 뒤바뀔 위험이 있었다. 또한 weight 필드를 수동으로 입력하게 하는 방식은 동시 작성 시 충돌 가능성이 있었다. 이에 GitHub Actions가 자동으로 순서 번호를 부여하는 방식을 채택하였다.

트러블 2. draft: false 없는 파일에서 weight 삽입 실패 /admin에서 생성된 파일에는 draft: false 항목이 존재하지 않아, replace("draft: false", ...) 방식의 삽입이 실패하였다. → 해결: 정규식으로 frontmatter 닫는 --- 구분자 직전에 weight를 삽입하는 방식으로 변경하였다.

트러블 3. 봇 커밋이 deploy 워크플로우를 트리거하지 못함 GitHub Actions 봇 커밋은 기본적으로 다른 워크플로우를 트리거하지 않는 보안 정책이 있다. weight 부여 후 배포가 자동으로 이루어지지 않았다. → 해결: Personal Access Token(PAT)을 GitHub Secret에 등록하고, assign-weight.yml의 checkout 단계에서 PAT를 사용하도록 변경하였다.

트러블 4. assign-weight.yml과 deploy.yml의 gh-pages 브랜치 충돌 두 워크플로우가 동시에 gh-pages 브랜치에 push를 시도하면서 "cannot lock ref" 오류가 발생하였다. → 해결: 배포 방식을 peaceiris/actions-gh-pages 브랜치 배포에서 GitHub 공식 actions/deploy-pages 방식으로 전환하고, Pages Source를 "GitHub Actions"로 변경하였다.


3-4. 카테고리 인식 네비게이션 (불완전한 구현)

도입 이유 메인 페이지에서 글에 접근하는 경우 전체 글 순서로, 카테고리 페이지에서 접근하는 경우 해당 카테고리 내 글 순서로 이전/다음 글 네비게이션이 동작해야 한다.

1차 시도: document.referrer 방식 접근 이전 URL을 JavaScript로 감지하여 카테고리 페이지에서 왔는지 판단하는 방식을 구현하였다. 그러나 같은 탭에서 이동했을 때만 작동하고, 새 탭으로 열거나 URL을 직접 입력하면 항상 전체 nav가 표시되는 한계가 있었다.

2차 시도: URL 파라미터 방식 (현재 적용) 카테고리 목록 페이지에서 각 글 링크에 ?from=카테고리슬러그 파라미터를 삽입하고, 글 상세 페이지에서 JavaScript로 파라미터를 감지하여 nav를 전환하는 방식으로 개선하였다.

트러블 5. layouts/_default/list.html이 적용되지 않음 PaperMod 테마는 layouts/_default/ 구조 없이 layouts/ 바로 아래에 템플릿을 배치한다. layouts/_default/list.html로 생성하여 적용이 되지 않았다. → 해결: layouts/list.html로 경로를 변경하였다.

트러블 6. cat-nav display 전환 실패 JavaScript에서 style.display = 'flex'로 cat-nav를 표시하려 하였으나, PaperMod paginav 클래스가 flex 레이아웃이 아닌 경우 렌더링이 되지 않았다. → 해결: display: 'block'으로 변경하였다.

현재 한계 URL 파라미터 방식은 카테고리 목록 페이지를 경유하지 않으면 파라미터가 붙지 않는다. 예를 들어 외부에서 링크를 직접 공유받아 접근하는 경우 항상 전체 글 nav가 표시된다. 완전한 해결을 위해서는 서버 사이드 렌더링 또는 별도의 상태 관리가 필요하나, 정적 사이트의 특성상 현재 방식이 가능한 최선이다.


3-5. 홈페이지 최신순 정렬

도입 이유 메인 페이지에서 가장 최근에 작성된 글이 최상단에 표시되어야 한다.

트러블 7. Hugo 기본 홈 레이아웃에 정렬 설정 미적용 hugo.toml에 정렬 관련 파라미터를 추가하여도 홈페이지에 반영되지 않았다. Hugo PaperMod의 홈 레이아웃이 별도의 정렬 설정을 지원하지 않기 때문이었다. → 해결: layouts/index.html 커스텀 템플릿을 직접 작성하여 sort $pages "Params.weight" "desc" 정렬을 명시적으로 적용하였다.


3-6. CSS 커스터마이징

도입 이유 PaperMod 기본 스타일에서 테이블 정렬이 깨지고, 인용구 가독성이 낮았으며, 헤딩 간격이 좁았다.

assets/css/extended/custom.css 파일을 생성하여 테이블 border, 인용구 스타일, 헤딩 간격, 단락 및 리스트 간격을 개선하였다.


3-7. 카테고리 확장 (0 to 1)

직접 구축한 프로젝트를 기록하는 전용 카테고리로 0 to 1을 추가하였다. 해당 카테고리는 학습 내용 블러팅이 아닌 프로젝트 기록 목적이므로 AI 피드백 없이 원문 그대로 업로드되도록 설계하였다.


4. 현재 시스템 구성

카테고리 AI 피드백
Tech Blurting ✅
Coding Test ✅
Open Source Analysis ✅
0 to 1 ❌

5. 결론 및 회고

이번 고도화 과정에서 가장 인상 깊었던 점은, 정적 사이트의 구조적 한계가 생각보다 자주 마주쳐진다는 것이다. 카테고리 인식 네비게이션, 초성 입력 지원, 봇 커밋 트리거 문제 등은 모두 정적 사이트 또는 서드파티 CMS의 근본적인 제약에서 비롯된 것이었다. 이를 우회하는 과정에서 Cloudflare Workers, GitHub Actions PAT, URL 파라미터 방식 등 다양한 기술을 활용하였으며, 완전한 해결이 불가능한 경우 그 한계를 명확히 인식하고 차선의 방법을 선택하는 판단도 중요한 경험이었다.