Dotorian

Next.js로 포트폴리오 블로그를 만든 이유

5분 소요
조회수

처음에는 블로그를 꼭 직접 만들 필요가 있나 싶었다. 글만 쓰면 된다면 티스토리나 브런치, 노션도 충분하다.

그런데 키움디지털 아카데미 강사분께서 블로그 글을 적는 걸 추천한다는 말을 들었다.

이전에도 계속 내 프로젝트들을 보여줄 수 있는 포트폴리오를 보여주고 싶은 사이트를 어떻게 만들까 고민하던 중이라 크게 고민 없이 블로그 겸 포트폴리오 사이트를 만들어보겠다고 결심했다.

아래에서 만드는 과정을 자세히 풀려고 하지만 블로그의 기본 뼈대를 만드는 건 하루면 충분했다.

블로그 겸 포트폴리오 사이트를 만들고자 할 때 AI를 다루는 실력도 보여주고 싶고 디자인 전공으로서 디자인으로도 신경을 쓰고 싶었다. 그러다 보니 그런지 기존 블로그(네이버, 티스토리)로는 충분치 않다고 느껴졌다. 그래서 내가 직접 만들고 싶었고 그래서 Next.js로 직접 만들기로 했다.

내가 원했던 구조

이 블로그에서 초반에 중요하게 생각했던 건 세 가지였다.

  1. 기능 구조와 확장 가능한 코드베이스를 구현할 것
  2. 새롭게 만들지 말고 누군가 만든 것을 따라하기
  3. 디자인을 적용하는 건 후순위

아래는 내가 실제로 넣었던 프롬프트다.

💬 내가 넣은 프롬프트 (펼쳐보기)

너는 시니어 프론트엔드 개발자이자 제품 디자이너야. 나는 포트폴리오 겸 블로그 사이트를 만들고 싶고, 이미 GitHub 레포는 만들어둔 상태야.

목표는 네이버 블로그, 티스토리, 브런치처럼 글을 읽기 좋게 보여주는 개인 블로그 사이트를 만드는 것이야. 디자인은 나중에 디자인 md를 줄거라서 크게 중요하지 않고, 우선 기능 구조와 확장 가능한 코드베이스를 잘 만드는 것이 중요해.

현재 상황

  • 우선 블로그 기능만 먼저 개발
  • 나중에 포트폴리오, 프로젝트 소개, About 페이지 등을 추가할 예정

기술 스택 제안 현재 레포 상태를 먼저 확인한 뒤, 가장 적절한 방식으로 제안해줘.

중요한 요청

  • 한 번에 너무 복잡하게 만들지 말고, 궁금한 점·확실하지 않은 점들은 무조건 물어봐줘. 지금은 기획을 중심으로 하고 나하고 plan을 질문하면서 만들자, 소크라테스처럼 나한테 질문을 던지면서 plan 파일을 만들어줘.
  • 무슨 핵심 기능을 만들지부터 고민해줘.
  • 나중에 확장할 수 있도록 구조를 많이 고려해줘.
  • 작업이 끝나면 변경된 파일 목록과 각 파일의 역할을 설명해줘.

내가 만들려고 하는 사이트는 디자이너 적인 포트폴리오도 있으면서 개발자 적인 블로그가 동시에 있었으면 좋겠다고 생각했다. 그렇기 위해서는 먼저 디자인 적용보다는 초반 프레임워크를 중요하게 생각해야겠다고 생각했다. 디자인보다는 프레임워크 변경이 더 어려울 것 같다고 생각했기 때문이다. 

아래는 Claude가 준 질문을 바탕으로 나눈 대화 요약본이다. (개인적으로 “소크라테스처럼 역질문해줘” 라는 프롬프트를 매우 좋아한다.)



💬 Claude와 나눈 대화 요약

Q. 글을 쓸 때는 어떤 방식으로 할까?
A. 마크다운 파일로 작성

Q. 네이버 블로그와 티스토리 중 어느 쪽 레이아웃을 기본으로 삼을까요? 둘은 구조가 꽤 달라요.
A. 티스토리 기본 스킨 스타일

Q. 기술 스택은 Next.js(App router) + 마크다운 처리 조합을 추천하려는데 괜찮을까요? Vercel 배포와 궁합이 가장 좋고, 나중에 조회수 같은 서버 기능도 붙일 수 있어요.
A. Next.js

Q. 조회수/공감은 유일하게 DB(무료 티어 Redis 등)가 필요한 기능이에요. 언제 구현할까요?
A. 2단계로 미루기


 무조건 AI가 잘 이해하기 쉬운 형식으로 만들려고 했고 그래서 마크다운(Markdown) 형식을 선택했다. 또 한번에 모든 기능을 구현한다고 생각하기보다는 기본이 탄탄한 뼈대를 만들고 대신에 추가 기능을 쉽게 덧붙일 수 있는 구조를 만들고자 했다. 아래는 내가 만든 plan.md이다.

 📄 dotorian-plan.md 다운로드 
 ## 기술 스택

처음 버전의 스택은 단순하게 잡았다.

영역선택
프레임워크Next.js 16 / App Router
콘텐츠Markdown + gray-matter
마크다운 처리unified / remark / rehype
코드 하이라이팅Shiki 기반 rehype-pretty-code
스타일CSS Modules + CSS 변수 토큰

CMS는 넣지 않았다. 지금 단계에서는 글을 빨리 고치고 구조를 바꾸는 게 더 중요했다. CMS를 먼저 붙이면 편해지는 부분도 있지만, 반대로 데이터 모델을 너무 빨리 고정할 수 있다.

그래서 일단 파일 기반으로 시작했다.

Markdown 파이프라인

핵심은 unified 체인이다. 빌드 타임에 Markdown을 HTML로 바꾸고, 런타임에서는 이미 만들어진 글을 보여준다.

src/lib/markdown.ts
const processor = unified()
  .use(remarkParse)
  .use(remarkGfm)
  .use(remarkRehype, { allowDangerousHtml: true })
  .use(rehypeSlug)
  .use(rehypePrettyCode, { theme: { light: 'github-light', dark: 'github-dark' } })
  .use(rehypeStringify);

처음에는 이 부분이 단순해 보였는데, 실제로는 꽤 중요했다. 글 본문, 목차, 코드 블록, slug가 여기서 결정된다.

목차는 같은 트리에서 뽑았다

목차는 별도 규칙으로 만들지 않았다. rehype-slug가 heading에 붙인 id를 같은 hast 트리에서 읽는다.

이렇게 하면 앵커와 목차가 따로 놀 가능성이 줄어든다. 나중에 제목을 바꿔도 같은 파이프라인 안에서 다시 계산된다.

frontmatter는 느슨하게 두지 않았다

글은 자유롭게 쓰고 싶지만, 메타데이터까지 자유로우면 빌드가 불안해진다. 그래서 frontmatter는 zod로 검증했다.

const frontmatterSchema = z.object({
  title: z.string().min(1),
  date: z.string().regex(/^\d{4}-\d{2}-\d{2}$/),
  category: z.string().min(1),
});

특히 날짜는 문자열로 강제했다. YAML이 날짜를 Date 객체로 해석하면 타임존 때문에 하루가 밀릴 수 있다. 작은 문제처럼 보이지만, 글 목록 정렬이나 timeline에서는 바로 티가 난다.

디자인은 나중에 바뀔 수 있게 했다

이 블로그는 처음부터 완성된 디자인을 목표로 하지 않았다. 오히려 나중에 DESIGN.md 기준을 가져와도 CSS 전체를 다시 쓰지 않도록 만드는 게 중요했다.

그래서 스타일은 CSS 변수 토큰을 기준으로 잡았다. 컴포넌트는 실제 색상값보다 --color-surface, --color-border, --color-fg 같은 역할 이름을 참조한다.

이 덕분에 디자인을 바꿀 때 손대야 하는 범위가 줄어든다. 


지금 남은 한계

아직 완성된 블로그라고 보기는 어렵다.

  • 글쓰기 경험은 아직 파일 편집 중심이다.
  • 관리자 화면은 더 다듬어야 한다.
  • 프로젝트 글이 많아졌을 때 탐색 구조도 다시 봐야 한다.
  • 디자인 토큰도 실제 글이 쌓이면서 더 정리해야 한다.

그래도 지금 구조는 마음에 든다. 글, 프로젝트, 디자인 기준이 한 저장소 안에서 같이 움직일 수 있게끔 만들었다.

내가 원했던 건 거창한 블로그도 포트폴리오 페이지도 아닌 나만의 프로젝트를 만들고 그 과정을 글로 남길 수 있는 작업대였다. 지금 버전은 그 출발점에 가깝다.

다음 글에서는 plan.md와 design.md를 가지고 블로그를 만들어간 과정 또 블로그 이름이 왜 Dotorian인지, 그리고 메인 홈 화면에 넣은 다람쥐/도토리 애니메이션 적용 및 수정 과정 등을 적어보겠다.

  • #nextjs
  • #markdown
  • #blog