
Syncfusion Vue Pdf Viewer
- 1 installs
- 1 repo stars
- Updated July 6, 2026
- syncfusion/pdf-viewer-sdk-skills
Generates Vue single-file component (.vue) code to embed and configure the Syncfusion PDF Viewer for loading PDF documents in Vue 2 or Vue 3.
About
Generates Vue SFC code that embeds the Syncfusion ejs-pdfviewer to render and interact with PDFs. A developer uses it when adding a configured PDF viewer to a Vue 2 or Vue 3 application.
- Targets the @syncfusion/ej2-vue-pdfviewer package
- Generates .vue single-file component code
Syncfusion Vue Pdf Viewer by the numbers
- 1 all-time installs (skills.sh)
- Ranked #1,912 of 2,245 Frontend Development skills by installs in the Skillselion catalog
- Data as of Jul 8, 2026 (Skillselion catalog sync)
npx skills add https://github.com/syncfusion/pdf-viewer-sdk-skills --skill syncfusion-vue-pdf-viewerAdd your badge
Show developers this skill is listed on Skillselion. Paste this into your README.
| Installs | 1 |
|---|---|
| repo stars | ★ 1 |
| Last updated | July 6, 2026 |
| Repository | syncfusion/pdf-viewer-sdk-skills ↗ |
What it does
Generates Vue single-file component (.vue) code to embed and configure the Syncfusion PDF Viewer for loading PDF documents in Vue 2 or Vue 3.
Files
Syncfusion Vue Pdfviewer – UI Sample Generator
Target package: @syncfusion/ej2-vue-pdfviewer
Generate Code for the User's Project (default)
Trigger keywords: "how to", "add pdfviewer", "code sample", "show me", "example", "snippet", "integrate", "component", "create sample", "vue sample".
Purpose: Generate minimal, copy-pasteable Vue SFC (.vue) code that the user can integrate directly into their Vue 2 or Vue 3 project.
Workflow: ⚠️ CRITICAL — Feature Support Policy (STRICT MODE):
FUNDAMENTAL RULE: Only generate code using APIs and properties that are EXPLICITLY listed in the reference files. ANY deviation is a VIOLATION.
- MANDATORY CHECKS BEFORE GENERATING ANY CODE:
1. Search the reference files for the exact API/property name 2. Verify it appears in the Method Reference, Properties, or Events tables 3. If NOT found in ANY reference file, STOP immediately 4. Do NOT generate or suggest undocumented APIs under any circumstances
- STRICT ENFORCEMENT - ZERO TOLERANCE:
- NO custom properties - Only use properties from reference file tables
- NO invented methods - Only use methods from reference file tables
- NO workarounds with undefined APIs - Forbidden
- NO assumptions about undocumented behavior - Forbidden
- NO alternative implementations using guess-work - Forbidden
- NO pretending support exists - Forbidden
- MANDATORY RESPONSE FOR UNSUPPORTED FEATURES:
- If a requested scenario/feature/API is NOT listed in any reference file, you MUST respond with:
"This feature is not supported in the current Syncfusion Vue PDF Viewer implementation."- Then list what IS supported from the appropriate reference file
- Never suggest alternatives unless explicitly documented in reference files
- REFERENCE FILE HIERARCHY:
- Each reference file contains complete, authoritative documentation for its domain
- The tables (Method Reference, Properties, Events) are the SOURCE OF TRUTH
- Content outside these tables in reference files is explanatory only
- Do NOT extend beyond what appears in the reference file tables
- AUDIT YOUR GENERATION:
- Before providing any code, verify EVERY API used appears in a reference file table
- Document which reference file each API comes from
- If you cannot cite a reference file table entry, DELETE that code
- This is a CRITICAL REQUIREMENT. Violations compromise the skill's integrity and reliability.
Step 1 — Detect the Application Type (REQUIRED - DO NOT SKIP)
- Use file_search and read_file tools to inspect workspace project files:
package.json(project configuration and dependencies)vite.config.jsorvite.config.ts(Vue 3 Vite build config)vue.config.js(Vue 2 Vue-CLI config)App.vue(root component)main.jsormain.ts(app entry point — check forVue.use(...)for Vue 2 vscreateApp(...)for Vue 3)- Any existing
.vuefiles insrc/folder - Output: Confirm the detected application type is Vue 2 or Vue 3 before proceeding, as the component registration and API patterns differ.
Step 2 — Generate Code from Reference Files Only (REQUIRED)
- Before generating: Confirm that Step 1 is complete
- Read the relevant
references/*.mdfile(s) for the requested feature - Cross-reference EVERY API, property, and method against these tables
- COMPONENT-BASED APPROACH (MANDATORY - VUE PATTERNS ONLY):
- Use Vue SFC (
.vue) syntax with<template>,<script>, and<style>sections - Use
<ejs-pdfviewer>as the component tag - Bind all PDF Viewer properties using Vue's
:prop="value"binding syntax - Vue 2: Register component via
components: { "ejs-pdfviewer": PdfViewerComponent }and inject services viaprovide: { PdfViewer: [...] } - Vue 3 Composition API: Import
PdfViewerComponent as EjsPdfviewerand useprovide('PdfViewer', [...])fromvue - Vue 3 Options API: Use
components+provideoptions just like Vue 2 but withcreateAppentry - Use
ref/$refs(Vue 2) orref()+ templaterefattribute (Vue 3) for programmatic viewer access - MANDATORY: Before generating ANY code, verify that reference files exist and are accessible
- Read the appropriate reference file(s) for the requested feature:
- Use
read_filetool on relevantreferences/*.mdfiles - Confirm file contains Methods/Properties/Events tables
- Verify tables are complete and readable
- If reference file is missing or cannot be read:
- STOP code generation
- Respond: "Reference file for this feature is not available. Please ensure all reference files are present in the
references/directory." - List the missing reference file name
- This is a BLOCKER step: Cannot proceed without reference file validation
- If an API/property does NOT appear in the reference file table, DO NOT USE IT
- Do NOT invent, guess, or suggest any API, method, property, class, or namespace not explicitly present in the reference files
---
Reference File Routing
All templates and operation snippets live in references/*.md. Each file is a focused snippet or template the agent will combine when generating samples.
Flow: Always start with getting-started.md, then merge matched features into its anchors (PROPS, EVENTS, UI_BUTTONS, HANDLERS). If no keyword matches, return only the basic sample.
Checklist Before Generating Code
- [ ] Detected Vue version? Vue 2 → use
data()+provide:{}| Vue 3 → useref()/reactive()+provide() - [ ] Count the settings properties: 1-3? → Use inline binding | 4+? → Use data constant
- [ ] Are enums involved? Yes → Import required enums | No → Skip enum imports
- [ ] Is it reused elsewhere? Yes → Use data/ref constant | No → Prefer inline
- [ ] Is the component prop simple enough? Yes → Keep inline | No → Extract to data/ref
🎯 Core Setup & Configuration
| File | Purpose | Route When User Asks About |
|---|---|---|
| getting-started.md | Minimal PDFViewer with documentPath, height, and width. Base template for all samples. | "basic setup", "minimal example", "getting started", "how to load PDF" |
| general-properties.md | Configure core viewer properties (server URL, document path, locale, resource base path). | "configuration", "server settings", "locale", "document path setup" |
| enable-properties.md | Enable/disable specific features (toolbar, annotations, forms, navigation, text selection, download, print). | "disable toolbar", "hide features", "enable/disable", "read-only mode", "restrict features" |
📐 Navigation & Page Management
| File | Purpose | Route When User Asks About |
|---|---|---|
| page-navigation.md | Navigate between pages (first, last, next, previous page), go to specific page numbers. | "page navigation", "go to page", "next page", "previous page", "jump to page" |
| bookmark-navigation.md | Navigate using PDF bookmarks/table of contents in the bookmark panel. *CRITICAL: All bookmark methods MUST be accessed via `this.$refs.pdfViewer.bookmark. (Vue 2) or pdfViewerRef.value.bookmark.` (Vue 3 Composition API), NOT directly on the viewer instance.* | "bookmarks", "bookmark", "table of contents", "TOC navigation", "outline panel", "get bookmarks", "retrieve bookmarks", "fetch bookmarks", "bookmarks programmatically", "getBookmarks", "goToBookmark", "bookmark API", "list bookmarks", "open bookmark", "close bookmark" |
| hyperlink-navigation.md | Configure hyperlink navigation behavior and external link handling in PDFs. | "hyperlinks", "external links", "URL navigation", "clickable links", "url", "link" |
| thumbnail-navigation.md | Display and navigate using page thumbnails in the thumbnail panel. | "thumbnails", "preview pages", "thumbnail panel", "thumbnail", "page previews" |
🔍 Viewing & Interaction
| File | Purpose | Route When User Asks About |
|---|---|---|
| magnification.md | Configure zoom levels, zoom modes, and magnification controls (fit-to-page, fit-to-width). | "zoom", "magnification", "fit to page", "zoom levels", "scale document" |
| interaction-mode.md | Switch between Selection mode (text selection) and Panning mode (touch scrolling). | "text selection", "panning", "scroll mode", "interaction mode", "touch navigation" |
| text-selection.md | Enable text selection, copying text, and text selection events. | "select text", "copy text", "highlight text to copy", "text selection mode" |
| text-search.md | Implement text search functionality with search options and navigation. | "search text", "find in PDF", "search functionality", "highlight search results" |
🛠️ Toolbar & Context Menu
Toolbar Configuration
| File | Purpose | Route When User Asks About |
|---|---|---|
| toolbar-settings.md | Configure toolbar visibility, tooltip behavior, and customize/remove toolbar items. | "customize toolbar", "hide toolbar items", "remove toolbar buttons", "toolbar configuration" |
| toolbar-methods.md | Programmatically show/hide toolbars and enable/disable toolbar items at runtime. | "show/hide toolbar dynamically", "toggle toolbar", "enable/disable toolbar items programmatically" |
⚠️ STRICT VALIDATION FOR TOOLBAR ITEM NAMES
When generating toolbar configurations, you MUST follow these rules to prevent incorrect toolbar item names:
1. ALWAYS reference exact item names from `toolbar-settings.md`
- Do NOT invent, guess, or assume toolbar item names
- Do NOT apply naming pattern logic to derive names
- Use ONLY names listed in the "Available Primary Toolbar Items", "Available Annotation Toolbar Items", and "Available Form Designer Items" sections in
toolbar-settings.md
2. VALIDATE item names character-by-character
- Case sensitivity matters:
HighlightTool≠HighlightOption - Exact names only:
AnnotationEditTool≠AnotatetionEditTool - No abbreviations or shortcuts
3. Before generating toolbar configuration code:
- [ ] Open
toolbar-settings.mdreference file - [ ] Locate: "Available Primary Toolbar Items" section
- [ ] Locate: "Available Annotation Toolbar Items" section
- [ ] Locate: "Available Form Designer Items" section
- [ ] Copy exact names from THESE SECTIONS ONLY
- [ ] Cross-check every single item name character-by-character
- [ ] If ANY item name is not in the reference sections, DO NOT USE IT
- [ ] Consult the "❌ COMMON MISTAKES TO AVOID" table in
toolbar-settings.mdif unsure
4. Common errors to prevent:
- ❌
AnotatetionEditTool→ ✅AnnotationEditTool(typo) - ❌
CalibrationOption→ ✅CalibrateTool(wrong suffix) - ❌
ShapeAnnotationOption→ ✅ShapeTool(annotation toolbar version) - ❌
InkAnnotationOption→ ✅InkAnnotationTool(annotation toolbar version) - For complete list of mistakes to avoid, see
toolbar-settings.md"❌ COMMON MISTAKES TO AVOID" table
Context Menu Customization
| File | Purpose | Route When User Asks About |
|---|---|---|
| contextmenu.md | Customize context menu items and handle context menu events. | "right-click menu", "context menu", "custom context menu", "disable context menu items" |
📝 Annotations
| File | Purpose | Route When User Asks About |
|---|---|---|
| annotation-settings.md | Configure annotation appearance (colors, opacity, styles) and behavior for all annotation types. | "annotation colors", "annotation styles", "customize annotation appearance", "annotation defaults" |
| annotation-events.md | Handle annotation lifecycle events (add, delete, move, resize, select, property change). | "annotation events", "when annotation is added", "annotation change detection", "annotation callbacks" |
| shape-label-settings.md | Customize shape and measure annotation labels (position, color, font, visibility). | "annotation labels", "shape labels", "measurement labels", "label customization" |
| redaction-annotation.md | Create, configure, and apply redaction annotations to permanently remove sensitive content. | "redaction", "redact content", "remove sensitive data", "black out text", "permanent removal" |
📄 Forms
| File | Purpose | Route When User Asks About |
|---|---|---|
| form-field-settings.md | Configure default properties for form fields (text, checkbox, radio, dropdown, signature). | "form field defaults", "form field styles", "configure form fields", "form field properties" |
| form-field-events.md | Handle form field interaction events (focus, blur, value change, validation). | "form field events", "when field changes", "form validation events", "field interaction callbacks" |
📋 Document Actions
| File | Purpose | Route When User Asks About |
|---|---|---|
| download.md | Enable/configure PDF download functionality with custom filenames. | "download PDF", "save PDF", "export document", "download button" |
| print.md | Configure and trigger PDF printing functionality. | "print PDF", "print document", "printing options", "print button" |
| organize-pages.md | Reorder, rotate, insert, remove, copy, import, and extract PDF pages. | "reorder pages", "rotate pages", "add blank pages", "remove pages", "rearrange pages", "merge PDFs" |
⚙️ Advanced Features
| File | Purpose | Route When User Asks About |
|---|---|---|
| api-methods.md | Programmatic control: load documents, manage forms, annotations, extract text, undo/redo, navigation APIs. | "load PDF programmatically", "API methods", "export form data", "extract text", "undo/redo", "programmatic control" |
| events.md | Complete list of all PDFViewer events (document load, download, annotations, forms, search, navigation). | "event list", "all events", "available events", "event reference", "event handlers" |
Quick Start Example
<template>
<ejs-pdfviewer
ref="pdfViewer"
:resourceUrl="resourceUrl"
:documentPath="documentPath"
style="height: 640px">
</ejs-pdfviewer>
</template>
<script setup>
import { provide } from 'vue';
import { PdfViewerComponent as EjsPdfviewer, Toolbar, Magnification, Navigation, LinkAnnotation,
BookmarkView, ThumbnailView, Print, TextSelection, TextSearch,
Annotation, FormDesigner, FormFields } from '@syncfusion/ej2-vue-pdfviewer';
const resourceUrl = window.location.origin + "/asset/ej2-pdfviewer-lib";
const documentPath = 'https://cdn.syncfusion.com/content/pdf/pdf-succinctly.pdf';
provide('PdfViewer', [ Toolbar, Magnification, Navigation, LinkAnnotation, BookmarkView, ThumbnailView,
Print, TextSelection, TextSearch, Annotation, FormDesigner, FormFields ]);
</script>
<style>
/* Refer to the CSS Configuration section for the full import list */
@import '../node_modules/@syncfusion/ej2-pdfviewer/styles/material.css';
</style>⚙️ SETTINGS CONFIGURATION BEST PRACTICES
When generating code with settings (toolbarSettings, annotationSettings, annotationSelectorSettings, arrowSettings, rectangleSettings, etc.), follow these guidelines to prevent unnecessary complexity:
Rule 1: Simple Settings → Define INLINE in Component Binding
Use this approach when:
- Configuring only 1-3 properties
- Settings are straightforward without complex enums or custom types
- No need for separate data constants
Example (DO THIS):
<template>
<ejs-pdfviewer
id="container"
documentPath="https://cdn.syncfusion.com/content/pdf/pdf-succinctly.pdf"
:annotationSelectorSettings="{
selectionBorderColor: '#0000ff',
selectionBorderThickness: 2,
resizerBorderColor: '#ff0000',
}"
style="height: 640px"
/>
</template>Benefits:
- ✅ No extra data properties needed
- ✅ Simple and readable
- ✅ Less code clutter
---
Rule 2: Complex Settings → Define in data() / ref() (OUTSIDE template)
Use this approach when:
- Configuring 4+ properties OR multiple related settings
- Using enums or complex configurations
- Need to reuse the same configuration across multiple components
Example — Vue 2 Options API (DO THIS ONLY FOR COMPLEX CASES):
<template>
<ejs-pdfviewer
id="container"
:documentPath="documentPath"
:annotationSelectorSettings="annotationSelectorConfig"
style="height: 640px"
/>
</template>
<script>
import { PdfViewerComponent, Annotation,
AnnotationResizerLocation, CursorType } from '@syncfusion/ej2-vue-pdfviewer';
export default {
name: 'App',
components: { 'ejs-pdfviewer': PdfViewerComponent },
data() {
return {
documentPath: 'https://cdn.syncfusion.com/content/pdf/pdf-succinctly.pdf',
annotationSelectorConfig: {
selectionBorderColor: '#0000ff',
selectionBorderThickness: 2,
resizerBorderColor: '#ff0000',
resizerFillColor: '#4070ff',
resizerSize: 8,
resizerShape: 'Square',
selectorLineDashArray: [5, 6],
resizerLocation: AnnotationResizerLocation.Corners | AnnotationResizerLocation.Edges,
resizerCursorType: CursorType.grab,
},
};
},
provide: { PdfViewer: [Annotation] },
};
</script>Example — Vue 3 Composition API (DO THIS ONLY FOR COMPLEX CASES):
<script setup>
import { provide } from 'vue';
import { PdfViewerComponent as EjsPdfviewer, Annotation,
AnnotationResizerLocation, CursorType } from '@syncfusion/ej2-vue-pdfviewer';
const documentPath = 'https://cdn.syncfusion.com/content/pdf/pdf-succinctly.pdf';
const annotationSelectorConfig = {
selectionBorderColor: '#0000ff',
selectionBorderThickness: 2,
resizerBorderColor: '#ff0000',
resizerFillColor: '#4070ff',
resizerSize: 8,
resizerShape: 'Square',
selectorLineDashArray: [5, 6],
resizerLocation: AnnotationResizerLocation.Corners | AnnotationResizerLocation.Edges,
resizerCursorType: CursorType.grab,
};
provide('PdfViewer', [Annotation]);
</script>When to import enums:
- [ ] Import any enums that are used in the settings (e.g.,
AnnotationResizerLocation,CursorType) - [ ] Keep imports minimal — import ONLY what is used in the settings
Benefits:
- ✅ Proper enum usage
- ✅ Reusable across multiple components
- ✅ Clean template code
---
Rule 3: NEVER Over-Engineer Simple Cases
❌ DO NOT DO THIS (Over-engineered):
<script>
import { PdfViewerComponent } from '@syncfusion/ej2-vue-pdfviewer';
export default {
components: { 'ejs-pdfviewer': PdfViewerComponent },
data() {
return {
// Unnecessary data property for 1 simple prop
toolbarSettings: { showTooltip: true },
};
},
};
</script>✅ DO THIS INSTEAD (Simple & Clean):
<ejs-pdfviewer :toolbarSettings="{ showTooltip: true }" ... />---
Syncfusion Vue PDF Viewer — Skill
Overview
The syncfusion-vue-pdf-viewer skill enables AI-assisted code generation for the Syncfusion Vue PDF Viewer (`PdfViewerComponent`). It produces minimal, copy-pasteable Vue SFC snippets to embed, configure, and interact with PDF documents inside Vue applications.
---
Compatibility
| Requirement | Version |
|---|---|
| Vue | >= 3.2.0 |
| Node.js | >= 14.0.0 |
| Package Manager | NPM |
| Framework | Vue 3 (TypeScript or JavaScript) |
---
Skill Structure
syncfusion-vue-pdf-viewer/
├── SKILL.md # Skill rules, routing, and code generation guidelines
├── README.md # This file
└── references/
├── getting-sample.md # Minimal setup & initialization template
├── general-properties.md # Core viewer properties (documentPath, height, locale, etc.)
├── enable-properties.md # Feature toggle properties (enableToolbar, enableAnnotation, etc.)
├── toolbar-settings.md # Toolbar visibility and item customization
├── toolbar-methods.md # Programmatic toolbar show/hide at runtime
├── contextmenu.md # Right-click context menu customization
├── page-navigation.md # Navigate between pages programmatically
├── bookmark-navigation.md # Bookmark panel and navigation
├── thumbnail-navigation.md # Thumbnail panel and page previews
├── hyperlink-navigation.md # Hyperlink and external link behavior
├── magnification.md # Zoom levels, zoom modes, fit-to-page/width
├── interaction-mode.md # Selection mode vs. panning mode
├── text-selection.md # Enable text select, copy, and selection events
├── text-search.md # Find text in PDF with search options
├── annotation-settings.md # Annotation appearance (colors, opacity, styles)
├── annotation-events.md # Annotation lifecycle events (add, delete, resize, etc.)
├── shape-label-settings.md # Shape/measure annotation label customization
├── redaction-annotation.md # Redaction: create, configure, and apply
├── form-field-settings.md # Form field default properties
├── form-field-events.md # Form field interaction events (focus, blur, change)
├── download.md # PDF download configuration
├── print.md # PDF print configuration
├── organize-pages.md # Reorder, rotate, insert, remove, merge pages
├── api-methods.md # Programmatic API (load, export, undo/redo, extract text)
└── events.md # Complete PDF Viewer event reference---
Quick Start
1. Create a Vue Project
# TypeScript
npm create vite@latest my-app -- --template vue-ts
cd my-app
# JavaScript
npm create vite@latest my-app -- --template vue
cd my-app2. Install the Package
npm install @syncfusion/ej2-vue-pdfviewer --save3. Copy WebAssembly Resources
cp -R ./node_modules/@syncfusion/ej2-pdfviewer/dist/ej2-pdfviewer-lib public/ej2-pdfviewer-lib4. Add CSS Imports (src/style.css)
@import '../node_modules/@syncfusion/ej2-base/styles/material.css';
@import '../node_modules/@syncfusion/ej2-buttons/styles/material.css';
@import '../node_modules/@syncfusion/ej2-dropdowns/styles/material.css';
@import '../node_modules/@syncfusion/ej2-inputs/styles/material.css';
@import '../node_modules/@syncfusion/ej2-navigations/styles/material.css';
@import '../node_modules/@syncfusion/ej2-popups/styles/material.css';
@import '../node_modules/@syncfusion/ej2-splitbuttons/styles/material.css';
@import '../node_modules/@syncfusion/ej2-pdfviewer/styles/material.css';5. Basic Component (src/App.vue)
<template>
<ejs-pdfviewer
id="container"
:documentPath="documentPath"
:resourceUrl="resourceUrl"
style="height: 640px"
></ejs-pdfviewer>
</template>
<script lang="ts">
import { defineComponent } from 'vue';
import {
PdfViewerComponent, Toolbar, Magnification, Navigation,
LinkAnnotation, BookmarkView, ThumbnailView, Print,
TextSelection, Annotation, TextSearch, FormFields, FormDesigner
} from '@syncfusion/ej2-vue-pdfviewer';
export default defineComponent({
name: 'App',
components: {
'ejs-pdfviewer': PdfViewerComponent
},
data() {
return {
documentPath: 'https://cdn.syncfusion.com/content/pdf/pdf-succinctly.pdf',
resourceUrl: 'https://cdn.syncfusion.com/ej2/31.2.2/dist/ej2-pdfviewer-lib'
};
},
provide: {
PdfViewer: [
Toolbar, Magnification, Navigation, Annotation, LinkAnnotation,
BookmarkView, ThumbnailView, Print, TextSelection, TextSearch,
FormFields, FormDesigner
]
}
});
</script>6. Run the App
npm run dev---
Available Services
Inject only the services your use-case requires to keep the bundle lean.
| Service | Purpose |
|---|---|
Toolbar | Main toolbar with document controls |
Magnification | Zoom and magnification |
Navigation | Page navigation controls |
Annotation | All annotation capabilities |
LinkAnnotation | Clickable hyperlinks in PDFs |
BookmarkView | Bookmark/outline panel |
ThumbnailView | Page thumbnail panel |
Print | Print functionality |
TextSelection | Select and copy text |
TextSearch | Find text in document |
FormFields | Interactive form field support |
FormDesigner | Create and edit form fields |
---
Reference File Routing
Use the table below to find the correct reference file for any feature request.
Core Setup
| Reference File | Use When … |
|---|---|
getting-started.md | Getting started, minimal setup, loading a PDF |
general-properties.md | Configuring server URL, locale, width/height, resourceUrl |
enable-properties.md | Enabling/disabling toolbar, annotations, forms, download, print |
Navigation
| Reference File | Use When … |
|---|---|
page-navigation.md | Go to first/last/next/previous page or a specific page number |
bookmark-navigation.md | Navigate via bookmarks or open/close bookmark panel |
thumbnail-navigation.md | Display or navigate with the thumbnail panel |
hyperlink-navigation.md | Configure clickable hyperlinks and external URL behavior |
Viewing & Interaction
| Reference File | Use When … |
|---|---|
magnification.md | Zoom controls, fit-to-page, fit-to-width, zoom levels |
interaction-mode.md | Switch between text-selection and panning modes |
text-selection.md | Enable/handle text selection and copy events |
text-search.md | Implement in-document text search and result highlighting |
Toolbar & Context Menu
| Reference File | Use When … |
|---|---|
toolbar-settings.md | Customize toolbar items, visibility, and tooltip behavior |
toolbar-methods.md | Show/hide toolbars programmatically at runtime |
contextmenu.md | Add, remove, or handle right-click context menu items |
Annotations
| Reference File | Use When … |
|---|---|
annotation-settings.md | Set default annotation colors, opacity, author, styles |
annotation-events.md | Handle annotation add/delete/move/resize/select events |
shape-label-settings.md | Customize labels on shape and measure annotations |
redaction-annotation.md | Create and apply redactions to remove sensitive content |
Forms
| Reference File | Use When … |
|---|---|
form-field-settings.md | Configure default properties for text, checkbox, radio, dropdown, signature fields |
form-field-events.md | Handle form field focus, blur, and value-change events |
Document Actions
| Reference File | Use When … |
|---|---|
download.md | Enable download and set custom filenames |
print.md | Configure and trigger printing |
organize-pages.md | Reorder, rotate, insert, remove, or merge pages |
Advanced / API
| Reference File | Use When … |
|---|---|
api-methods.md | Load documents programmatically, export form data, undo/redo, extract text |
events.md | Browse all available PDF Viewer events and their signatures |
---
Metadata
| Field | Value |
|---|---|
| Skill Name | syncfusion-vue-pdf-viewer |
| Author | Syncfusion Inc |
| Version | 1.0.0 |
| Reference Files | 25 |
Annotation Events
Description: Annotation events for the Syncfusion PDF Viewer (Vue) notify your app when annotations are created, changed, moved, resized, selected, or removed. Use these hooks to implement logging, validation, custom UI updates, or backend synchronization.
Table of Contents
- When to use
- Picking the right event
- Using events in Vue
- Events reference (complete list)
- Annotation object summary
- Common usage patterns
---
When to use
- Track user edits and build audit trails.
- Run business validation before allowing annotations.
- Update custom property panes, toolbars, or lists when selection changes.
- Sync annotation changes to a server or shared session.
Picking the right event
- Need to stop an action? Use a "before" event that supports cancellation (see
beforeAddFreeText). - Want the final state after a user finishes an action? Use the lifecycle events (e.g.,
annotationAdd,annotationMove,annotationRemove). - Need real-time feedback while dragging/resizing? Use the in-progress events like
annotationMoving.
---
Using events in Vue
Example: register handlers on the PDF Viewer component using Vue event listeners.
<template>
<ejs-pdfviewer
@annotationAdd="handleAnnotationAdd"
@annotationSelect="handleAnnotationSelect"
@annotationMove="handleAnnotationMove"
/>
</template>
<script setup>
import { ref } from 'vue'
const handleAnnotationAdd = (args) => { console.log('annotation added', args) }
const handleAnnotationSelect = (args) => { console.log('selected', args) }
const handleAnnotationMove = (args) => { console.log('moved', args) }
</script>Use the handler args to access annotationId, pageIndex, and the full annotation object when provided.
---
Events reference (Vue)
The following events are supported. Each entry lists when it fires and the useful properties available on the event args object.
annotationAdd— Fires after an annotation is added. Args:annotationId,pageIndex,annotation,annotationAddMode.annotationDoubleClick— Fires on double-clicking an annotation. Args:annotationId,pageIndex,annotation.annotationMouseLeave— Mouse left an annotation. Args:annotationId,pageIndex.annotationMouseover— Mouse entered an annotation. Args:annotationId,pageIndex,X,Y.annotationMove— Fires after an annotation move completes. Args:annotationId,pageIndex,annotation(updated).annotationMoving— Fires continuously while an annotation moves. Args:annotationId,pageIndex,currentPosition.annotationPropertiesChange— Annotation property changes. Args includeannotationId,pageIndex, boolean flags such asisColorChanged,isThicknessChanged,isOpacityChanged, plusannotation.annotationRemove— Fires when an annotation is removed. Args:annotationId,pageIndex,annotation(removed object).annotationResize— Fires after resize completes. Args:annotationId,pageIndex,annotation(with new bounds).annotationSelect— Fires when annotation(s) are selected. Args:annotationId,pageIndex,annotation,annotationCollection,isMultiSelect.annotationUnSelect— Fires when an annotation is unselected. Args:annotationId,pageIndex.beforeAddFreeText— Fires before a free-text annotation is created; supports cancellation viaargs.cancel = true. Args:pageIndex,cancel.addSignature— Fired when a signature is added. Args:pageIndex,signature(object).removeSignature— Fired when a signature is deleted. Args:pageIndex,signature.resizeSignature— Fires after signature resize. Args:pageIndex,signature,previousPosition,currentPosition.signaturePropertiesChange— Signature property changes. Args:pageIndex,isThicknessChanged,isOpacityChanged,isStrokeColorChanged,signature.signatureSelect— Signature selected. Args:pageIndex,signature.signatureUnselect— Signature unselected. Args:pageIndex,signature.
Ensure your Vue handlers inspect the args object to determine the annotation type and the properties that are present.
---
Annotation object summary
When handlers expose an annotation object, it contains both general and type-specific properties. Not every property appears on every annotation type — check type/subType first.
Core properties you can expect (commonly available):
annotationId/id/randomId— identifiers.author,creationDate,modifiedDate.pageNumber/pageIndex.type,subType,shapeAnnotationType.- Visual properties:
color,strokeColor,fillColor,opacity,thickness,isLocked,isPrint. - Geometry:
bounds(x,y,width,height,left,top,right),rect(left,top,right,bottom,height,width),vertexPointsfor polygons. annotationAddMode,customData,comments,review.
Type-specific highlights
- Text markup (
type: "TextMarkup"):textMarkupContent,textMarkupStartIndex,textMarkupEndIndex. - FreeText:
content,dynamicText,fontFamily,textAlign,fontobject. - Ink:
data(path/SVG data). - Shape/Measure:
caption,captionPosition,labelContent,labelBounds,calibrate. - Stamp:
icon,customStampName,isDynamicStamp,stampAnnotationPath.
Nested objects you will commonly access
- Rect:
{ left, top, right, bottom, width, height }. - Bounds:
{ x, y, left, top, right, width, height }. - Review:
{ state, stateModel, author, modifiedDate }. - AnnotationSettings:
{ isLock, isPrint, maxHeight, maxWidth, minHeight, minWidth }. - AnnotationSelectorSettings: selection handle and border styling.
- LabelSettings: label
borderColor,fillColor,fontColor,fontSize,opacity.
---
Common usage patterns (Vue examples)
1) Audit logging on add/move/remove
const onAnnotationAdd = (args) => {
sendTelemetry('annotation.add', { id: args.annotationId, page: args.pageIndex, time: new Date().toISOString() })
}
const onAnnotationMove = (args) => {
sendTelemetry('annotation.move', { id: args.annotationId, page: args.pageIndex })
}
const onAnnotationRemove = (args) => {
sendTelemetry('annotation.remove', { id: args.annotationId, page: args.pageIndex })
}2) Preventing free-text on certain pages
const onBeforeAddFreeText = (args) => {
if (args.pageIndex === 0) { // e.g., cover page
args.cancel = true
// show message to user
}
}3) Properties panel for the selected annotation
const onAnnotationSelect = (args) => {
const ann = args.annotation
// populate UI with ann.color, ann.opacity, ann.bounds, etc.
}4) Bulk operations when multiple annotations are selected
const onAnnotationSelect = (args) => {
if (args.isMultiSelect) {
args.annotationCollection.forEach(a => applyBulkChange(a.annotationId))
}
}---
Tips
- Always check the
typebefore reading type-specific fields. - For validations that must stop an action, prefer
before*events (onlybeforeAddFreeTextsupports cancellation today). - Use
annotationPropertiesChangeto react to fine-grained property edits — it includes boolean flags to indicate what changed.
Annotation Settings in Vue PdfViewer Component
Description: Configure PDF annotation settings to control appearance, behavior, and interaction of text markup, shape, and stamp annotations in the ejs-pdfviewer component. Customize colors, styles, author details, and access restrictions.
Table of Contents
- Overview
- Quick Start
- Global vs Type-Specific Settings
- Annotation Types Available
- Settings Properties Reference
- Annotation-Related Component Properties
- Core Annotation Settings Props
- Common Use Cases
- Selector Customization
- Type Definitions
Important: Bounds Format for Annotations (Lowercase)
⚠️ When adding annotations programmatically, ALWAYS use lowercase property names in the bounds object:
<!-- CORRECT ✅ - Use LOWERCASE bounds -->
<script setup>
const pdfViewer = ref(null);
pdfViewer.value.ej2Instances.annotation.addAnnotation('Rectangle', {
bounds: { x: 100, y: 100, width: 200, height: 50 },
color: '#FF0000'
});
</script>
<!-- INCORRECT ❌ - Do NOT use capitalized letters -->
<script setup>
pdfViewer.value.ej2Instances.annotation.addAnnotation('Rectangle', {
bounds: { X: 100, Y: 100, Width: 200, Height: 50 }, // WRONG for annotations
color: '#FF0000'
});
</script>---
Overview
Configure annotation settings immediately to control how PDF annotations display and behave in your viewer. Choose between applying settings globally to all annotation types or customizing individual annotation behaviors through type-specific properties like :highlightSettings, :areaSettings, :stampSettings, etc.
When to use: Whenever you need to customize annotation appearance (colors, size, opacity), control user interactions (lock state, allowed actions), set author details, or restrict features (disable downloads/printing).
Quick Start
Apply Settings to Specific Annotation Type
Customize appearance and behavior for individual annotation types by binding type-specific props:
Vue 3 – Composition API
<template>
<ejs-pdfviewer id="pdfViewer" :documentPath="documentPath"
:highlightSettings="highlightSettings" style="height:640px" />
</template>
<script setup>
import { provide } from 'vue';
import { PdfViewerComponent as EjsPdfviewer, Toolbar, Annotation, TextSelection }
from '@syncfusion/ej2-vue-pdfviewer';
const documentPath = 'https://cdn.syncfusion.com/content/pdf/pdf-succinctly.pdf';
const highlightSettings = { color: 'green', opacity: 0.6, author: 'John Doe', isLock: false };
provide('PdfViewer', [Toolbar, Annotation, TextSelection]);
</script>Vue 3 – Options API
<template>
<ejs-pdfviewer id="pdfViewer" :documentPath="documentPath"
:highlightSettings="highlightSettings" style="height:640px" />
</template>
<script>
import { PdfViewerComponent, Toolbar, Annotation, TextSelection }
from '@syncfusion/ej2-vue-pdfviewer';
export default {
components: { 'ejs-pdfviewer': PdfViewerComponent },
data() {
return {
documentPath: 'https://cdn.syncfusion.com/content/pdf/pdf-succinctly.pdf',
highlightSettings: { color: 'green', opacity: 0.6, author: 'John Doe', isLock: false }
};
},
provide: { PdfViewer: [Toolbar, Annotation, TextSelection] }
}
</script>Vue 2
<template>
<ejs-pdfviewer id="pdfViewer" :documentPath="documentPath"
:highlightSettings="highlightSettings" />
</template>
<script>
import Vue from 'vue';
import { PdfViewerPlugin, Toolbar, Annotation, TextSelection }
from '@syncfusion/ej2-vue-pdfviewer';
Vue.use(PdfViewerPlugin);
export default {
data() {
return {
documentPath: 'https://cdn.syncfusion.com/content/pdf/pdf-succinctly.pdf',
highlightSettings: { color: 'green', opacity: 0.6, author: 'John Doe', isLock: false }
};
},
provide: { PdfViewer: [Toolbar, Annotation, TextSelection] }
}
</script>Use this when: You need to control how a specific annotation type (highlight, underline, stamp, etc.) appears and behaves across your PDF.
Apply Global Settings to All Annotations
<template>
<ejs-pdfviewer id="pdfViewer" :documentPath="documentPath"
:annotationSettings="annotationSettings" style="height:640px" />
</template>
<script setup>
import { provide } from 'vue';
import { PdfViewerComponent as EjsPdfviewer, Toolbar, Annotation }
from '@syncfusion/ej2-vue-pdfviewer';
const documentPath = 'https://cdn.syncfusion.com/content/pdf/pdf-succinctly.pdf';
const annotationSettings = { author: 'PDF Author', opacity: 0.7, isLock: false };
provide('PdfViewer', [Toolbar, Annotation]);
</script>Use this when: You need a uniform author name, opacity, or lock state applied to every annotation type.
---
Global vs Type-Specific Settings
Global Settings (:annotationSettings):
- Applied to all annotation types unless overridden
- Best for company-wide policies (author name, lock state, download restrictions)
- Properties:
author,subject,customData,isLock,isPrint,skipDownload,skipPrint,maxWidth,maxHeight,minWidth,minHeight,opacity,allowedInteractions
Type-Specific Settings:
- Override global settings for individual annotation behaviors
- Best for controlling how each annotation type looks and acts
- Examples:
:highlightSettings,:areaSettings,:stampSettings,:freeTextSettings - Each type has unique properties (e.g.,
highlightSettingshasenableMultiPageAnnotation,enableTextMarkupResizer)
Decision Guide:
- Set author globally →
:annotationSettings - Customize highlight color only →
:highlightSettings - Lock all annotations →
:annotationSettings - Different colors per type → multiple type-specific props
---
Annotation Types Available
| Annotation Type | Prop Name | Use When |
|---|---|---|
| Area | areaSettings | User needs to draw enclosed area measurements |
| Arrow | arrowSettings | User needs to draw directional arrows or connectors |
| Circle | circleSettings | User needs to mark circular regions |
| Distance | distanceSettings | User needs to measure distance between points |
| FreeText | freeTextSettings | User needs to add text boxes with custom styling |
| HandWrittenSignature | handwrittenSignatureSettings | User needs to add handwritten signatures |
| Highlight | highlightSettings | User needs to highlight text (most common) |
| Ink | inkAnnotationSettings | User needs freehand drawing or handwriting |
| Line | lineSettings | User needs to draw lines with arrow styles |
| Perimeter | perimeterSettings | User needs to measure perimeter of shapes |
| Polygon | polygonSettings | User needs to draw multi-sided shapes |
| Radius | radiusSettings | User needs to measure radius or diameter |
| Rectangle | rectangleSettings | User needs to mark rectangular regions |
| Squiggly | squigglySettings | User needs wavy line text markup |
| Stamp | stampSettings | User needs predefined stamps (Approved, Confidential, etc.) |
| StickyNotes | stickyNotesSettings | User needs comment notes on PDF |
| Strikethrough | strikethroughSettings | User needs strikethrough text markup |
| Underline | underlineSettings | User needs underline text markup |
| Volume | volumeSettings | User needs to calculate volume of 3D objects |
---
Settings Properties Reference
Annotation-Related Component Properties
These properties are available directly on the ejs-pdfviewer component to control annotation-related functionality:
| Property Name | Description | Type | Default Value |
|---|---|---|---|
| annotation | Get the annotation object of the PDF Viewer. | Annotation | null |
| annotationCollection | Get the annotation collection of the PDF Viewer. | AnnotationCollection | null |
| annotationDrawingOptions | Configure annotation drawing options. | AnnotationDrawingOptions | null |
| dateTimeFormat | Customize the date and time format for dynamic stamps and annotations. | string | "MM/dd/yyyy" |
| exportAnnotationFileName | Set the filename when exporting annotations. | string | "annotations" |
| handWrittenSignatureSettings | Configure handwritten signature settings. | HandWrittenSignatureSettings | null |
| isAnnotationToolbarVisible | Show or hide the annotation toolbar. | boolean | true |
| isSignatureEditable | Allow or prevent editing of signatures after creation. | boolean | true |
| isValidFreeText | Validate free text before rendering. | boolean | true |
| showDigitalSignatureAppearance | Show or hide digital signature appearance dialog. | boolean | true |
| signatureCollection | Get the collection of digital signatures in the PDF. | SignatureCollection | null |
| signatureDialogSettings | Configure signature dialog settings. | SignatureDialogSettings | null |
| signatureFitMode | Set how signatures fit in the signature field. | SignatureFitMode | Default |
Core Annotation Settings Props
| Prop | Type | Applicable To |
|---|---|---|
annotationSettings | AnnotationSettings | All annotations |
areaSettings | AreaSettings | Area |
arrowSettings | ArrowSettings | Arrow |
circleSettings | CircleSettings | Circle |
distanceSettings | DistanceSettings | Distance |
freeTextSettings | FreeTextSettings | FreeText |
handwrittenSignatureSettings | HandWrittenSignatureSettings | HandWrittenSignature |
highlightSettings | HighlightSettings | Highlight |
inkAnnotationSettings | InkAnnotationSettings | Ink |
lineSettings | LineSettings | Line |
measurementSettings | MeasurementSettings | Distance, Perimeter, Area, Radius, Volume |
perimeterSettings | PerimeterSettings | Perimeter |
polygonSettings | PolygonSettings | Polygon |
radiusSettings | RadiusSettings | Radius |
rectangleSettings | RectangleSettings | Rectangle |
squigglySettings | SquigglySettings | Squiggly |
stampSettings | StampSettings | Stamp |
stickyNotesSettings | StickyNotesSettings | StickyNotes |
strikethroughSettings | StrikethroughSettings | Strikethrough |
underlineSettings | UnderlineSettings | Underline |
volumeSettings | VolumeSettings | Volume |
---
Common Use Cases
Use Case 1: Apply Company Branding to All Annotations
const annotationSettings = {
author: 'Acme Corporation', subject: 'Document Review',
customData: { department: 'Legal', version: '1.0' }
};
// Bind: :annotationSettings="annotationSettings"Use Case 2: Make Annotations Non-Editable After Creation
const annotationSettings = { isLock: true, allowedInteractions: [] };Use Case 3: Customize Highlight and Underline Appearance
const highlightSettings = { color: '#00FF00', opacity: 0.5 };
const underlineSettings = { color: '#0000FF', opacity: 0.4 };
// Bind: :highlightSettings="highlightSettings" :underlineSettings="underlineSettings"Use Case 4: Restrict Annotation Download/Print
const annotationSettings = { skipDownload: true, skipPrint: true };Use Case 5: Customize Resize Handles
const annotationSelectorSettings = {
resizerBorderColor: '#FF0000', resizerFillColor: '#FFE0E0',
resizerSize: 8, resizerShape: 'Circle'
};
// Bind: :annotationSelectorSettings="annotationSelectorSettings"---
Selector Customization
Global – applies to all annotations:
<ejs-pdfviewer :annotationSelectorSettings="{ resizerBorderColor: 'green' }" />Apply Selection Styling to Specific Annotation Type
Customize resize handles for individual annotation types:
<ejs-pdfviewer :areaSettings="{ annotationSelectorSettings: { resizerBorderColor: 'green' } }" />---
Type Definitions
AnnotationSettings / All Annotation Type Settings Properties
| Property | Description | Type | Applicable To |
|---|---|---|---|
allowedInteractions | Allowed interactions for locked annotations | AllowedInteraction[] | AnnotationSettings, all types |
annotationSelectorSettings | Selector settings for the annotation | AnnotationSelectorSettings | Area, Arrow, Circle, Distance, FreeText, HandwrittenSignature, Ink, Line, Perimeter, Polygon, Radius, Rectangle, Stamp, Volume |
author | Author name. Default: "Guest" | string | AnnotationSettings, all types |
borderColor | Border color for FreeText. Default: "#ffffff00" | string | FreeTextSettings |
borderDashArray | Border dash array | number[] | Area, Arrow, Circle, Distance, HandwrittenSignature, Ink, Line, Perimeter, Polygon, Radius, Rectangle, Stamp, Volume |
borderStyle | Border style for FreeText. Default: "solid" | string | FreeTextSettings |
borderWidth | Border width for FreeText. Default: 1 | number | FreeTextSettings |
color | Color for text markup annotations | string | Highlight, Squiggly, Strikethrough, Underline |
conversionUnit | Unit for measuring annotation. Default: "in" | CalibrationUnit | MeasurementSettings |
customData | User-defined information. Default: null | object | AnnotationSettings, all types |
customStamps | Collection of custom stamps | CustomStampSettings[] | StampSettings |
dateTimeFormat | Date/time format for dynamic stamps | string | StampSettings |
defaultText | Default text for FreeText. Default: "Type Here" | string | FreeTextSettings |
depth | Depth value. Default: 96 | number | MeasurementSettings |
displayUnit | Display unit for measuring. Default: "in" | CalibrationUnit | MeasurementSettings |
dynamicStamps | Dynamic stamp items for toolbar menu | DynamicStampItem[] | StampSettings |
enableAutoFit | Auto fit for FreeText. Default: false | boolean | FreeTextSettings |
enableCustomStamp | Allow custom stamp addition. Default: true | boolean | StampSettings |
enableMultiPageAnnotation | Allow text markup across multiple pages. Default: false | boolean | Highlight, Squiggly, Strikethrough, Underline |
enableTextMarkupResizer | Enable resizer for text markup. Default: false | boolean | Highlight, Squiggly, Strikethrough, Underline |
fillColor | Fill color of the annotation | string | Area, Arrow, Circle, Distance, FreeText, HandwrittenSignature, Ink, Line, Perimeter, Polygon, Radius, Rectangle, Stamp, Volume |
fontColor | Font color for FreeText. Default: "#000" | string | FreeTextSettings |
fontFamily | Font family for FreeText. Default: "Helvetica" | string | FreeTextSettings |
fontSize | Font size for FreeText. Default: 16 | number | FreeTextSettings |
fontStyle | Font style for FreeText. Default: None | FontStyle | FreeTextSettings |
height | Height of the annotation | number | FreeText, HandwrittenSignature, Ink, Stamp |
isAddToMenu | Add custom stamp to menu items. Default: false | boolean | StampSettings |
isLock | Lock annotation from interaction. Default: false | boolean | AnnotationSettings, all types |
isPrint | Include annotation in print actions | boolean | AnnotationSettings, all types |
leaderLength | Leader length. Default: 40 | number | DistanceSettings |
lineHeadEndStyle | Head end style of line annotation | LineHeadStyle | Area, Arrow, Distance, Line |
lineHeadStartStyle | Head start style of line annotation | LineHeadStyle | Area, Arrow, Distance, Line |
maxHeight | Maximum height. Default: 0 | number | AnnotationSettings, all types |
maxWidth | Maximum width. Default: 0 | number | AnnotationSettings, all types |
minHeight | Minimum height. Default: 0 | number | AnnotationSettings, all types |
minWidth | Minimum width. Default: 0 | number | AnnotationSettings, all types |
opacity | Opacity (0–1). Default: 1 | number | AnnotationSettings, all types |
scaleRatio | Scale ratio for measuring. Default: 1 | number | MeasurementSettings |
signStamps | Sign stamp items for toolbar menu | SignStampItem[] | StampSettings |
skipDownload | Exclude from downloaded file. Default: false | boolean | AnnotationSettings, all types |
skipPrint | Exclude from printing. Default: false | boolean | AnnotationSettings, all types |
standardBusinessStamps | Standard business stamp items for toolbar menu | StandardBusinessStampItem[] | StampSettings |
strokeColor | Stroke color of shape annotations | string | Area, Arrow, Circle, Distance, HandwrittenSignature, Ink, Line, Perimeter, Polygon, Radius, Rectangle, Stamp, Volume |
subject | Subject of the annotation | string | AnnotationSettings, all types |
textAlignment | Text alignment for FreeText. Default: Left | TextAlignment | FreeTextSettings |
thickness | Thickness of shape annotations (1–10). Default: 1 | number | Area, Arrow, Circle, Distance, HandwrittenSignature, Ink, Line, Perimeter, Polygon, Radius, Rectangle, Stamp, Volume |
width | Width of the annotation | number | FreeText, HandwrittenSignature, Ink, Stamp |
AnnotationSelectorSettings
| Property Name | Description | Data Type |
|---|---|---|
| resizerBorderColor | Defines the annotation resizer border color. By default it is black. | string |
| resizerCursorType | Defines the annotation resizer Type. By default it is null. | CursorType |
| resizerFillColor | Defines the annotation resizer fill color. | string |
| resizerLocation | Defines the location for the resizer of the annotation. It is used to customize the resizer location of the annotation. | AnnotationResizerLocation |
| resizerShape | Defines the shape of the resizer. By default it is Square. Different shapes of resizer are circle and square. | AnnotationResizerShape |
| resizerSize | Defines the size of the resizer used for annotations. | number |
| selectionBorderColor | Defines the selection border color for the annotation. By default it is empty. It is used to customize the selection border color for the annotation. | string |
| selectionBorderThickness | Defines the selection border thickness for the annotation. By default it is 1. It is used to customize the selection border thickness for the annotation. It's range varies from 1 to 10. | number |
| selectorLineDashArray | Defines the selector line dash array. By default it is empty. | number[] |
CursorType
| Property Name | Description | Data Type |
|---|---|---|
| auto | Represents the default cursor type Auto. | enum |
| crossHair | Represents the cursor type CrossHair. | enum |
| e_resize | The cursor indicates that an edge of a box is to be moved right (east). | enum |
| ew_resize | Represents a bidirectional resize cursor. | enum |
| grab | Represents a grab cursor. | enum |
| grabbing | Represents a grabbing cursor. | enum |
| move | Represents a Move cursor when moving on something. | enum |
| n_resize | The cursor indicates that an edge of a box is to be moved up (north). | enum |
| ne_resize | The cursor indicates that an edge of a box is to be moved up and right (north/east). | enum |
| ns_resize | Represents a bidirectional resize cursor. | enum |
| nw_resize | The cursor indicates that an edge of a box is to be moved up and left (north/west). | enum |
| pointer | Represents Pointer cursor type. | enum |
| s_resize | The cursor indicates that an edge of a box is to be moved down (south). | enum |
| se_resize | The cursor indicates that an edge of a box is to be moved down and right (south/east). | enum |
| sw_resize | The cursor indicates that an edge of a box is to be moved down and left (south/west). | enum |
| text | The cursor indicates text that may be selected. | enum |
| w_resize | The cursor indicates that an edge of a box is to be moved left (west). | enum |
AnnotationResizerLocation
| Property Name | Description | Data Type |
|---|---|---|
| Corners | When resizing annotation, Resizer location is represented by corners. | enum |
| Edges | When resizing annotation, Resizer location is represented by Edges. | enum |
AnnotationResizerShape
| Property Name | Description | Data Type |
|---|---|---|
| Circle | Represent the Resizer shape by Circle when resizing annotations. | enum |
| Square | Represent the Resizer shape by Square when resizing annotations. | enum |
LineHeadStyle
| Name | Description | Data Type |
|---|---|---|
| Arrow | Represents the line with Arrow head style. | enum |
| Closed | Represents the line with closed head style. | enum |
| ClosedArrow | Represents the line with Closed Arrow head style. | enum |
| Diamond | Represents the line with diamond head style. | enum |
| None | Represents the line with no head style. | enum |
| Open | Represents the line with open arrow head style. | enum |
| OpenArrow | Represents the line with Open Arrow head style. | enum |
| Round | Represents the line with round head style. | enum |
| Square | Represents the line with square head style. | enum |
CustomStampSettings
| Name | Description | Data Type |
|---|---|---|
| customStampImageSource | Defines the custom stamp images source to be added in stamp menu of the PDF Viewer toolbar. | string |
| customStampName | Defines the custom stamp name to be added in stamp menu of the PDF Viewer toolbar. | string |
FontStyle
| Name | Description | Data Type |
|---|---|---|
| Bold | Represents the text content style will be bold. | enum |
| Italic | Represents the text content style will be italic. | enum |
| None | Represents the text content style does not set. | enum |
| Strikethrough | Represents the text content style will be strikethrough. | enum |
| Underline | Represents the text content style will be underline. | enum |
TextAlignment
| Name | Description | Data Type |
|---|---|---|
| Center | Represents the text alignment in Center. The text content will be shown at center. | enum |
| Justify | Represents the text alignment of Justify. The text is aligned along the left margin. | enum |
| Left | Represents the text alignment in left. The text content will be shown in left side. | enum |
| Right | Represents the text alignment in Right. The text content will be shown in right side. | enum |
CalibrationUnit
| Name | Description | Data Type |
|---|---|---|
| cm | Represents the unit of centimeter. | enum |
| ft | Represents the unit of feet. | enum |
| in | Represents the unit of inch. | enum |
| mm | Represents the unit of millimeter. | enum |
| p | Represents the unit of points. | enum |
| pt | Represents the unit of points. | enum |
DynamicStampItem
| Name | Description | Data Type |
|---|---|---|
| Approved | Represents a stamp indicating the document is approved. | enum |
| Confidential | Represents a stamp indicating the document is confidential. | enum |
| NotApproved | Represents a stamp indicating the document is not approved. | enum |
| Received | Represents a stamp indicating the document has been received. | enum |
| Reviewed | Represents a stamp indicating the document has been reviewed. | enum |
| Revised | Represents a stamp indicating the document has been revised. | enum |
SignStampItem
| Name | Description | Data Type |
|---|---|---|
| Accepted | Represents a stamp indicating the document is accepted. | enum |
| InitialHere | Represents a stamp indicating the initial placement here. | enum |
| Rejected | Represents a stamp indicating the document is rejected. | enum |
| SignHere | Represents a stamp indicating where the sign is needed. | enum |
| Witness | Represents a stamp indicating a witness is required. | enum |
StandardBusinessStampItem
| Name | Description | Data Type |
|---|---|---|
| Approved | Represents a stamp indicating the document is approved. | enum |
| Completed | Represents a stamp indicating the document is completed. | enum |
| Confidential | Represents a stamp indicating the document is confidential. | enum |
| Draft | Represents a stamp indicating the document is a draft. | enum |
| Final | Represents a stamp indicating the document is final. | enum |
| ForComment | Represents a stamp indicating the document is for comment. | enum |
| ForPublicRelease | Represents a stamp indicating the document is for public release. | enum |
| InformationOnly | Represents a stamp indicating the document is for information only. | enum |
| NotApproved | Represents a stamp indicating the document is not approved. | enum |
| NotForPublicRelease | Represents a stamp indicating the document is not for public release. | enum |
| PreliminaryResults | Represents a stamp indicating the document contains preliminary results. | enum |
| Void | Represents a stamp indicating the document is void. | enum |
API Methods in Vue PdfViewer Component
When user requests programmatic control beyond UI interactions, guide them to these API methods. This reference helps you recommend the right method based on user goals: loading documents, managing form fields, handling annotations, exporting data, or manipulating viewer state.
Your role: Match user intent to the appropriate API methods, explain when to use each method, and provide complete Vue-friendly examples using the PDF Viewer instance.
Table of Contents
- When to Use These APIs
- Get the Viewer Instance in Vue
- API Categories
- Complete API Reference
- Common Parameter Types
- Usage Examples by Scenario
When to Use These APIs
Guide users to these methods when they express these needs:
- "Load a PDF programmatically" → Use
load()andunload() - "Process form data from PDF" → Use
exportFormFieldsAsObject()orimportFormFields() - "Add or edit PDF annotations dynamically" → Use
annotation.addAnnotation(),deleteAnnotations(),exportAnnotation() - "Extract text from PDF" → Use
extractText()with bounds - "Implement undo or redo for PDF edits" → Use
undo()andredo() - "Refresh viewer layout after resize" → Use
updateViewerContainer() - "Navigate to specific coordinates" → Use
zoomToRect()or the coordinate conversion methods
Alternative guidance: If the user only needs toolbar actions, page navigation, or event handling, route them to the relevant feature reference instead of these APIs.
Get the Viewer Instance in Vue
Use one shared viewer accessor and reuse it for all API calls. This avoids repeating full component code blocks for every method example.
Vue 3 – Composition API
<template>
<ejs-pdfviewer
ref="pdfViewer"
:documentPath="documentPath"
style="height: 640px" />
</template>
<script setup>
import { ref, provide } from 'vue';
import {
PdfViewerComponent as EjsPdfviewer, Toolbar, Magnification, Navigation, LinkAnnotation, BookmarkView,
ThumbnailView, Print, TextSelection, TextSearch, Annotation, FormFields, FormDesigner } from '@syncfusion/ej2-vue-pdfviewer';
const pdfViewer = ref(null);
const documentPath = 'https://cdn.syncfusion.com/content/pdf/pdf-succinctly.pdf';
provide('PdfViewer', [
Toolbar, Magnification, Navigation, LinkAnnotation, BookmarkView,ThumbnailView, Print,
TextSelection, TextSearch, Annotation, FormFields, FormDesigner ]);
const getViewer = () => pdfViewer.value?.ej2Instances;
</script>Vue 2 or Vue 3 – Options API Access Pattern
Use the same methods, but access the instance through the component ref:
const viewer = this.$refs.pdfViewer?.ej2Instances;Module Access Pattern
- Viewer-level methods →
viewer.load(),viewer.download(),viewer.undo() - Annotation methods →
viewer.annotation.addAnnotation(),viewer.annotation.editAnnotation() - Form designer methods →
viewer.formDesigner.addFormField(),viewer.formDesigner.updateFormField()
API Categories
| Category | Methods | When to Recommend |
|---|---|---|
| Document Loading | load, unload | Open PDF from URL or Blob, switch documents, or clear the current viewer |
| Document Operations | download, extractPages, saveAsBlob | Download the current file, extract specific pages, or upload the modified PDF as a Blob |
| Form Fields | updateFormFields, updateFormFieldsValue, clearFormFields, resetFormFields, retrieveFormFields, focusFormField, importFormFields, exportFormFields, exportFormFieldsAsObject, formDesigner.addFormField, formDesigner.updateFormField, formDesigner.deleteFormField, formDesigner.selectFormField, formDesigner.resetFormField, formDesigner.setFormFieldMode, formDesigner.clearSelection, formDesigner.getRgbToHex | Use when working with fillable PDFs, pre-filling values, exporting form data, or creating form fields programmatically |
| Annotations | annotation.addAnnotation, deleteAnnotations, exportAnnotation, exportAnnotationsAsBase64String, exportAnnotationsAsObject, importAnnotation, annotation.selectAnnotation, annotation.editAnnotation, annotation.setAnnotationMode, annotation.clearSelection, annotation.hexToRgba | Use when adding, editing, saving, restoring, or selecting annotations programmatically |
| Navigation | getPageNumberFromClientPoint, getPageInfo, zoomToRect, convertClientPointToPagePoint, convertPagePointToClientPoint, convertPagePointToScrollingPoint | Use when zooming to an area, converting coordinates, or locating a page from a screen point |
| Text Extraction | extractText | Use when extracting text from a known PDF region |
| State Management | undo, redo, setJsonData, destroy, updateViewerContainer | Use when the app needs undo or redo, layout refresh, viewer cleanup, or state restore |
| UI Customization | addCustomMenu, showNotificationPopup | Use when extending the context menu or showing in-viewer notifications |
Complete API Reference
How to use this table: Match the user goal to the method, then provide a Vue snippet using const viewer = getViewer(); or const viewer = this.$refs.pdfViewer?.ej2Instances;.
List of Methods
| Method Name | Description | Parameters | Return Type | Vue Snippet |
|---|---|---|---|---|
| addAnnotation | Adds an annotation programmatically with the specified type and options | annotationType: AnnotationType, options?: AnnotationSettings | void | viewer?.annotation.addAnnotation('Highlight', { bounds: { x: 100, y: 100, width: 200, height: 50 } }); |
| addCustomMenu | Adds custom items to the PDF Viewer context menu | items: CustomToolbarItem[], hideDefaultMenu?: boolean, addAtBottom?: boolean | void | viewer?.addCustomMenu([{ id: 'custom1', text: 'Custom Item' }], false); |
| addFormField | Adds a form field to the PDF page programmatically | formFieldType: FormFieldType, options?: FormFieldSettings | HTMLElement | viewer?.formDesigner.addFormField('Textbox', { name: 'field1', bounds: { X: 100, Y: 100, Width: 200, Height: 30 } }); |
| clearFormFields | Clears all form field values in the loaded PDF | - | void | viewer?.clearFormFields(); |
| convertClientPointToPagePoint | Converts a client point to page coordinates | clientPoint: IPoint | IPoint | const pagePoint = viewer?.convertClientPointToPagePoint({ x: 100, y: 200 }); |
| convertPagePointToClientPoint | Converts a page point to client coordinates | pagePoint: IPoint | IPoint | const clientPoint = viewer?.convertPagePointToClientPoint({ x: 50, y: 75 }); |
| convertPagePointToScrollingPoint | Converts a page point to scrolling coordinates in the viewport | pagePoint: IPoint | IPoint | const scrollPoint = viewer?.convertPagePointToScrollingPoint({ x: 50, y: 75 }); |
| deleteAnnotations | Deletes the specified annotation from the document | annotationId: string | void | viewer?.deleteAnnotations('annotation-id-123'); |
| deleteFormField | Deletes a form field from the PDF page | formFieldId: `string \ | object, addAction: boolean` | void |
| destroy | Destroys the PDF Viewer instance and releases resources | - | void | viewer?.destroy(); |
| download | Downloads the current PDF document | - | void | viewer?.download(); |
| editAnnotation | Updates an existing annotation object | annotation: any | void | viewer?.annotation.editAnnotation({ id: 'annot-123', color: '#ff0000', opacity: 0.8 }); |
| exportAnnotation | Exports annotations as a JSON string | - | string | const annotations = viewer?.exportAnnotation(); |
| exportAnnotationsAsBase64String | Exports annotations as a Base64 string | - | string | const base64Annotations = viewer?.exportAnnotationsAsBase64String(); |
| exportAnnotationsAsObject | Exports annotations as a JSON object | - | object | const annotationsObject = viewer?.exportAnnotationsAsObject(); |
| exportFormFields | Exports form field data as XML | - | string | const formFieldsXml = viewer?.exportFormFields(); |
| exportFormFieldsAsObject | Exports form field data as a JSON object | - | object | const formFieldsObject = viewer?.exportFormFieldsAsObject(); |
| extractPages | Extracts the specified pages from the PDF | pageIndexes: number[] | void | viewer?.extractPages([0, 1, 2]); |
| extractText | Extracts text from the specified rectangular region | bounds: IRect | string | const text = viewer?.extractText(bounds); |
| clearSelection | Clears the current annotation or form field selection | formFieldId?: `string \ | object` | void |
| focusFormField | Focuses a form field by field name | fieldName: string | void | viewer?.focusFormField('fieldName'); |
| getPageInfo | Gets information about the specified page | pageIndex: number | PageInfo | const pageInfo = viewer?.getPageInfo(0); |
| getPageNumberFromClientPoint | Gets the page number at a client coordinate | clientPoint: IPoint | number | const pageNumber = viewer?.getPageNumberFromClientPoint({ x: 100, y: 200 }); |
| getRgbToHex | Converts an RGB color object to hex | color: any | string | const hexColor = viewer?.formDesigner.getRgbToHex({ r: 255, g: 87, b: 51 }); |
| hexToRgba | Converts a hex color string to RGBA | hex: string | string | const rgba = viewer?.annotation.hexToRgba('#FF5733'); |
| importAnnotation | Imports annotations from a JSON string | annotationData: string | void | viewer?.importAnnotation(annotationJson); |
| importFormFields | Imports form field data from XML | formFieldData: string | void | viewer?.importFormFields(formFieldsXml); |
| load | Loads a PDF from a URL, base64 string, or Blob | document: `string \ | Blob` | void |
| redo | Redoes the last undone action | - | void | viewer?.redo(); |
| resetFormField | Resets one form field to its original state | formFieldId: `string \ | object` | void |
| resetFormFields | Resets all form fields to their default values | - | void | viewer?.resetFormFields(); |
| retrieveFormFields | Retrieves the form field collection from the PDF | - | FormField[] | const formFields = viewer?.retrieveFormFields(); |
| saveAsBlob | Saves the current PDF as a Blob object | - | Blob | const blob = viewer?.saveAsBlob(); |
| selectAnnotation | Selects an annotation using its ID or object | annotationId: `string \ | object` | void |
| selectFormField | Selects a form field in the PDF Viewer | formFieldId: `string \ | object` | void |
| setAnnotationMode | Sets the annotation type that the next user action will add | type: AnnotationType | void | viewer?.annotation.setAnnotationMode('Rectangle'); |
| setFormFieldMode | Sets the form field mode for the next user action | formFieldType: FormFieldType | void | viewer?.formDesigner.setFormFieldMode('Textbox'); |
| setJsonData | Applies JSON configuration or restored viewer state | jsonData: string | void | viewer?.setJsonData(jsonConfigString); |
| showNotificationPopup | Displays an in-viewer notification message | message: string, timeout?: number | void | viewer?.showNotificationPopup('Success!', 3000); |
| undo | Undoes the last action | - | void | viewer?.undo(); |
| unload | Unloads the current PDF document | - | void | viewer?.unload(); |
| updateFormField | Updates a form field with new properties | formFieldId: `string \ | object, options: FormFieldSettings` | void |
| updateFormFields | Updates one or more form fields in the document | formFields: FormField[] | void | viewer?.updateFormFields([{ name: 'field1', value: 'newValue' }]); |
| updateFormFieldsValue | Updates a form field value by field name | fieldName: string, fieldValue: string | void | viewer?.updateFormFieldsValue('fieldName', 'newValue'); |
| updateViewerContainer | Updates the viewer container size and layout | - | void | viewer?.updateViewerContainer(); |
| zoomToRect | Zooms the viewer to fit a rectangular region | rect: IRect | void | viewer?.zoomToRect({ x: 0, y: 0, width: 200, height: 300 }); |
Common Parameter Types
Use these structures when building method calls. Most method signatures are identical to the JavaScript-based Syncfusion API, but in Vue you call them through the viewer instance.
⚠️ CRITICAL: Bounds Format Differs Between Annotations and Form Fields
Annotations use lowercase bounds keys:
const viewer = getViewer();
viewer?.annotation.addAnnotation('Rectangle', {
bounds: { x: 100, y: 100, width: 200, height: 50 }
});Form fields use capitalized coordinate keys inside `bounds`:
const viewer = getViewer();
viewer?.formDesigner.addFormField('Textbox', {
name: 'customerName',
bounds: { X: 100, Y: 100, Width: 200, Height: 30 }
});Do not interchange these two formats.
IPoint
When to use: Coordinate conversion and page hit-testing methods.
| Property | Description | Data Type |
|---|---|---|
| x | The x-coordinate value | number |
| y | The y-coordinate value | number |
IRect
When to use: Text extraction, zooming to a region, or annotation bounds.
| Property | Description | Data Type |
|---|---|---|
| x | Left coordinate | number |
| y | Top coordinate | number |
| width | Rectangle width | number |
| height | Rectangle height | number |
PageInfo
When to use: Returned by getPageInfo() for page measurements and layout calculations.
| Property | Description | Data Type |
|---|---|---|
| pageNumber | The page number. It starts from the 1 and it is not a index based. | number |
| height | The page height | number |
| rotation | The page rotation angle | number |
FormField
When to use: Returned by retrieveFormFields() or passed to updateFormFields().
| Property | Description | Data Type |
|---|---|---|
| name | Form field name | string |
| value | Current field value | string |
| fieldType | Field type such as text box or checkbox | string |
PdfAnnotationBase
When to use: Passed to annotation.addAnnotation().
| Property | Description | Data Type |
|---|---|---|
| annotationType | The annotation type | string |
| pageIndex / pageNumber | Target page information | number |
| bounds | Annotation rectangle | IRect |
CustomToolbarItem
When to use: Passed to addCustomMenu().
| Property | Description | Data Type |
|---|---|---|
| id | Unique item identifier | string |
| text | Menu item text | string |
| tooltipText | Tooltip text | string |
| iconCss | Optional icon class | string |
AnnotationType
When to use: Passed to annotation.addAnnotation() or annotation.setAnnotationMode().
Valid values include: 'None', 'Highlight', 'Underline', 'Strikethrough', 'Squiggly', 'Line', 'Arrow', 'Rectangle', 'Circle', 'Polygon', 'Distance', 'Perimeter', 'Area', 'Radius', 'Volume', 'FreeText', 'HandWrittenSignature', 'Ink', 'Stamp', 'Image', 'StickyNotes'
AnnotationSettings
When to use: Optional parameter for annotation.addAnnotation() to customize annotation properties. Annotation settings object can include:
| Property | Description | Data Type |
|---|---|---|
| bounds | Annotation bounds | IRect |
| pageNumber | The page number where annotation is placed. It starts from the 1 and it is not a index based. | number |
| subject | Annotation subject | string |
| note | Note or comment | string |
| color | Main color | string |
| opacity | Opacity from 0 to 1 | number |
| strokeColor | Border or stroke color | string |
| fillColor | Fill color | string |
| thickness | Border or line thickness | number |
| fontSize | Font size for text-based annotations | number |
| fontFamily | Font family for text-based annotations | string |
| path | SVG path data for Ink annotations (array of point commands: M for move, L for line) | string |
FormFieldType
When to use: Passed to formDesigner.addFormField() or formDesigner.setFormFieldMode().
Valid values include: 'Textbox', 'Password', 'Checkbox', 'RadioButton', 'DropDown', 'ListBox', 'SignatureField', 'InitialField'
FormFieldSettings
When to use: Passed to formDesigner.addFormField() or formDesigner.updateFormField().
| Property | Description | Data Type |
|---|---|---|
| name | Field name | string |
| bounds | Field bounds | IRect |
| value | Default value | string |
| fontFamily | Font family | string |
| fontSize | Font size | number |
| fontStyle | Font style | string |
| color | Text color | string |
| backgroundColor | Background color | string |
| borderColor | Border color | string |
| thickness | Border thickness | number |
| alignment | Text alignment | string |
| isReadOnly | Read-only flag | boolean |
| visibility | Field visibility | string |
| maxLength | Maximum length | number |
| isRequired | Required flag | boolean |
| isPrint | Print flag | boolean |
| tooltip | Tooltip text | string |
| options | DropDown or ListBox items | Item[] |
| isChecked | Checkbox or radio state | boolean |
| isSelected | Radio button selected state | boolean |
CustomStamp
When to use: For custom stamp image definitions.
| Property | Description | Data Type |
|---|---|---|
| customStampName | Display name of the stamp | string |
| customStampImageSource | Base64 image source | string |
AnnotationDrawingOptions
When to use: To constrain line and arrow drawing angles.
| Property | Description | Data Type |
|---|---|---|
| enableLineAngleConstraints | Enables angular constraints | boolean |
| restrictLineAngleTo | Allowed angle interval in degrees | number |
Usage Examples by Scenario
Use these patterns after establishing the viewer instance once.
Scenario 1: Load and Download a PDF
When: The user wants to open a document dynamically and let the user save it.
const viewer = getViewer();
viewer?.load(documentPath);
viewer?.download();Scenario 2: Read and Update Form Fields
When: The user needs to prefill or extract form data.
const viewer = getViewer();
const formFields = viewer?.retrieveFormFields();
viewer?.updateFormFieldsValue('firstName', 'John');
viewer?.updateFormFieldsValue('email', 'john@example.com');
const formData = viewer?.exportFormFieldsAsObject();Scenario 3: Export and Restore Annotations
When: The user wants to persist annotations between sessions.
const viewer = getViewer();
const annotationJson = viewer?.exportAnnotation();
viewer?.importAnnotation(annotationJson);
viewer?.deleteAnnotations('annotation-id-123');Scenario 4: Extract Text from a Region
When: The user wants text from a specific rectangle.
const viewer = getViewer();
const bounds = { x: 100, y: 150, width: 200, height: 100 };
const extractedText = viewer?.extractText(bounds);Scenario 5: Zoom to a Target Region
When: The user wants to focus the viewer on a known area.
const viewer = getViewer();
const pageInfo = viewer?.getPageInfo(0);
viewer?.zoomToRect({ x: 50, y: 50, width: 300, height: 300 });Scenario 6: Undo and Redo Viewer Actions
When: The user edits annotations or forms and needs reversible actions.
const viewer = getViewer();
viewer?.undo();
viewer?.redo();Scenario 7: Extend the Context Menu
When: The user wants custom actions inside the viewer.
const viewer = getViewer();
const customItems = [
{ id: 'custom-1', text: 'My Action', tooltipText: 'Do something custom' }
];
viewer?.addCustomMenu(customItems, false);
viewer?.showNotificationPopup('PDF loaded successfully', 3000);Scenario 8: Programmatic Annotation Management
When: The user needs to add, select, edit, or switch annotation modes from code.
- Note: Pagenumber is starts from 1.
const viewer = getViewer();
viewer?.annotation.addAnnotation('Highlight', {
bounds: { x: 100, y: 100, width: 200, height: 50 },
pageNumber: 1, color: '#FFFF00', opacity: 0.5, author: 'System',
subject: 'Auto-highlight', note: 'Important section'
});
viewer?.annotation.selectAnnotation('annotation-id-123');
viewer?.annotation.editAnnotation({
id: 'annotation-id-123', color: '#FF0000', opacity: 0.8, note: 'Updated comment'
});
viewer?.annotation.setAnnotationMode('Rectangle');
viewer?.annotation.clearSelection();
const rgbaColor = viewer?.annotation.hexToRgba('#FF5733');Ink Annotation with Path Points (Freehand Drawing):
const viewer = getViewer();
// Add ink annotation with SVG path data representing freehand drawing
viewer?.annotation.addAnnotation('Ink', {
offset: { x: 150, y: 100 }, pageNumber: 1, width: 200, height: 60,
path: '[{"command":"M","x":244.83,"y":982.00},{"command":"L","x":250.83,"y":953.33},{"command":"L","x":260.83,"y":920.33}]', strokeColor: '#0000FF', thickness: 2,opacity: 1, author: 'User'
});Scenario 9: Dynamic Form Field Creation and Management
When: The user needs to create or edit fillable PDF fields in code.
const viewer = getViewer();
viewer?.formDesigner.addFormField('Textbox', {
name: 'firstName', bounds: { X: 100, Y: 100, Width: 200, Height: 30 },
value: '', fontSize: 12, fontFamily: 'Helvetica', color: '#000000',
backgroundColor: '#FFFFFF', borderColor: '#000000',
thickness: 1, isRequired: true, tooltip: 'Enter your first name'
});
viewer?.formDesigner.addFormField('Checkbox', {
name: 'agreeTerms', bounds: { X: 100, Y: 150, Width: 20, Height: 20 },
isChecked: false, borderColor: '#000000', backgroundColor: '#FFFFFF'
});
viewer?.formDesigner.addFormField('DropDown', {
name: 'country', bounds: { X: 100, Y: 200, Width: 200, Height: 30 },
options: [
{ itemName: 'USA', itemValue: 'us' }, { itemName: 'Canada', itemValue: 'ca' }, { itemName: 'UK', itemValue: 'uk' }
],
fontSize: 12, fontFamily: 'Helvetica'
});
viewer?.formDesigner.selectFormField('firstName');
viewer?.formDesigner.updateFormField('firstName', {
backgroundColor: '#FFFF00', fontSize: 14, value: 'John'
});
viewer?.formDesigner.resetFormField('firstName');
viewer?.formDesigner.deleteFormField('firstName', true);
viewer?.formDesigner.setFormFieldMode('Textbox');
viewer?.formDesigner.clearSelection('firstName');
const hexColor = viewer?.formDesigner.getRgbToHex({ r: 255, g: 87, b: 51 });Scenario 10: Configure Custom Stamps
When: The user wants company-specific stamp images available in the stamp menu.
const customStamps = [
{
customStampName: 'Approved',
customStampImageSource: 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAA...'
},
{
customStampName: 'Confidential',
customStampImageSource: 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAA...'
}
];Bind the collection through the viewer configuration that supports custom stamps.
Scenario 11: Constrain Annotation Drawing Angles
When: The user wants line and arrow annotations to snap to fixed angles.
const annotationDrawingOptions = {
enableLineAngleConstraints: true,
restrictLineAngleTo: 45
};Bookmark Navigation
Brief: Bookmark navigation lets Vue PDF Viewer apps expose built-in PDF table-of-contents hierarchies for instant jumps across lengthy documents.
⚠️ Critical: Correct API Access
Always call bookmark APIs through the viewer instance's `bookmark` module. Retrieve the underlying EJ2 instance from your Vue ref before calling methods.
// Composition API
const viewerRef = ref(null);
viewerRef.value?.ej2Instances.bookmark.openBookmarkPane();
// Options API
this.$refs.pdfViewer?.ej2Instances.bookmark.goToBookmark(pageIndex, y);Table of Contents
- When to Use
- Prerequisites
- Enable Bookmarks
- API Methods
- Complete Examples
- Bookmark Data Structure
- Bookmark Properties
- Best Practices
When to Use
Use bookmarks when you need to:
- Navigate large PDFs without manual scrolling
- Surface a built-in table of contents alongside the viewer UI
- Drive custom navigation widgets that jump to specific sections
- Support structured documents such as specs, textbooks, or manuals
Skip bookmark UI when the source PDF lacks embedded bookmarks or when standard page navigation is enough.
Prerequisites
1. Turn on bookmark support via :enableBookmark="true". 2. Register the BookmarkView service (and other services you need) using Vue's provide helper. 3. Point documentPath and, for standalone builds, resourceUrl to valid assets. 4. Ensure the PDF actually contains bookmark metadata—many simple PDFs do not.
Enable Bookmarks
<template>
<div class="viewer-shell">
<ejs-pdfviewer
id="pdfViewer"
ref="pdfViewer"
:documentPath="documentPath"
:enableBookmark="true"
style="height: 640px"
/>
</div>
</template>
<script setup>
import {
PdfViewerComponent as EjsPdfviewer,
Toolbar,
Magnification,
Navigation,
LinkAnnotation,
BookmarkView,
Annotation,
ThumbnailView,
Print,
TextSelection,
TextSearch
} from '@syncfusion/ej2-vue-pdfviewer';
import { provide, ref } from 'vue';
const documentPath = 'https://cdn.syncfusion.com/content/pdf/pdf-succinctly.pdf';
const pdfViewer = ref(null);
provide('PdfViewer', [
Toolbar,
Magnification,
Navigation,
LinkAnnotation,
BookmarkView,
Annotation,
ThumbnailView,
Print,
TextSelection,
TextSearch
]);
</script>
<style scoped>
.viewer-shell {
height: 100vh;
display: flex;
flex-direction: column;
}
</style>API Methods
All signatures below assume you already verifiedpdfViewerRef.value?.ej2Instances.bookmark(Composition) orthis.$refs.pdfViewer?.ej2Instances.bookmark(Options).
1. openBookmarkPane()
Opens the built-in bookmark sidebar.
const openBookmarks = () => {
pdfViewer.value?.ej2Instances.bookmark.openBookmarkPane();
};2. closeBookmarkPane()
Closes the bookmark sidebar.
const closeBookmarks = () => {
pdfViewer.value?.ej2Instances.bookmark.closeBookmarkPane();
};3. getBookmarks()
Retrieves an array of bookmark nodes. Returns [] when none exist.
const fetchBookmarks = () => {
const items = pdfViewer.value?.ej2Instances.bookmark.getBookmarks() ?? [];
bookmarkTree.value = items;
};4. goToBookmark(pageIndex: number, y: number)
Navigates to a zero-based page index and Y offset. Returns true when the jump succeeds.
const goToBookmark = (node) => {
if (typeof node?.page === 'number' && typeof node?.y === 'number') {
const isSuccessful = pdfViewer.value?.ej2Instances.bookmark.goToBookmark(node.page, node.y);
if (!isSuccessful) {
console.warn('Bookmark navigation failed');
}
}
};Complete Examples
Example 1: Open/Close Buttons (Composition API)
<template>
<div>
<div class="controls">
<button @click="openBookmark">Open Bookmarks</button>
<button @click="closeBookmark">Close Bookmarks</button>
</div>
<ejs-pdfviewer
id="pdfViewer"
ref="pdfViewer"
:documentPath="documentPath"
:enableBookmark="true"
style="height: 600px"
/>
</div>
</template>
<script setup>
import { PdfViewerComponent as EjsPdfviewer, BookmarkView, Toolbar } from '@syncfusion/ej2-vue-pdfviewer';
import { provide, ref } from 'vue';
const pdfViewer = ref(null);
const documentPath = 'https://cdn.syncfusion.com/content/pdf/pdf-succinctly.pdf';
provide('PdfViewer', [Toolbar, BookmarkView]);
const openBookmark = () => pdfViewer.value?.ej2Instances.bookmark.openBookmarkPane();
const closeBookmark = () => pdfViewer.value?.ej2Instances.bookmark.closeBookmarkPane();
</script>
<style scoped>
.controls {
margin-bottom: 12px;
display: flex;
gap: 12px;
}
</style>Example 2: Toggle Button (Options API)
<template>
<div>
<button @click="toggleBookmarks">
{{ isPaneOpen ? 'Hide Bookmarks' : 'Show Bookmarks' }}
</button>
<ejs-pdfviewer
id="pdfViewer"
ref="pdfViewer"
:documentPath="documentPath"
:enableBookmark="true"
style="height: 600px"
/>
</div>
</template>
<script>
import { PdfViewerComponent, BookmarkView } from '@syncfusion/ej2-vue-pdfviewer';
export default {
components: { 'ejs-pdfviewer': PdfViewerComponent },
data: () => ({
isPaneOpen: false,
documentPath: 'https://cdn.syncfusion.com/content/pdf/pdf-succinctly.pdf'
}),
provide() {
return { PdfViewer: [BookmarkView] };
},
methods: {
toggleBookmarks() {
const bookmark = this.$refs.pdfViewer?.ej2Instances.bookmark;
if (!bookmark) return;
if (this.isPaneOpen) {
bookmark.closeBookmarkPane();
} else {
bookmark.openBookmarkPane();
}
this.isPaneOpen = !this.isPaneOpen;
}
}
};
</script>Example 3: Auto-Open Bookmarks on Load
<template>
<ejs-pdfviewer
id="pdfViewer"
ref="pdfViewer"
:enableBookmark="true"
:documentPath="documentPath"
:documentLoad="handleDocumentLoad"
style="height: 640px"
/>
</template>
<script setup>
import { PdfViewerComponent as EjsPdfviewer, BookmarkView } from '@syncfusion/ej2-vue-pdfviewer';
import { provide, ref } from 'vue';
const pdfViewer = ref(null);
const documentPath = 'https://cdn.syncfusion.com/content/pdf/pdf-succinctly.pdf';
provide('PdfViewer', [BookmarkView]);
const handleDocumentLoad = () => {
if (pdfViewer.value?.ej2Instances.pageCount > 20) {
pdfViewer.value.ej2Instances.isBookmarkPanelOpen = true;
}
};
</script>Example 4: Custom Bookmark Sidebar
<template>
<div class="layout">
<aside>
<h3>Table of Contents</h3>
<p v-if="!bookmarks.length">No bookmarks</p>
<ul v-else>
<li v-for="bookmark in bookmarks" :key="bookmark.title">
<button @click="goTo(bookmark)">{{ bookmark.title }}</button>
</li>
</ul>
</aside>
<section>
<ejs-pdfviewer
id="pdfViewer"
ref="pdfViewer"
:documentPath="documentPath"
:enableBookmark="true"
style="height: 100%"
/>
</section>
</div>
</template>
<script setup>
import { PdfViewerComponent as EjsPdfviewer, BookmarkView } from '@syncfusion/ej2-vue-pdfviewer';
import { onMounted, provide, ref } from 'vue';
const pdfViewer = ref(null);
const bookmarks = ref([]);
const documentPath = 'https://cdn.syncfusion.com/content/pdf/pdf-succinctly.pdf';
provide('PdfViewer', [BookmarkView]);
onMounted(() => {
setTimeout(() => {
const nodes = pdfViewer.value?.ej2Instances.bookmark.getBookmarks();
bookmarks.value = nodes ?? [];
}, 1000);
});
const goTo = (bookmark) => {
pdfViewer.value?.ej2Instances.bookmark.goToBookmark(bookmark.page, bookmark.y);
};
</script>
<style scoped>
.layout {
display: flex;
height: 100vh;
}
aside {
width: 260px;
padding: 16px;
border-right: 1px solid #e2e2e2;
overflow-y: auto;
}
section {
flex: 1;
}
button {
display: block;
width: 100%;
margin-bottom: 8px;
}
</style>Bookmark Data Structure
getBookmarks() returns an array of nodes shaped like the following:
| Property | Type | Description | Example |
|---|---|---|---|
title | string | Bookmark caption displayed in UI | "Chapter 2" |
page | number | Zero-based destination page index | 4 |
y | number | Vertical offset within the page | 180 |
children | BookmarkNode[] | Nested bookmarks | [{ title: 'Section 2.1', ... }] |
[
{
title: 'Chapter 1',
page: 0,
y: 120,
children: [
{ title: 'Section 1.1', page: 1, y: 160, children: [] }
]
},
{ title: 'Chapter 2', page: 4, y: 80, children: [] }
];Bookmark Properties
isBookmarkPanelOpen lets you control the sidebar's default state.
| Property | Description | Type | Default |
|---|---|---|---|
isBookmarkPanelOpen | Open (true) or collapse (false) the built-in bookmark pane. | boolean | false |
Example
<ejs-pdfviewer
ref="pdfViewer"
:documentPath="documentPath"
:resourceUrl="resourceUrl"
:enableBookmark="true"
:isBookmarkPanelOpen="true"
/>Or toggle it dynamically:
const handleDocumentLoad = () => {
const instance = pdfViewer.value?.ej2Instances;
if (instance?.pageCount > 30) {
instance.isBookmarkPanelOpen = true;
}
};Best Practices
1. Guard ref access: Always confirm pdfViewerRef and bookmark exist before calling methods. 2. Wait for load: Use documentLoad, onMounted delays, or watchers so bookmarks are ready before reading them. 3. Handle empty arrays: Display fallback text when getBookmarks() returns []. 4. Cache results: Store the bookmark list in component state to avoid repeated calls. 5. Validate nodes before jumping: Ensure page/y are valid numbers prior to goToBookmark calls. 6. Defer heavy logic: When loading remote PDFs, add a small timeout or rely on viewer events to avoid accessing the bookmark API too early.
Context Menu
Brief: The Vue PDF Viewer provides a context-aware context menu that dynamically updates based on the right-clicked element. It supports built-in menu items for text, annotations, and form fields, with extensive customization options to add custom items, handle click events, and dynamically show or hide items.
Table of Contents
- When to Use This Guide
- Context Menu Component Properties
- Understanding the Context Menu
- Built-in Context Menu Items
- Text Menu Items
- Annotation Menu Items
- Form Field Menu Items
- Empty Space Menu Items
- Add Custom Context Menu Items
- Handle Click Events for Custom Menu Items
- Dynamic Context Menu Customization
- Disable the Context Menu
- Complete Example with Multiple Custom Menu Items
---
When to Use This Guide
Guide the user to implement context menu functionality when they need to:
- Add custom actions to the right-click menu (e.g., "Search in Google", "Lock annotation")
- Provide context-specific options based on what the user right-clicks (text, annotation, form field)
- Control which menu items appear based on the current selection or document state
- Replace default menu actions with custom business logic
- Disable the context menu entirely for simplified user experiences
Common user requests that require this guide:
- "Add a custom menu item to search selected text"
- "Show different menu options for locked vs unlocked annotations"
- "Disable the default context menu"
- "Add custom actions when right-clicking on form fields"
- "Control when menu items appear or hide dynamically"
---
Context Menu Component Properties
These properties are available directly on the ejs-pdfviewer (PdfViewerComponent) to control context menu-related functionality:
| Property Name | Description | Type | Default Value |
|---|---|---|---|
| contextMenuOption | Configure context menu options. Set to None to disable the context menu entirely. | ContextMenuOption | null |
| contextMenuSettings | Configure context menu appearance and behavior. | ContextMenuSettings | null |
| disableContextMenuItems | Disable specific context menu items by specifying their IDs. | string[] | null |
Usage Example
<template>
<ejs-pdfviewer
ref="viewer"
:documentPath="documentPath"
:serviceUrl="serviceUrl"
:contextMenuOption="contextMenuOption"
:contextMenuSettings="contextMenuSettings"
:disableContextMenuItems="disableContextMenuItems"
/>
</template>
<script setup lang="ts">
import { ref, onMounted } from 'vue';
import {
PdfViewerComponent,
Toolbar,
Magnification,
Navigation,
ContextMenuItem
} from '@syncfusion/ej2-vue-pdfviewer';
const viewer = ref<PdfViewerComponent | null>(null);
const documentPath = 'PDF_Succinctly.pdf';
const serviceUrl = 'https://services.syncfusion.com/vue/production/api/pdfviewer';
const contextMenuOption = 'Auto';
const disableContextMenuItems = ['cut', 'paste'];
const contextMenuSettings = {
contextMenuAction: 'RightClick',
contextMenuItems: [
ContextMenuItem.Comment,
ContextMenuItem.Copy,
ContextMenuItem.Cut,
ContextMenuItem.Delete,
ContextMenuItem.Highlight,
ContextMenuItem.Paste,
ContextMenuItem.Properties,
ContextMenuItem.ScaleRatio,
ContextMenuItem.Strikethrough,
ContextMenuItem.Underline
]
};
onMounted(() => {
const instance = viewer.value?.ej2Instances;
if (instance) {
instance.contextMenuSettings = contextMenuSettings;
}
});
</script>Note: Provide the required services using provide: { pdfviewer: [Toolbar, Magnification, Navigation] } when registering the component, or register them globally if you are using the composition API.---
Understanding the Context Menu
When implementing context menu functionality, guide the user to understand these capabilities:
- Default Behavior: The viewer automatically provides standard actions (cut, copy, annotation management) based on what the user right-clicks. Use this when the user needs basic functionality without customization.
- Customization: Add custom menu items when the user needs domain-specific actions (e.g., "Search in Google", "Lock annotation"). You can also remove default items or reorder them to match the user's workflow.
- Granular Control: Disable the menu entirely when the user wants a simplified interface, or replace default actions with custom business logic.
- Client-side Interaction: The context menu operates entirely on the client side, ensuring consistent behavior regardless of initial server configuration. This also makes it reliable for offline scenarios.
---
Built-in Context Menu Items
When to reference this section: Guide the user here when they need to understand what default menu items are available or when they want to know which context triggers which menu items.
The context menu displays different default items based on the element being right-clicked. Understanding these built-in items helps when deciding whether to customize, extend, or replace the default menu.
Text Menu Items
Context: These items appear when the user has selected text in the PDF document. Use this knowledge when implementing custom text-related actions or when the user asks about text selection menu options.
| Item | Description |
|---|---|
| Copy | Copies selected text to the clipboard. |
| Highlight | Highlights selected text using the default highlight color. |
| Underline | Applies an underline to the selected text. |
| Strikethrough | Applies a strikethrough to the selected text. |
| Squiggly | Applies a squiggly underline to the selected text. |
| Redact Text | Redacts the selected text. |
Annotation Menu Items
Context: These items appear when the user right-clicks on an existing annotation (highlight, shape, stamp, etc.). Guide the user to this section when they need to understand or customize annotation-related menu actions.
| Item | Description |
|---|---|
| Copy | Copies the selected annotation for pasting within the same page. |
| Cut | Removes the selected annotation and copies it to the clipboard. |
| Paste | Pastes a previously copied or cut annotation. |
| Delete | Permanently removes the selected annotation. |
| Comments | Opens the comment panel to manage discussions on the annotation. |
Form Field Menu Items
Context: These items appear when the viewer is in form designer mode and the user right-clicks on a form field (textbox, checkbox, dropdown, etc.). Reference this when the user is building form design functionality.
| Item | Description |
|---|---|
| Copy | Copies the selected form field for duplication. |
| Cut | Removes the selected form field for relocation. |
| Paste | Pastes a copied or cut form field. |
| Delete | Removes the selected form field from the document. |
| Properties | Launches the properties dialog for the specific form field. |
Empty Space Menu Items
Context: These items appear when the user right-clicks on empty space (no text selection, no annotation, no form field). This is useful for paste operations after copying/cutting annotations or form fields.
| Item | Description |
|---|---|
| Paste | Pastes a previously copied annotation or form field. |
---
Add Custom Context Menu Items
When to use: Guide the user to add custom menu items when they need domain-specific actions beyond the built-in options. Common scenarios include:
- Adding "Search in Google" for selected text
- Adding "Lock/Unlock annotation" for security workflows
- Adding "Submit form" or "Validate form" for form processing
- Adding integration actions (e.g., "Save to database", "Send to API")
Decision point:
- Use
hideDefaultMenu: falsewhen the user wants to extend the default menu with additional options - Use
hideDefaultMenu: truewhen the user wants to completely replace the default menu with custom actions only
Method
addCustomMenu(menuItems, hideDefaultMenu?, addAtBottom?)
Adds custom options to the context menu using the addCustomMenu() method. Call this during the documentLoad event to ensure the viewer is fully initialized before customization.
Parameters
- menuItems: Array of custom menu item objects (see structure below)
- hideDefaultMenu (optional): Set to
trueto show only custom items,falseto keep default items alongside custom ones (default: false) - addAtBottom (optional): Set to
trueto place custom items at the bottom of the menu,falsefor top placement (default: false)
Menu Item Object Structure
Each custom menu item requires these properties:
{
text: string; // Display text for the menu item
id: string; // Unique identifier for the menu item
iconCss?: string; // CSS class for the icon (e.g., 'e-icons e-search')
}Implementation Example
Scenario: User wants to add "Search in Google" for text and "Lock/Unlock" for annotations.
const menuItems = [
{ text: 'Search In Google', id: 'search_in_google', iconCss: 'e-icons e-search' },
{ text: 'Lock Annotation', iconCss: 'e-icons e-lock', id: 'lock_annotation' },
{ text: 'Unlock Annotation', iconCss: 'e-icons e-unlock', id: 'unlock_annotation' },
{ text: 'Lock Form Fields', iconCss: 'e-icons e-lock', id: 'read_only_true' },
{ text: 'Unlock Form Fields', iconCss: 'e-icons e-unlock', id: 'read_only_false' }
];
const documentLoad = () => {
const instance = viewer.value?.ej2Instances;
if (instance) {
instance.addCustomMenu(menuItems, false);
}
};Attach documentLoad to the component (@documentLoad="documentLoad"). Calling addCustomMenu() here ensures the viewer is fully initialized. Setting hideDefaultMenu to false preserves the built-in functionality while extending it with custom actions.
---
Handle Click Events for Custom Menu Items
When to implement: After adding custom menu items with addCustomMenu(), implement this event handler to define what happens when the user clicks each custom menu item.
Purpose: This event bridges the UI (menu item) with your business logic (search, lock, submit, etc.).
Event Method
customContextMenuSelect(args)
This event fires when the user clicks a custom menu item. Use the args.id to determine which item was clicked and execute the corresponding action.
Parameters
- args.id: The unique identifier of the clicked menu item (matches the
idyou defined inaddCustomMenu()) - args.cancel: Set to
falseto allow the default action (typically used with annotation/form field operations)
Implementation Pattern
const customContextMenuSelect = (args) => {
const instance = viewer.value?.ej2Instances;
if (!instance) {
return;
}
switch (args.id) {
case 'search_in_google':
if (instance.textSelectionModule?.isTextSelection) {
instance.textSelectionModule.selectionRangeArray.forEach((range) => {
if (/\S/.test(range.textContent)) {
window.open('https://www.google.com/search?q=' + range.textContent);
}
});
}
break;
case 'lock_annotation':
toggleAnnotationLock(instance, true, args);
break;
case 'unlock_annotation':
toggleAnnotationLock(instance, false, args);
break;
case 'read_only_true':
setFormFieldsReadOnly(instance, true, args);
break;
case 'read_only_false':
setFormFieldsReadOnly(instance, false, args);
break;
default:
break;
}
};
const toggleAnnotationLock = (instance, lock, args) => {
const selected = instance.selectedItems.annotations?.[0];
if (!selected) {
return;
}
const target = instance.annotationCollection.find(
(annotation) => annotation.uniqueKey === selected.id
);
if (target?.annotationSettings) {
target.annotationSettings.isLock = lock;
target.isCommentLock = lock;
instance.annotation.editAnnotation(target);
args.cancel = false;
}
};
const setFormFieldsReadOnly = (instance, isReadOnly, args) => {
instance.selectedItems.formFields.forEach((field) => {
if (field) {
instance.formDesignerModule.updateFormField(field, { isReadOnly });
}
});
args.cancel = false;
};Result: When the user right-clicks an annotation and selects "Lock Annotation", the annotation becomes read-only. Selecting "Unlock Annotation" restores editing capability, and the same handler covers read-only toggles for form fields.
---
Dynamic Context Menu Customization
When to use: Implement this when the user needs menu items to appear or hide based on context. This is essential for:
- Showing "Search in Google" only when text is selected
- Showing "Lock" only for unlocked annotations, and "Unlock" only for locked ones
- Hiding menu items that aren't applicable to the current selection
- Creating intelligent, context-aware menus that adapt to user actions
Why this matters: Without dynamic customization, all custom menu items appear in every context menu, which creates a cluttered and confusing user experience.
Event Method
customContextMenuBeforeOpen(args)
This event fires just before the context menu is displayed, giving you the opportunity to show or hide menu items based on the current selection or document state.
Parameters
- args.ids: Array of all menu item IDs (both default and custom) that are about to be displayed
- args: Event arguments containing menu state information
Implementation Pattern
const customContextMenuBeforeOpen = (args) => {
const instance = viewer.value?.ej2Instances;
if (!instance) {
return;
}
args.ids.forEach((id) => {
const menuElement = document.getElementById(id);
if (!menuElement) {
return;
}
menuElement.style.display = 'none';
if (id === 'search_in_google' && instance.textSelectionModule?.isTextSelection) {
menuElement.style.display = 'block';
} else if (id === 'lock_annotation' || id === 'unlock_annotation') {
const isLockOption = id === 'lock_annotation';
const annotation = instance.selectedItems.annotations?.[0];
if (annotation?.annotationSettings) {
const shouldDisplay = (isLockOption && !annotation.annotationSettings.isLock) ||
(!isLockOption && annotation.annotationSettings.isLock);
menuElement.style.display = shouldDisplay ? 'block' : 'none';
}
} else if (id === 'read_only_true' || id === 'read_only_false') {
const isReadOnlyOption = id === 'read_only_true';
const formField = instance.selectedItems.formFields?.[0];
if (formField) {
const shouldDisplay = (isReadOnlyOption && !formField.isReadonly) ||
(!isReadOnlyOption && formField.isReadonly);
menuElement.style.display = shouldDisplay ? 'block' : 'none';
}
}
});
};Result: The menu intelligently adapts — "Search in Google" only appears when text is selected, and lock/unlock options appear based on the current state of the annotation. Form-field menu items show or hide depending on whether the selected fields are currently read-only.
---
Disable the Context Menu
When to use: Guide the user to disable the context menu when they need:
- A simplified, distraction-free PDF viewing experience
- To prevent users from accessing any context menu actions
- To implement completely custom right-click behavior using standard browser events
- To meet specific security or compliance requirements that prohibit context menus
Trade-off: Disabling the context menu removes all built-in functionality (copy, cut, paste, annotation management). Only do this if the user explicitly requests it or if you're implementing a completely custom alternative.
Property
contextMenuOption
Set this property to 'None' to completely disable the context menu.
Implementation
<template>
<ejs-pdfviewer
:contextMenuOption="'None'"
/>
</template>---
Complete Example with Multiple Custom Menu Items
Bring everything together by combining the base setup and the handlers defined earlier. The template below wires the events, while the <script setup> block should include the menuItems, documentLoad, customContextMenuSelect, toggleAnnotationLock, setFormFieldsReadOnly, and customContextMenuBeforeOpen implementations already covered above.
<template>
<ejs-pdfviewer
ref="viewer"
:documentPath="documentPath"
:serviceUrl="serviceUrl"
@documentLoad="documentLoad"
@customContextMenuSelect="customContextMenuSelect"
@customContextMenuBeforeOpen="customContextMenuBeforeOpen"
/>
</template>
<script setup lang="ts">
import { ref, provide } from 'vue';
import {
PdfViewerComponent,
Toolbar,
Magnification,
Navigation
} from '@syncfusion/ej2-vue-pdfviewer';
const viewer = ref<PdfViewerComponent | null>(null);
const documentPath = 'PDF_Succinctly.pdf';
const serviceUrl = 'https://services.syncfusion.com/vue/production/api/pdfviewer';
// Paste the menuItems array plus the handlers from the previous sections here.
// They can live in this block or be imported from a dedicated composable.
provide('pdfviewer', [Toolbar, Magnification, Navigation]);
</script>For production scenarios, remember to register the dependency services:
provide('pdfviewer', [Toolbar, Magnification, Navigation]);documentLoad, customContextMenuSelect, and customContextMenuBeforeOpen are bound in the template, ensuring the Vue PDF Viewer adds custom menu items, responds to click actions, and dynamically toggles menu visibility.
---
Download
Table of Contents
- When to Use Download
- Choosing a Download Approach
- Toolbar Download
- Programmatic Download
- Download with Event Interception
- Flatten Annotations Before Download
When to Use Download
Guide teams to wire up the download feature whenever users must persist the exact state of the currently loaded PDF. This covers annotations, form-field edits, ink drawings, comments, redactions, and page organizer changes that occur inside the viewer session.
Common scenarios:
- A filled form needs to be saved locally or uploaded elsewhere
- An annotated review copy must be exported with visible markups
- Page order changes need to be captured in an updated PDF
- Business workflows require generating a finalized, tamper-resistant PDF
Choosing a Download Approach
Need an out-of-the-box button in the viewer UI? → Enable the built-in toolbar download experience.
Need to initiate download from custom Vue UI or workflow logic? → Use the download() method on the viewer instance.
Need to intercept and customize the file before it leaves the browser? → Handle the downloadStart event and use saveAsBlob() for bespoke processing.
---
Toolbar Download
The simplest path is to expose the stock download icon by injecting the Toolbar module and keeping enableDownload set to true (default). You can also explicitly list DownloadOption inside toolbarSettings.toolbarItems if you are composing a custom toolbar.
Implementation
<template>
<div class="viewer-wrapper">
<ejs-pdfviewer
id="pdfViewer"
ref="pdfviewer"
:documentPath="documentPath"
:toolbarSettings="toolbarSettings"
:enableDownload="true"
/>
</div>
</template>
<script setup>
import { provide } from 'vue';
import {
PdfViewerComponent as EjsPdfviewer,
Toolbar,
Magnification,
Navigation,
Annotation,
BookmarkView
} from '@syncfusion/ej2-vue-pdfviewer';
provide('PdfViewer', [Toolbar, Magnification, Navigation, Annotation, BookmarkView]);
const documentPath = 'https://cdn.syncfusion.com/content/pdf/pdf-succinctly.pdf';
const toolbarSettings = {
toolbarItems: [
'PageNavigationTool',
'MagnificationTool',
'AnnotationEditTool',
'DownloadOption'
]
};
</script>Users now click the download icon to export the document with every edit made in the viewer.
---
Programmatic Download
When the download action must tie into external Vue UI (custom buttons, form wizards, timed auto-save, etc.), grab the component reference and call download().
API: download()
Triggers a download of the currently loaded PDF and includes all client-side modifications.
Implementation (Composition API)
<template>
<div>
<button @click="downloadCurrentPdf">Save PDF</button>
<ejs-pdfviewer id="pdfViewer" ref="pdfviewer" :documentPath="documentPath" />
</div>
</template>
<script setup>
import { ref, provide } from 'vue';
import { PdfViewerComponent as EjsPdfviewer, Toolbar } from '@syncfusion/ej2-vue-pdfviewer';
provide('PdfViewer', [Toolbar]);
const pdfviewer = ref(null);
const documentPath = 'https://cdn.syncfusion.com/content/pdf/pdf-succinctly.pdf';
const downloadCurrentPdf = () => {
pdfviewer.value?.ej2Instances.download();
};
</script>API: downloadFileName
Controls the filename used during download.
<ejs-pdfviewer
id="pdfViewer"
downloadFileName="CustomerApplication"
:documentPath="documentPath"
/>This saves the exported PDF as CustomerApplication.pdf for both toolbar-triggered and programmatic downloads.
---
Download with Event Interception
Use the downloadStart event to run validations, audit logic, watermarks, or to replace the default download behavior entirely.
API: downloadStart
- Type:
DownloadStartEventArgs - Key property:
cancel– set totrueto abort the built-in download and run custom logic.
Implementation
<template>
<ejs-pdfviewer
id="pdfViewer"
ref="pdfviewer"
:documentPath="documentPath"
@downloadStart="onDownloadStart"
/>
</template>
<script setup>
import { ref, provide } from 'vue';
import { PdfViewerComponent as EjsPdfviewer, Toolbar } from '@syncfusion/ej2-vue-pdfviewer';
provide('PdfViewer', [Toolbar]);
const pdfviewer = ref(null);
const documentPath = 'https://cdn.syncfusion.com/content/pdf/pdf-succinctly.pdf';
const onDownloadStart = (args) => {
if (!pdfviewer.value?.ej2Instances?.isDocumentEdited) {
return; // default download is fine
}
args.cancel = true;
runCustomSaveFlow();
};
const runCustomSaveFlow = async () => {
const blob = await pdfviewer.value.ej2Instances.saveAsBlob();
// upload blob to storage, show toast, etc.
};
</script>---
Flatten Annotations Before Download
Flattening bakes annotations, handwritten signatures, and form data into the page content so they cannot be altered in downstream PDF tools. This is useful for compliance, archival, or final approval workflows.
API: saveAsBlob()
Returns a Blob that represents the current PDF (post-edit). Combine it with the downloadStart interception hook.
Implementation
import { PdfDocument } from '@syncfusion/ej2-pdfviewer';
const blobToBase64 = (blob: Blob): Promise<string> => {
return new Promise((resolve, reject) => {
const reader = new FileReader();
reader.onerror = () => reject(reader.error);
reader.onload = () => {
const dataUrl = reader.result as string;
resolve(dataUrl.split(',')[1]);
};
reader.readAsDataURL(blob);
});
};
const flattenPdfAndSave = async () => {
const blob = await pdfviewer.value.ej2Instances.saveAsBlob();
const base64 = await blobToBase64(blob);
const document = new PdfDocument(base64);
document.flatten = true;
document.save(`${pdfviewer.value.ej2Instances.fileName}.pdf`);
document.destroy();
};
const onDownloadStart = async (args: DownloadStartEventArgs) => {
args.cancel = true;
await flattenPdfAndSave();
};Notes
saveAsBlob()captures annotations, form fields, and other viewer-side edits.- Flattening prevents recipients from modifying embedded markups once the PDF leaves the app.
- Include additional processing (e.g., watermarking) inside
flattenPdfAndSavebefore callingdocument.save.
Next: Review the complete Vue setup in getting-started.md for module registration, resource configuration, and viewer layout.
Form Field Events
Goal: Syncfusion Vue PDF Viewer exposes granular form designer events so Vue apps can react whenever a form field is created, selected, updated, moved, or validated. These hooks surface the metadata you need to drive UI rules, analytics, or custom persistence without polling the viewer state.
Subscribing to form-field events in Vue
Attach handlers on <ejs-pdfviewer> by using Vue event modifiers. Each event keeps its camelCase name.
<template>
<ejs-pdfviewer
ref="viewer"
:serviceUrl="serviceUrl"
:documentPath="documentPath"
@formFieldAdd="onFieldAdd"
@formFieldClick="onFieldClick"
@formFieldPropertiesChange="onFieldPropsChange"
/>
</template>
<script setup>
const serviceUrl = 'https://services.syncfusion.com/vue/production/api/pdfviewer'
const documentPath = 'FormTemplate.pdf'
const onFieldAdd = (args) => {
console.log('Field created', args.field?.name)
}
const onFieldClick = (args) => {
if (args.cancel) {
return
}
console.log('Clicked field id', args.field?.id)
}
const onFieldPropsChange = (args) => {
console.log('Updated props', args.changedProperties)
}
</script>Every handler receives an args object documented below. Use the same approach inside the Options API (methods) if you are not on <script setup>.
---
Event catalog (Vue)
| Event | When it fires | Args type | Payload highlights |
|---|---|---|---|
| formFieldAdd | A new field is inserted through the designer toolbar or via the API. | formFieldAddArgs | cancel (bool) lets you veto creation.<br>field (FormFieldInfo) holds the field being added. |
| formFieldRemove | A form element is removed from the page. | formFieldRemoveArgs | cancel (bool) to block deletion.<br>field (FormFieldInfo) describes the target.<br>pageIndex (number) tells which page lost the field. |
| formFieldClick | Users click any form field inside the viewer canvas. | formFieldClickArgs | cancel (bool) suppresses default focus behavior.<br>field (FormFieldInfo) for the clicked element. |
| formFieldDoubleClick | Double-click gesture occurs on a field (often to open the property pane). | formFieldDoubleClickArgs | cancel (bool) prevents the built-in editor from opening.<br>field (FormFieldInfo) references the target. |
| formFieldSelect | The designer highlights a field as the active selection. | formFieldSelectArgs | field (FormFieldInfo) for the selected item.<br>isProgrammaticSelection (bool) indicates API-driven selection.<br>pageIndex (number) shows the page hosting the field. |
| formFieldUnselect | A previously selected item loses focus/selection. | formFieldUnselectArgs | field (FormFieldInfo) for the item being cleared.<br>pageIndex (number) identifies the page. |
| formFieldResize | Drag handles resize a field. | formFieldResizeArgs | field (FormFieldInfo) for context.<br>newBounds (PdfBounds) capture the latest position/size.<br>oldBounds (PdfBounds) store the prior rectangle.<br>pageIndex (number) indicates which page was edited. |
| formFieldMove | A field gets dragged to a different location. | formFieldMoveArgs | field (FormFieldInfo) is the moved object.<br>newPosition (PdfPoint) is the updated origin.<br>oldPosition (PdfPoint) is the previous origin.<br>pageIndex (number) marks the page. |
| validateFormFields | Validation fails during download or print (required fields missing, invalid values, etc.). | validateFormFieldsArgs | cancel (bool) cancels the workflow.<br>formField (array) lists the invalid fields.<br>documentName (string) is the file under validation. |
| formFieldFocusOut | A field loses focus after editing. | formFieldFocusOutEventArgs | field (FormFieldInfo) for the element that lost focus.<br>pageIndex (number) indicates its page. |
| formFieldMouseOver | The pointer hovers over a field. | formFieldMouseOverArgs | field (FormFieldInfo) for the hovered element.<br>pageIndex (number) page reference.<br>pageX/pageY (number) coordinates relative to the page.<br>x/y (number) coordinates relative to the viewer container. |
| formFieldMouseLeave | Pointer exits the bounds of a field. | formFieldMouseLeaveArgs | field (FormFieldInfo) for the element just left.<br>pageIndex (number) page reference. |
| formFieldPropertiesChange | Any property change (style, constraint, metadata) is applied. | formFieldPropertiesChangeArgs | changedProperties (array) names of properties that changed.<br>newValue (FormFieldInfo) snapshot after the change.<br>oldValue (FormFieldInfo) snapshot before the change. |
All event names align with the React reference so that cross-platform documentation stays consistent.
---
FormFieldInfo schema
FormFieldInfo describes one form field instance and is returned by most of the events above.
| Property | What it represents | Type |
|---|---|---|
alignment | Horizontal text alignment (see TextAlignment values). | string |
backgroundColor | Hex color string for the field background. | string |
bounds | Field rectangle relative to the PDF page (see PdfBounds). | PdfBounds |
color | Foreground/text color as a hex string. | string |
customData | Arbitrary metadata bag for app-specific data. | object |
fontFamily | Font family name used to render text. | string |
fontSize | Numeric font size. | number |
fontStyle | Font styling flag (see FontStyle table). | string |
id | Unique identifier generated for the field. | string |
isReadOnly | Marks whether the field is locked against edits. | bool |
isRequired | Indicates whether validation requires the field. | bool |
name | Logical field name shown in the designer. | string |
pageIndex | Zero-based page index that hosts the field. | number |
thickness | Border thickness. | number |
tooltipText | Helper text shown as tooltip. | string |
type | Field type enum (see FormFieldType list). | FormFieldType |
value | Current value or text content. | string |
---
PdfBounds structure
PdfBounds captures the rectangle used for movement and resize events.
| Property | Description | Type |
|---|---|---|
x | Left coordinate from the page origin. | number |
y | Top coordinate from the page origin. | number |
width | Width of the field. | number |
height | Height of the field. | number |
---
FormFieldType values
| Type | Meaning |
|---|---|
Textbox | Single-line text entry. |
PasswordField | Masked textbox for sensitive data. |
Checkbox | Boolean toggle box. |
RadioButton | Radio button that belongs to an option group. |
DropdownList | Drop-down list for single selection. |
ListBox | Multi-select or single-select list box. |
SignatureField | Digital signature placeholder. |
InitialField | Initials capture control. |
---
FontStyle values
| Value | Effect |
|---|---|
None | No additional style besides the default weight. |
Bold | Renders text in bold weight. |
Italic | Slants text. |
Underline | Draws an underline beneath the text. |
Strikethrough | Paints a strike through the text baseline. |
---
TextAlignment values
| Value | Effect |
|---|---|
left | Text anchors to the left edge of the field. |
center | Text is centered horizontally. |
right | Text anchors to the right edge. |
justify | Text stretches to fill the width, aligning both edges. |
---
Behavior tips
- UI actions and programmatic calls raise the same events, so a single handler covers both scenarios.
- Property-change notifications are immediate—persist your data store whenever
formFieldPropertiesChangefires. validateFormFieldsonly runs when print/download is initiated, letting you block those flows while keeping editing fluid.- Every supported form field type listed above emits the same events, so you can branch using
args.field.typewhen necessary.