대표 이미지 (feature image)

ghost-toc-plugin 미리보기

왼쪽 패널에서 옵션을 바꿔보세요. 목차가 실시간으로 다시 그려지고, 임베드 코드도 함께 갱신됩니다. 스크롤하면 현재 섹션이 강조됩니다.

들어가며

ghost-toc-plugin은 코드 한 줄로 Ghost 블로그에 떠다니는 목차를 더하는 가볍고(약 3KB) 의존성 없는 위젯입니다. Ghost 전용으로 시작했지만, Notion 기반 블로그에서도 동작하며 스크립트를 넣을 수 있는 곳이면 어디서나 동작합니다. 글의 헤딩을 읽어 목차를 자동으로 만들고, 스크롤을 따라다니며 지금 읽는 섹션을 강조합니다. 이 페이지가 바로 그 예시로, 옆에 보이는 목차가 실제로 동작하는 위젯입니다.

설치 방법

빌드 과정도, 테마 파일 수정도 없이 아래 스니펫 한 번이면 설치가 끝납니다:

<link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/GreedyLabs/ghost-toc-plugin@1/toc.css">
<script src="https://cdn.jsdelivr.net/gh/GreedyLabs/ghost-toc-plugin@1/toc.min.js"
        data-content=".gh-content"
        data-headings="h2,h3"
        data-title="목차"></script>

코드 인젝션

Ghost에서는 Settings → Code injection → Site Footer 에 붙여넣습니다. Notion 기반 호스팅이라면 커스텀 코드 주입란에 넣습니다. oopy는 사이트 설정의 head/footer 코드란, super.so는 Custom Code 영역이며, 이때 data-content.notion-page-content로 지정하세요. 그 밖의 사이트라면 닫는 </body> 태그 바로 앞에 두면 됩니다. async나 defer 없이 두어야 자신의 data-* 옵션을 읽을 수 있습니다.

옵션 설정

동작은 모두 스크립트 태그의 data-* 속성으로 설정합니다: 본문 선택자, 포함할 헤딩, 제목, 위치 등을 지정할 수 있습니다:

data-content=".gh-content"
data-headings="h2,h3"
data-position="right"
data-min-width="1200"
data-top="100"

커스터마이즈

색과 위치는 자유롭게 조절할 수 있습니다. 모든 클래스와 CSS 변수는 greedylabs-ghost-toc로 네임스페이스가 걸려 있어 테마와 절대 충돌하지 않습니다.

색상

현재 항목 색은 기본적으로 Ghost 테마 강조색(--ghost-accent-color)을 따릅니다. 바꾸려면 data-accent를 주거나 CSS 변수를 덮어쓰면 됩니다. 위젯은 라이트·다크 기본값을 모두 갖춰 시스템 테마에 자동으로 맞춰집니다. 다크 모드 가독성을 더 높이고 싶다면 다크에만 적용되도록 색을 따로 지정하세요, 값 하나로 고정하면 라이트에서 어색해집니다:

@media (prefers-color-scheme: dark) {
  .greedylabs-ghost-toc {
    --greedylabs-ghost-toc-muted: #c9d1d9;
    --greedylabs-ghost-toc-border: rgba(255,255,255,.22);
  }
}

위치

data-position으로 좌·우를, data-top으로 상단 여백을, data-gap으로 본문과의 간격을, data-width로 패널 너비를 정합니다. 화면이 data-min-width보다 좁거나 옆에 공간이 없으면 목차는 스스로 숨습니다.

자주 묻는 질문

목차 위젯이 사이트를 느리게 하나요?

거의 그렇지 않습니다. 약 3KB에 의존성이나 외부 요청이 없고, 스크롤은 passive 리스너로 받아 requestAnimationFrame으로 프레임당 한 번만 계산합니다. 지연 로딩 이미지나 giscus 같은 위젯으로 문서 높이가 바뀔 때만 ResizeObserver로 다시 계산합니다.

목차가 안 보이는데 왜 그럴까요?

세 가지를 확인하세요. data-content 선택자가 실제 본문 컨테이너와 맞는지, 헤딩이 2개 이상인지(그 미만이면 목차를 만들지 않습니다), 화면이 data-min-width(기본 1200px)보다 넓고 본문 옆에 패널이 들어갈 공간이 있는지. 좁은 화면과 모바일에서는 의도적으로 숨습니다.

h4처럼 더 깊은 헤딩도 목차에 넣을 수 있나요?

네. data-headings에 원하는 태그를 쉼표로 나열하면 됩니다(예: h2,h3,h4). 목록에 포함할 헤딩 레벨을 자유롭게 정할 수 있습니다.

마치며

ghost-toc-plugin은 MIT 라이선스 오픈소스이며, 소스와 이슈는 GitHub에 있습니다. 왼쪽 패널에서 옵션을 바꿔 실시간으로 확인한 뒤 마음에 들면 임베드 코드를 복사하세요. 도움이 되었다면 커피 한 잔 부탁드려요 ☕.