플랫폼별 통합

Vue · Nuxt

Vue에서는 onMounted에서 마운트하고 onBeforeUnmount에서 정리합니다. SDK는 전역 <script>로 로드되므로 window.Inko로 접근합니다.

공통 전제

뷰어 산출물이 /pdfv/ 경로에 배포되어 있어야 합니다 — 시작하기 참고. Vite 개발 서버에서는 server.proxy/pdfv를 운영 서버에 연결하세요. SDK 로드는 index.html<script src="/pdfv/sdk/pdfv-sdk.js"> 한 줄이면 됩니다.

Composition API (Vue 3)

PdfEditor.vue vue
<template>
  <div ref="container" style="width:100%; height:80vh"></div>
</template>

<script setup>
import { ref, onMounted, onBeforeUnmount } from 'vue';

const props = defineProps({
  docId: Number,
  pdfUrl: String,
  initialCanvasData: String,
});

const container = ref(null);
let viewer = null;

onMounted(() => {
  viewer = window.Inko.mount(container.value, {
    src: '/pdfv/index.html',
    pdfUrl: props.pdfUrl,
    initialCanvasData: props.initialCanvasData,
    onSave(canvasData, ok) {
      if (!ok) return;
      fetch('/api/annotations', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({ docId: props.docId, canvasData }),
      });
    },
  });
});

// 라우트 이동·언마운트 시 정리 — iframe·리스너 제거
onBeforeUnmount(() => viewer?.destroy());
</script>

Options API

기존 Options API 코드베이스라면 라이프사이클 훅만 다릅니다.

PdfEditor.vue (Options API) vue
<!-- Options API를 쓰는 기존 Vue 2/3 코드베이스 -->
<script>
export default {
  props: ['docId', 'pdfUrl', 'initialCanvasData'],
  mounted() {
    this.viewer = window.Inko.mount(this.$refs.container, {
      src: '/pdfv/index.html',
      pdfUrl: this.pdfUrl,
      initialCanvasData: this.initialCanvasData,
      onSave: (canvasData, ok) => {
        if (!ok) return;
        this.$emit('saved', canvasData);
      },
    });
  },
  beforeUnmount() {        // Vue 2는 beforeDestroy()
    this.viewer?.destroy();
  },
};
</script>

<template>
  <div ref="container" style="width:100%; height:80vh"></div>
</template>

Nuxt

Nuxt는 SSR(서버에서 HTML을 미리 그려 보내는 단계)에 window가 없으므로 <ClientOnly>로 감싸거나 .client.vue 접미사 컴포넌트로 만들어 클라이언트에서만 렌더되게 합니다.

Nuxt 3 구성 vue
<!-- Nuxt 3 — SDK 로드(nuxt.config.ts) -->
export default defineNuxtConfig({
  app: {
    head: {
      script: [{ src: '/pdfv/sdk/pdfv-sdk.js', defer: true }],
    },
  },
});

<!-- 페이지에서 — 클라이언트 전용으로 감싸기 -->
<template>
  <ClientOnly>
    <PdfEditor :doc-id="123" pdf-url="/files/contract.pdf" />
  </ClientOnly>
</template>

주의사항

  • destroy() 필수 — 언마운트 정리를 생략하면 라우트를 오갈 때마다 iframe·리스너가 누적됩니다.
  • viewer는 반응형 상태가 아닙니다ref()에 넣지 말고 일반 변수에 보관하세요 (불필요한 반응성 추적 방지).
  • 문서 교체 — 재마운트 대신 viewer.loadPdfUrl(url, name, canvasData)로 같은 인스턴스에서 문서를 바꿀 수 있습니다 — PDF 불러오기 참고.