import { Kernstra, PDFDocument, PDFViewer } from '@kernstra/pdf-web-sdk';// 1. Once per page load. Checks your key and loads the engine.await Kernstra.init({ license: import.meta.env.KERNSTRA_LICENSE,});// 2. Open a document. Nothing about it leaves the browser.const doc = await PDFDocument.fromUrl('/reports/q3-board-pack.pdf');// 3. Give it an element with a height. Options are optional:// here, the ribbon toolbar instead of the default bar.const container = document.getElementById('viewer');new PDFViewer(container, doc, { toolbar: { layout: 'ribbon' },});
import { Kernstra, PDFDocument, PDFViewer } from '@kernstra/pdf-web-sdk';// 1. Once per page load. Checks your key and loads the engine.await Kernstra.init({ license: import.meta.env.KERNSTRA_LICENSE,});// 2. Open a document. Nothing about it leaves the browser.const doc = await PDFDocument.fromUrl('/reports/q3-board-pack.pdf');// 3. Give it an element with a height. Options are optional:// here, the ribbon toolbar instead of the default bar.const container = document.getElementById('viewer')!;new PDFViewer(container, doc, { toolbar: { layout: 'ribbon' },});
import { useEffect, useRef } from 'react';import { PDFDocument, PDFViewer } from '@kernstra/pdf-web-sdk';import { initKernstra } from '../lib/kernstra';export function DocumentViewer({ url }: { url: string }) { const ref = useRef<HTMLDivElement>(null); useEffect(() => { let canceled = false; let doc: PDFDocument | undefined; let viewer: PDFViewer | undefined; (async () => { await initKernstra(); // safe on every mount const opened = await PDFDocument.fromUrl(url); if (canceled) { await opened.close(); return; } doc = opened; viewer = new PDFViewer(ref.current!, doc, { toolbar: { layout: 'ribbon' }, }); })().catch(console.error); return () => { canceled = true; viewer?.destroy(); void doc?.close(); }; }, [url]); // a new url opens a new document return <div ref={ref} style={{ height: '80vh' }} />;}
<!-- Opens its url once: give it :key="url" to switch documents. --><script setup lang="ts">import { onBeforeUnmount, onMounted, ref } from 'vue';import { PDFDocument, PDFViewer } from '@kernstra/pdf-web-sdk';import { initKernstra } from '../lib/kernstra';const props = defineProps<{ url: string }>();const el = ref<HTMLDivElement>();let doc: PDFDocument | undefined;let viewer: PDFViewer | undefined;let unmounted = false;async function open() { await initKernstra(); const opened = await PDFDocument.fromUrl(props.url); if (unmounted) return opened.close(); doc = opened; viewer = new PDFViewer(el.value!, doc, { toolbar: { layout: 'ribbon' }, });}onMounted(() => { open().catch(console.error); // log a failed load, keep the page});onBeforeUnmount(() => { unmounted = true; viewer?.destroy(); void doc?.close();});</script><template> <div ref="el" style="height: 80vh" /></template>
import { Component, ElementRef, afterRenderEffect, inject, input, viewChild,} from '@angular/core';import { PDFDocument, PDFViewer } from '@kernstra/pdf-web-sdk';import { KernstraService } from './kernstra.service';@Component({ selector: 'app-document-viewer', template: `<div #host style="height: 80vh"></div>`,})export class DocumentViewer { readonly url = input.required<string>(); private readonly host = viewChild.required<ElementRef<HTMLElement>>('host'); private readonly kernstra = inject(KernstraService); constructor() { // Browser only, so server rendering never runs it. Runs again when // url changes; the cleanup runs first, and on destroy. afterRenderEffect((onCleanup) => { const url = this.url(); const host = this.host().nativeElement; let doc: PDFDocument | undefined; let viewer: PDFViewer | undefined; let canceled = false; onCleanup(() => { canceled = true; viewer?.destroy(); void doc?.close(); }); void (async () => { await this.kernstra.init(); const opened = await PDFDocument.fromUrl(url); if (canceled) return opened.close(); doc = opened; viewer = new PDFViewer(host, opened, { toolbar: { layout: 'ribbon' }, }); })(); }); }}
<script lang="ts"> import { onMount } from 'svelte'; import { PDFDocument, PDFViewer } from '@kernstra/pdf-web-sdk'; import { initKernstra } from './kernstra'; // Opens its url once: wrap it in {#key url} to switch documents. let { url }: { url: string } = $props(); let el: HTMLDivElement; onMount(() => { let destroyed = false; let doc: PDFDocument | undefined; let viewer: PDFViewer | undefined; (async () => { await initKernstra(); const opened = await PDFDocument.fromUrl(url); if (destroyed) return opened.close(); doc = opened; viewer = new PDFViewer(el, doc, { toolbar: { layout: 'ribbon' } }); })().catch(console.error); return () => { destroyed = true; viewer?.destroy(); void doc?.close(); }; });</script><div bind:this={el} style="height: 80vh"></div>
'use client';import dynamic from 'next/dynamic';// The React tab's component; its ../lib/kernstra import is// lib/kernstra.ts, which reads process.env.KERNSTRA_LICENSE.// It needs the browser, so it never renders on the server.export const DocumentViewer = dynamic( () => import('@/components/DocumentViewer').then((m) => m.DocumentViewer), { ssr: false, loading: () => <div style={{ height: '80vh' }} /> },);
<!-- The .client suffix keeps it out of server rendering. --><script setup lang="ts">import { onBeforeUnmount, onMounted, ref } from 'vue';import { PDFDocument, PDFViewer } from '@kernstra/pdf-web-sdk';const initKernstra = useKernstra(); // auto-imported composableconst props = defineProps<{ url: string }>();const el = ref<HTMLDivElement>();let doc: PDFDocument | undefined;let viewer: PDFViewer | undefined;let unmounted = false;async function open() { await initKernstra(); const opened = await PDFDocument.fromUrl(props.url); if (unmounted) return opened.close(); doc = opened; viewer = new PDFViewer(el.value!, doc, { toolbar: { layout: 'ribbon' }, });}onMounted(() => { open().catch(console.error); // log a failed load, keep the page});onBeforeUnmount(() => { unmounted = true; viewer?.destroy(); void doc?.close();});</script><template> <div ref="el" style="height: 80vh" /></template>
<script lang="ts"> import { page } from '$app/state'; // SvelteKit 2: '$lib/DocumentViewer.svelte' import DocumentViewer from '#lib/DocumentViewer.svelte';</script><!-- The Svelte tab's two files, unchanged: onMount runs only in the browser. The key mounts a fresh viewer when the id changes. -->{#key page.params.id} <DocumentViewer url={`/api/documents/${page.params.id}`} />{/key}