포트폴리오 웹사이트 기획부터 배포까지
디자인개발기획
2024. 08 - 2024. 09

포트폴리오 웹사이트 기획부터 배포까지

템플릿 없이 기획·디자인·프론트엔드 개발·CMS 연동·배포 전 과정을 직접 수행함. Next.js SSR + Sanity Headless CMS + Portable Text 기반 콘텐츠 모듈화로 수식·코드·표 등 다양한 포맷을 하나의 구조로써 표현.

Portable Text 컴포넌트

6종

코드·수식·표·이미지·헤더·인용구 커스텀 구현

콘텐츠 수정

실시간

코드 변경·재배포 없이 CMS 직접 수정

Next.jsTypeScriptTailwind CSSSanityFigmaAdobe PhotoshopAdobe Illustrator
서비스 기획·IA 설계UI/UX 디자인프론트엔드 개발CMS 구조 설계배포 자동화

Overview

템플릿에 의존하지 않고 원하는 데이터 구조와 표현 방식을 직접 설계. 이 포트폴리오 사이트 자체가 사용한 기술 스택의 동작 증명임.

Portable Text 모듈화

수식·코드·표·이미지 등 6종 커스텀 컴포넌트로 어떤 포맷도 하나의 구조에서 표현 가능

Headless CMS 구조

Sanity Embedded Studio — 코드 수정 없이, SaaS를 통해 실시간 콘텐츠 관리·수정

Next.js SSR

App Router로 로딩 속도 향상, 이미지 Lazy Loading

GROQ 쿼리 설계

페이지 단위 필요 데이터만 선택적 호출 → 이미지 URL·메타데이터 쿼리 단계에서 주입

디자인 시스템

폰트 스케일, 커스텀 컬러 토큰, 브레이크포인트 직접 설계

Problem

템플릿의 한계: 원하는 구조를 표현할 수 없다
템플릿 기반 포트폴리오의 한계
비교항목템플릿 기반직접 개발
데이터 구조고정 필드직접 설계
콘텐츠 포맷제한적수식/코드/표 자유로움
디자인 자유도낮음높음(100%)
유지보수서비스에 종속직접 관리
포트폴리오를 노션·벨로그·템플릿 기반 서비스로 만드는 것은 처음부터 배제했음. 프로젝트마다 강조 포인트가 다르고, 수식·코드 블록 같은 학습 자료도 표현해야 했기 때문.
  • 고정 필드 구조가 표현의 다양성을 제한함
  • 필드 기반 CMS → 프로젝트마다 다른 포맷을 하나의 틀에 강제
  • 직접 만들기로 결정 → 데이터 구조·렌더링 방식 모두 직접 설계 필요
일정 없는 개인 프로젝트 = 완성되지 않는 제품
개인 프로젝트라고 기획 없이 개발부터 시작하면, 우선순위가 흔들리고 작업 범위가 계속 늘어나기 쉬움을 경험을 통해 알고있음.
  • 완료 기준과 일정 구조 부재

Solution

콘텐츠 구조 → Portable Text로 모듈화
프로젝트마다 포맷이 달라도 하나의 시스템으로 표현하는 구조가 필요.
  • Sanity Portable Text 도입 → 콘텐츠를 JSON 배열로 저장, 컴포넌트 단위 조합
  • 커스텀 컴포넌트: PortableHeader / PortableCodebox / PortableMath(KaTeX) / PortableTable / PortableImage 등 직접 구현
렌더링 구조 → Next.js SSR + Headless CMS
콘텐츠와 코드 분리, 초기 로딩 속도, GROQ를 동시에 해결.
  • SPA → Next.js SSR
  • Firebase → Sanity CMS: 코드 수정 없이 실시간 콘텐츠 관리
  • GROQ 쿼리: 페이지 단위로 필요 데이터만 선택적 호출
일정 수립
기획 단계에서 요구사항 정의서·IA 구조도·일정표를 작성했다.
  • 기능/비기능 요구사항 정의 → MVP 범위 확정
  • 단계별 마일스톤 설정
본문 이미지
본문 이미지

Implementation

Sanity CMS + GROQ 쿼리 구조
  • coalesce 활용 → 빈 필드 안전 처리
  • 이미지 URL·메타데이터 GROQ 단계에서 직접 주입 → 프론트 enrichment 최소화
디자인 시스템
  • 타이포그래피: Pretendard 폰트, clamp() 기반 9단계 반응형 폰트 스케일
  • 컬러 토큰: primary·neutral·emerald·lemon 등 커스텀 팔레트 정의
  • 브레이크포인트: xs(480px) / md(890px) / xxl(1550px) 커스텀 설정
  • 로고: 'ㅅㅈ' 초성 기반 이모티콘형 로고 직접 제작
Portable Text 커스텀 컴포넌트
  1. PortableHeader: h1 렌더링
  2. PortableSubheader: h2 렌더링
  3. PortableCodebox: 코드 블록, dynamic import (SSR 비활성화)
  4. PortableMath: 수식 (KaTeX)
  5. PortableTable: 표 (행·열·혼합 헤더 3종)
  6. PortableImage: 이미지

Problem Solving

코드 블록 SSR hydration 오류
  • 문제: PortableCodebox 렌더 시 서버·클라이언트 마크업 불일치로 hydration 경고 반복
  • 원인: next-sanityPortableText는 서버에서도 실행되는데, 코드 하이라이터가 브라우저 전용 API에 의존
  • 해결: dynamic(() => import('./portable-codebox-inner'), { ssr: false }) → 클라이언트 전용 로드, 로딩 중 <pre> 플레이스홀더 표시
  • 결과: hydration 오류 제거, SSR 성능 유지
  • 인사이트: CMS 렌더러 안에서 브라우저 의존 컴포넌트는 반드시 ssr: false 처리해야 한다
Sanity Embedded Studio 라우트 충돌
  • 문제: /studio 경로에 Sanity Studio를 임베드했으나, Next.js App Router의 [[...tool]] catch-all과 충돌해 특정 Studio 페이지에서 404 발생
  • 원인: App Router의 동적 라우트 우선순위와 Sanity Studio 내부 라우팅이 동일 경로를 두고 경합
  • 해결: client-studio.tsx'use client' 분리, <NextStudio> 컴포넌트를 클라이언트 전용으로 격리
  • 결과: Studio 전 페이지 정상 접근, 콘텐츠 실시간 수정 가능
  • 인사이트: Next.js에 외부 SPA를 임베드할 때는 App Router 라우트 해석 순서를 먼저 검토해야 한다

Insight

확장 가능한 구조
  • 프로젝트마다 다른 포맷을 Portable Text 하나로 수용 → 새 포맷 추가 시 컴포넌트만 등록하면 됨
  • 데이터 스키마 설계가 먼저 → 화면은 그 결과
개인 프로젝트도 기획 문서가 있어야 된다
  • 요구사항 정의서·IA·일정표 작성
  • 이후 꾸준한 백업 과정에서, 문서를 읽고 코드 리딩 시간 단축
이 포트폴리오 자체가 기술 스택의 증명
  • Next.js·TypeScript·Sanity·Tailwind CSS로 만든 웹사이트
  • 포트폴리오의 동작 자체가 그동안의 기술 역량 레퍼런스

Result

Outcomes

  • 요구사항·IA·일정표 사전 작성으로 일정 이탈 없이 완료

  • 수식·코드·표 등 6종 Portable Text 커스텀 컴포넌트 직접 구현 → 프로젝트마다 다른 포맷을 단일 구조로 표현

  • Sanity Embedded Studio 도입 → 코드 변경·재배포 없이 실시간 콘텐츠 수정 가능

  • SSR hydration 오류 제거 → 코드 블록 ssr:false 격리 처리

관련 프로젝트

포트폴리오 웹사이트 기획부터 배포까지 · Portfolio · Sojin Lee