플랫폼별 통합
JavaScript
프레임워크 없이 <script> 태그만으로 통합하는 기준 예제입니다.
모든 플랫폼 가이드는 이 패턴의 변형이므로, 다른 스택을 쓰더라도 이 페이지를 먼저 보면 전체 흐름이 잡힙니다.
공통 전제
뷰어 산출물이 서버 /pdfv/ 경로에 배포되어 있어야 합니다 — 시작하기 참고.
전체 페이지 예제
contract-view.html html
<!DOCTYPE html>
<html lang="ko">
<head>
<meta charset="UTF-8" />
<title>계약서 검토</title>
<style>
#pdf-container { width: 100%; height: 80vh; }
*{}</style>
</head>
<body>
<button id="my-save-btn">검토 완료 저장</button>
<div id="pdf-container"></div>
<!-- 컨테이너보다 아래에 두면 DOMContentLoaded 대기가 필요 없습니다 -->
<script src="/pdfv/sdk/pdfv-sdk.js"></script>
<script>
var viewer = Inko.mount('#pdf-container', {
src: '/pdfv/index.html',
pdfUrl: '/files/contract.pdf',
fileName: 'contract.pdf',
// LATEST_CANVAS는 예시용 이름 — 서버가 페이지에 심어 주는 직전 저장본 (없으면 undefined)
initialCanvasData: window.LATEST_CANVAS || undefined,
onSave: function (canvasData, ok, msg) {
if (!ok) { alert('저장 실패: ' + msg); return; }
fetch('/api/annotations', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ docId: 123, canvasData: canvasData })
}).then(function (res) {
if (res.ok) alert('저장되었습니다.');
});
},
onError: function (err) { console.error('[Inko]', err); }
});
// 페이지 자체 버튼에서 저장 트리거
document.getElementById('my-save-btn').onclick = function () {
viewer.save();
};
</script>
</body>
</html>- SDK 스크립트를 컨테이너 요소보다 아래에 두면 별도의 로드 대기 코드가 필요 없습니다.
<head>에서 로드해야 한다면mount()호출을DOMContentLoaded이후로 미루세요.- 컨테이너에 명시적 높이가 반드시 필요합니다 (높이 0이면 화면에 아무것도 보이지 않습니다).
문서함 패턴 — 마운트 한 번, 문서 교체
목록에서 문서를 오가는 화면이라면 페이지 이동 대신 loadPdfUrl()로 교체하는 것이 효율적입니다.
문서 교체 js
// 문서함 목록에서 클릭할 때마다 같은 뷰어에 문서 교체
var viewer = Inko.mount('#pdf-container', { src: '/pdfv/index.html' });
document.querySelectorAll('.doc-row').forEach(function (row) {
row.addEventListener('click', function () {
fetch('/api/documents/' + row.dataset.id)
.then(function (r) { return r.json(); })
.then(function (doc) {
viewer.loadPdfUrl(doc.url, doc.name, doc.latestCanvasData);
});
});
});주의사항
- 전역 이름 —
Inko와PdfViewer둘 다 등록됩니다. 기존 코드와 이름이 충돌하면 다른 쪽을 사용하세요. - 타이밍 — 뷰어 준비 전에 호출한 명령은 SDK가 큐에 보관했다가 준비 직후 실행하므로 가드 코드가 필요 없습니다.
- 저장 응답 —
viewer.save()의 결과는 반환값이 아니라onSave콜백으로 옵니다. 콜백을 마운트 옵션에 등록해 두세요.