Use Case: Share-Link Viewer
Permission-gated read-only viewer for anonymous visitors (share-link / public-link patterns).
When a document is shared via a public link, you typically want the recipient to be able to read but not edit — no annotation, no thread replies, no download. The permissions prop combined with the features flags lets you build this without forking the component.
Pattern
<script setup lang="ts">
import { DocumentViewer } from '@meldui/vue'
import type { ViewerPermissions } from '@meldui/vue'
const isAnonymousVisitor = !currentUser
const permissions: ViewerPermissions = {
canAnnotate: !isAnonymousVisitor,
canResolveThreads: !isAnonymousVisitor,
canDownload: false,
canPrint: false,
canSaveAsCopy: false,
}
</script>
<template>
<DocumentViewer
source="/shared-doc.pdf"
wasm-url="/pdfium.wasm"
:features="{
zoom: true,
search: true,
outline: true,
thumbnails: true,
annotations: true,
commentThreads: true,
}"
:permissions="permissions"
/>
</template>
features vs. permissions
featuresdecides whether the plugin is registered (bundle impact). Disabled features are tree-shaken.permissionsdecides whether the UI for an already-registered feature is visible to the current user (no bundle impact, runtime-only).
For a share-link viewer, you typically want all the features registered (so a logged-in user clicking the same link gets full functionality) but the UI gated by permissions for anonymous visitors.
Pre-seeded read-only review
A common share-link pattern: an editor publishes a reviewed document and shares a link. The recipient sees the highlights and threaded comments but can’t add their own.
<script setup lang="ts">
import { onMounted } from 'vue'
onMounted(async () => {
const { annotations, threads } = await fetch(`/shared/${shareToken}`).then((r) => r.json())
await viewer.value?.loadAnnotations(annotations)
viewer.value?.loadThreads(threads)
})
</script>
<template>
<DocumentViewer
ref="viewer"
:source="docUrl"
wasm-url="/pdfium.wasm"
:features="{ annotations: true, commentThreads: true, zoom: true }"
:permissions="{ canAnnotate: false, canResolveThreads: false }"
/>
</template>
Embedding in another page
For embedding the viewer in a 3rd-party page (iframe, embedded widget), set a fixed size and disable everything except viewing:
<DocumentViewer
:source="docUrl"
wasm-url="/pdfium.wasm"
:features="{ zoom: true, search: true }"
:permissions="{
canAnnotate: false,
canResolveThreads: false,
canDownload: false,
canPrint: false,
canSaveAsCopy: false,
}"
class="h-[600px] w-full"
/>
Hiding the toolbar entirely
For a fully chrome-free embed, pass an empty groups array via toolbar:
const toolbar: ToolbarConfig = {
groups: [],
}
The viewport renders without any toolbar. Users still get keyboard shortcuts if features.keyboardShortcuts is on.
See also
- Customization → Permissions
- Features — flag table