birchholt 직접 해보고 남기는 기록

글 목록을 여섯 편씩 끊었습니다 — 틀려도 조용한 것들

커밋된 글이 일곱 편이 되면서 목록 페이지가 길어졌습니다. 여섯 편씩 끊기로 했습니다. 설정 한 줄과 템플릿 몇 줄로 끝날 일로 봤는데, 걸린 것들이 대체로 오류를 안 냈습니다. 2026-09-03 작업입니다.

옛 키는 무시되는 게 아니라 기본값 10 으로 떨어집니다

최상위에 paginate = 6 을 적었습니다. 지금 문법은 [pagination].pagerSize 입니다. 제가 옛 문법을 그대로 적은 것입니다. 설정 키가 조용히 넘어가는 것 자체는 Hugo 로 갈아엎을 때 겪었고, 다른 것은 넘어간 다음이었습니다.

설정 블록만 옛 키로 바꾸고 hugo --buildFuture 로 빌드했습니다. 미발행분까지 포함한 11편 기준입니다(커밋된 것만 세면 일곱 편입니다).

확인한 것[pagination].pagerSize = 6최상위 paginate = 6
/posts/ 1페이지의 글 카드6개10개
/posts/page/2/생깁니다생깁니다
빌드 출력의 경고0줄입니다

옛 키는 무시되고 끝나는 게 아니라 pagerSize 를 내장 기본값 10 으로 떨어뜨립니다. 그래서 글이 열 편에 못 미치는 동안에는 페이징을 넣은 티가 안 납니다. 목록은 한 페이지에 다 나오고, 열한 편째에야 2페이지가 생깁니다.

canonical 이 페이저를 모릅니다

2페이지가 생긴 뒤 산출물을 열어봤습니다. 그때는 홈도 페이징하고 있어서 /page/2/ 가 있었는데, 1페이지와 똑같은 두 줄이 박혀 있었습니다.

<title>birchholt — 직접 해보고 남기는 기록</title>
<link rel="canonical" href="https://birchholt.com/">

2페이지가 스스로를 1페이지의 복제라고 선언하고 있었습니다. .Permalink 가 페이저와 무관하게 그 Page 자신의 주소를 돌려주기 때문입니다. 페이저 주소는 Pager 의 .URL 뿐입니다.

{{- $canon := .Permalink -}}
{{- with .Store.Get "pager" -}}
  {{- if gt .PageNumber 1 -}}
    {{- $canon = .URL | absURL -}}
    {{- $title = printf "%s (%d페이지)" $title .PageNumber -}}
  {{- end -}}
{{- end -}}

고친 뒤에는 rel=canonical href=https://birchholt.com/page/2/ 와 제목 끝의 「(2페이지)」 가 나옵니다(--minify 라 따옴표가 없습니다). 색인이 실제로 어떻게 잡히는지는 아직 확인하지 못했습니다 — 등록하고 몇 주는 지나야 압니다.

「빌드가 죽는다」고 적어둔 자리 — 안 죽습니다

위 코드가 .Store.Get 으로 읽는 이유가 여기 있습니다. head 는 main 블록보다 먼저 렌더되니, head 에서 .Paginator 를 부르면 그 시점에 기본 인자로 페이저가 만들어집니다. 뒤이어 main 이 다른 인자로 .Paginate 를 부르면 어떻게 되는지를 저는 주석과 커밋 본문(09c9789)에 「빌드가 죽는다」고 적어뒀습니다. 인용까지 붙여놨습니다 — invoked multiple times with different arguments.

그 문자열을 찾아봤는데 지금 쓰는 바이너리에 한 줄도 없었습니다.

$ strings $(which hugo) | grep -cE 'invoked multiple times|different arguments'
0

v0.165.0 의 실제 페이저 오류 문자열은 invalid paginator state for %q 입니다. 그래서 재현했습니다. 복사본에서 baseof 의 페이저 생성을 지우고 head.html.Paginator 를 먼저 부르게 한 뒤, section.html 에서 .Paginate (first 3 .Pages) 2 로 다른 인자를 줬습니다.

WARN  HEAD paginator pages=6 totalpages=2
/posts/ 카드 수: 6

WARN 은 확인하려고 넣은 줄입니다. 빌드는 통과하고 먼저 만들어진 head 쪽 페이저가 이깁니다. main 이 준 인자는 오류도 경고도 없이 버려지고 목록 개수만 달라집니다. 설계는 손댈 데가 없고 제가 적어둔 근거만 틀렸습니다.

{{- /* baseof.html — head 보다 위에서 한 번만 만든다 */ -}}
{{- if and (eq .Kind "section") (eq .Section "posts") -}}
  {{- .Store.Set "pager" (.Paginate .Pages) -}}
{{- end -}}

이유가 「죽으니까」가 아니라 「조용히 어긋나니까」였을 뿐입니다. 주석과 커밋 본문은 e242680 에서 고쳤습니다.

홈을 페이징하지 않기로 했습니다

홈과 /posts/ 를 둘 다 끊었다가 산출물을 보고 되돌렸습니다.

확인한 것홈까지 페이징했을 때
/page/2/ 의 내용인트로 산문과 「두 개의 기록」 섹션이 통째로 반복됩니다
같은 글 목록의 주소/page/2//posts/page/2/ — 두 벌이 됩니다

canonical 을 고쳐놨으니 색인이 접히지는 않지만, 읽는 사람에게 2페이지가 홈의 재방송이 됩니다. 홈은 최신 6편과 「글 전체 보기」 링크로 바꿨습니다.

그 대가로 6 이 두 곳에 남았습니다

해결 못 한 채로 둔 것. hugo.tomlpagerSize = 6home.html$limit := 6 이 따로 적혀 있습니다. 한쪽만 고치면 경계가 어긋납니다.

한쪽에서 읽어올 수가 없습니다. home.htmlsite.Config.Pagination.PagerSize 를 넣으면 can't evaluate field Pagination in type page.SiteConfig 로 죽습니다 — Hugo 는 pagerSize 를 템플릿에 노출하지 않습니다. 같은 값을 두 군데 적지 않는 방법은 배포를 자동화할 때 찾아뒀는데 여기서는 안 됐고, 두 파일 주석에 서로를 가리키는 경고를 박아두는 데 그쳤습니다. 주석은 강제가 아니라 부탁입니다.

나머지는 짧게 적습니다

생략()은 pagerSize 를 1 로 낮춰 9페이지로 확인했습니다.

page 1: ← 이전 1 2 3 … 9 다음 →
page 9: ← 이전 1 … 7 8 9 다음 →

정리