react-pdf(pdf.js)를 Next.js App Router + Turbopack에서 띄울 때, 검색해서 나오는 설정들이
지금도 필요한지 확인하는 최소 예제입니다.
라이브 데모는 없습니다.
npm run build가/에서 실패하는 것이 의도된 재현이라 배포하지 않았습니다. 로컬에서npm run dev로 확인하세요.
next.config.ts는 비어 있습니다. 그리고 그걸로 충분합니다 — 딱 하나만 빼고요.
| 흔한 처방 | 지금도 필요한가 |
|---|---|
swcMinify: false |
❌ 불필요 |
resolve.alias.canvas = false |
❌ 불필요 |
워커를 public/에 복사 |
❌ 불필요 (Turbopack이 번들함) |
next/dynamic + ssr: false |
✅ 지금도 필요 |
Next.js 16.3.6 (Turbopack)
pdfjs-dist 5.4.296
react-pdf 10.x
npm install
npm run dev| 경로 | 무엇 | 예상 |
|---|---|---|
/ |
감싸지 않은 뷰어 | 실패 — 500 · DOMMatrix is not defined |
/ssr-skipped |
ssr:false로 감싼 뷰어 |
성공 — 콘솔 깨끗 |
/가 실패하는 것은 의도된 재현입니다. 고쳐야 할 버그가 아닙니다.
ReferenceError: DOMMatrix is not defined
app/pdf-viewer.tsx (4:1) @ module evaluation
> 4 | import { Document, Page, pdfjs } from 'react-pdf'
.next/dev/server/chunks/ssr/node_modules_...
npm run build 를 돌리면 더 선명합니다.
Warning: Please use the `legacy` build in Node.js environments.
Error occurred prerendering page "/"
ReferenceError: DOMMatrix is not defined
at module evaluation (webpack://pdf.js/src/display/canvas.js:63:22)
> 63 | const SCALE_MATRIX = new DOMMatrix();
Export encountered an error on /page: /, exiting the build.
DOMMatrix는 브라우저 API인데 pdf.js가 모듈 최상단에서 인스턴스를 하나 만들어 둡니다.
함수 안이 아니라 최상단이라 import 되는 순간 실행되고, App Router의 'use client'
컴포넌트도 서버에서 한 번 렌더되므로 여기서 터집니다.
| # | 확인 | 통과 기준 |
|---|---|---|
| 1 | /ssr-skipped 가 뜨는가 |
상태에 ✓ 워커 로드 성공 · 2쪽 |
| 2 | 워커 경로 | /_next/static/media/pdf.worker.min.*.mjs — public/을 안 썼는데도 |
| 3 | Setting up fake worker 경고 |
없어야 정상 |
| 4 | Can't resolve 'canvas' |
없어야 정상 |
| 5 | / 가 500인가 |
DOMMatrix is not defined |
| 6 | npm run build |
/ 에서 실패 (의도됨) |
npm run versions # next / react / react-pdf / pdfjs-dist
npm run dev:webpack # webpack 과 비교pdfjs.GlobalWorkerOptions.workerSrc = new URL(
'pdfjs-dist/build/pdf.worker.min.mjs',
import.meta.url,
).toString()public/에 복사하지 않습니다. 복사하면pdfjs-dist를 올릴 때 워커만 옛 버전으로 남아API version … does not match Worker version …로 터집니다.- CDN 주소를 쓰지 않습니다. 사내망·오프라인에서 죽고 버전 고정도 사람이 해야 합니다.
- 컴포넌트를 쓰는 같은 모듈에서 설정합니다. react-pdf README가 명시하는 조건입니다.
app/
page.tsx / 감싸지 않음 — 실패 재현
ssr-skipped/page.tsx /ssr-skipped ssr:false — 정상 동작
pdf-viewer.tsx 'use client' + workerSrc를 같은 모듈에서 설정
icon.png
public/sample.pdf 2쪽짜리 최소 PDF (외부 의존 없이 생성)
next.config.ts 비어 있음
검색하면 여전히 상단에 나옵니다. 읽을 때 날짜를 보세요.
- vercel/next.js #64165 · #64657
- wojtekmaj/react-pdf #1856 · discussion #1688
이 저장소는 에이전트(Claude)와 같이 만들었어요. 어떤 문제를 다룰지와 어디까지 공개할지는 제가 정했고, 코드는 에이전트가 쓰고 제가 읽고 검토했어요. 글에 쓴 숫자는 모두 이 코드로 실제로 돌려 본 값이고, 틀린 곳이 있다면 책임은 저에게 있어요.
MIT