← 목록으로
BinaryHub 개발

BinaryHub 개발기 ② 블로그를 직접 만들기 — BBlog와 부원 블로그

2

BinaryHub 개발기. 글을 쓸 곳을 고르는 대신, 만들기로 했다.

왜 직접 만들었나

블로그 서비스는 이미 많다. 티스토리, 벨로그, Medium, GitHub Pages 위의 정적 사이트 제너레이터까지. 그런데 기존 서비스마다 어딘가 거슬렸다. 광고가 끼는 곳, 디자인이 내 톤이랑 안 맞는 곳, 내가 손댈 수 있는 게 별로 없는 곳. 무엇보다 — 이미 도메인이 있고 Next.js 앱이 두 개나 굴러가는 상황에서, 그냥 같은 스택으로 블로그도 띄우는 게 가장 단순했다.

그래서 만들었다. 이름은 BBlog. binaryhub.club 안에서 /blog로 들어오는 부분이다.

마크다운 파일이 곧 글이다

DB도 없고 관리자 페이지도 없다. 글은 그냥 content/posts/ 아래의 .md 파일 하나다. 제목·날짜·카테고리·태그·요약은 frontmatter에 적는다.

---
title: "BinaryHub 개발기 ② ..."
date: "2026-06-11"
category: "binaryhub"
tags: ["BinaryHub", "BBlog"]
summary: "..."
---
 
본문 시작

빌드 시점에 gray-matter로 frontmatter를 파싱하고, react-markdown + remark-gfm으로 본문을 렌더한다. 결과는 정적 페이지로 미리 생성된다. 글을 쓰는 흐름이 단순하다 — .md 파일 하나 추가하고, 빌드하고, 끝.

이 방식의 좋은 점은 git이 글의 버전 관리를 그대로 떠맡는다는 것이다. 글을 수정하면 commit이 남고, 잘못 쓴 게 있으면 되돌리기 쉽다. "글을 쓴다"는 행위가 "코드를 쓴다"와 거의 같은 흐름 안에 들어온다.

카테고리는 하드코딩

카테고리도 별도 테이블 없이 그냥 코드에 박혀 있다.

export const CATEGORIES = [
  { slug: "dev", label: "개발·프로그래밍" },
  { slug: "research", label: "연구노트" },
  { slug: "cre", label: "창의개인연구" },
  { slug: "nsgh-tools", label: "북곽툴즈 개발" },
  { slug: "binaryhub", label: "BinaryHub 개발" },
  ...
];

처음엔 "이거 좀 약하지 않나" 싶었는데, 글 분류가 자주 늘어나는 종류의 것도 아니라서 충분하다. 새 시리즈 시작할 때 한 줄 추가하면 된다.

부원 블로그(Club)를 한 단계 더

블로그가 자리를 잡을 즈음, 동아리 부원 몇 명도 글을 쓰고 싶다는 얘기가 나왔다. 그때 선택지는 둘이었다. 각자 따로 블로그를 만들게 하거나, BBlog 안에 부원별 영역을 두거나.

각자 따로 만드는 건 부담이 너무 크다. 부원 입장에서 도메인·호스팅·디자인을 다 신경 써야 한다. 그래서 같은 앱 안에 부원별 블로그를 한 단계 더 두는 쪽으로 갔다. 라우트는 /club/[member]로 잡았다.

  • /club — 부원 전체 인덱스 (자기소개 카드 모음)
  • /club/[member] — 부원 본인 홈
  • /club/[member]/posts/[slug] — 부원 글 본문
  • /club/[member]/category/..., .../tag/... — 부원 안에서의 카테고리·태그

콘텐츠 디렉토리도 부원별로 나눴다.

content/
  posts/                ← BBlog 본인 글
  club/
    member1/
      profile.json
      posts/welcome.md
    member2/
      ...

부원이 글을 추가하는 흐름은 "본인 폴더 아래 .md 추가"로 통일했다. 사이드 드로어와 헤더 컴포넌트는 컨텍스트(자기 블로그인지, 부원 블로그인지)에 따라 다른 사이드바를 렌더하게 분기해 뒀다.

부원 이메일을 평문으로 두지 않기

부원별 로그인은 이메일 기반인데, lib/club.ts에 이메일을 평문으로 박아 두면 모노레포가 공개 전환될 때 부원들 이메일이 그대로 노출된다. 그래서 이메일은 코드에 두지 않고 .env.localMEMBER_EMAIL_<SLUG> 환경변수로만 관리한다.

// lib/club.ts
{ slug: "member1", displayName: "...", email: emailFor("member1"), ... }
# .env.local
[email protected]

서버 컴포넌트에서만 읽고, 클라이언트 번들에는 절대 들어가지 않게 했다. 작은 디테일인데, 한 번 잘못 박혀 있으면 되돌리기 곤란하다.

단순함을 유지하기

블로그 만들기는 한번 빠지면 끝이 없다. 검색·태그 클라우드·관련 글·뉴스레터·코멘트·뷰 카운트… 처음엔 다 넣고 싶어진다. 그러나 글이 별로 없을 때 기능만 많은 블로그만큼 어색한 것도 없다.

그래서 BBlog는 의도적으로 기능을 적게 가져갔다. 글 목록, 본문, 카테고리, 태그, 검색. 그게 다다. 글이 정말 늘어나서 부족함이 생기면 그때 더한다.