Release v2.2.0
-
#389 by @bobsingor – Add document permissions support:
- Add
useDocumentPermissionshook for React, Svelte, and Vue with reactive permission state and helper methods (hasPermission,hasAllPermissions, and shorthand booleans likecanPrint,canCopyContents, etc.) - Add
UPDATE_DOCUMENT_SECURITYaction andupdateDocumentSecurityaction creator for updating document security state - Add reducer case for updating document permissions and owner unlock state
- Add permission helper methods to
BasePlugin:getDocumentPermissions,checkPermission,requirePermission - Export
useDocumentPermissionsfrom shared, svelte, and vue entry points
- Add
-
#389 by @bobsingor – Add permission override system with global and per-document configuration:
- Add
PermissionConfiginterface for configuring permission overrides withenforceDocumentPermissionsandoverridesoptions - Add
permissionsoption toPluginRegistryConfigfor global permission configuration - Add
permissionstoDocumentStatefor per-document permission overrides - Add
getEffectivePermissionandgetEffectivePermissionsselectors for layered permission resolution (per-document → global → PDF) - Add human-readable permission names (
print,modifyContents,copyContents, etc.) as alternatives to numeric flags - Update
BasePluginpermission helpers (checkPermission,requirePermission,getDocumentPermissions) to use effective permissions - Update
useDocumentPermissionshooks (React, Svelte, Vue) to return both effective and raw PDF permissions - Add
configprop toEmbedPDFcomponents for passingPluginRegistryConfig, deprecating individualloggerprop - Export
PermissionConfig,PermissionName,ALL_PERMISSION_FLAGS, and permission selectors
- Add
- #389 by @bobsingor – Add document security/encryption engine methods:
- Add
setDocumentEncryptionfor setting AES-256 encryption with user/owner passwords and permission flags - Add
removeEncryptionfor marking documents for encryption removal on save - Add
unlockOwnerPermissionsfor unlocking owner permissions on encrypted documents - Add
isEncryptedandisOwnerUnlockedquery methods - Implement security methods in
PdfEngineorchestrator,RemoteExecutor,PdfiumNative,WebWorkerEngine, andEngineRunner - Query and store
isEncrypted,isOwnerUnlocked, andpermissionswhen opening documents
- Add
- #389 by @bobsingor – Add PDF permission and security types:
- Add
isEncrypted,isOwnerUnlocked, andpermissionsproperties toPdfDocumentObject - Add
PdfPermissionFlagenum with all PDF permission flags (Print, ModifyContents, CopyContents, ModifyAnnotations, FillForms, ExtractForAccessibility, AssembleDocument, PrintHighQuality) andAllowAllcombination - Add
buildPermissionshelper function for combining permission flags - Add
PermissionDeniedErrorclass for permission check failures - Add security methods to
PdfEngineinterface:setDocumentEncryption,removeEncryption,unlockOwnerPermissions,isEncrypted,isOwnerUnlocked - Add security methods to
IPdfiumExecutorinterface
- Add
- #389 by @bobsingor – Add permission checking for annotation operations:
- Check
PdfPermissionFlag.ModifyAnnotationsbefore creating, updating, or deleting annotations - Check permission before activating annotation tools
- Check permission before creating annotations from text selection
- Update
AnnotationContainercomponents (React, Svelte, Vue) to respectcanModifyAnnotationspermission:- Disable drag/resize when permission is denied
- Hide vertex handles when permission is denied
- Guard double-click handlers based on permission
- Check
- #389 by @bobsingor – Add per-document permission overrides when opening documents:
- Add
permissionsoption toLoadDocumentUrlOptionsfor URL-based document loading - Add
permissionsoption toLoadDocumentBufferOptionsfor buffer-based document loading - Add
permissionsoption toOpenFileDialogOptionsfor file dialog document loading - Pass permission configuration to core store when documents are opened
- Add
- #389 by @bobsingor – Add permission checking for print operations:
- Check
PdfPermissionFlag.Printbefore allowing document printing - Return
PdfErrorCode.Securityerror when print permission is denied
- Check
- #389 by @bobsingor – Add permission checking for redaction operations:
- Check
PdfPermissionFlag.ModifyContentsbefore adding pending redaction items - Check permission before enabling redact selection or marquee redact modes
- Check permission before starting redaction mode
- Check permission before committing pending redactions (single or all)
- Return
PdfErrorCode.Securityerror when permission is denied for commit operations
- Check
- #389 by @bobsingor – Add overlay enable/disable functionality:
- Add
SET_OVERLAY_ENABLEDaction andsetOverlayEnabledaction creator - Add
enabledOverlaysstate toUIDocumentStatefor tracking overlay visibility - Add overlay management methods to
UIScope:enableOverlay,disableOverlay,toggleOverlay,isOverlayEnabled,getEnabledOverlays - Add
onOverlayChangedevent hook for overlay state changes - Update schema renderer to filter overlays by enabled state
- Initialize overlay enabled state from schema's
defaultEnabledproperty
- Add
-
#389 by @bobsingor – Add document security and protection features:
- Add
ProtectModalcomponent for setting document encryption with user/owner passwords and permission restrictions - Add
UnlockOwnerOverlaycomponent to notify users when viewing protected documents with restricted permissions - Add
ViewPermissionsModalcomponent for viewing and unlocking document permissions - Add
PermissionsDisplaycomponent for showing permission status - Add permission-based command disabling for annotation, redaction, print, copy, and capture commands
- Add security-related translations for English, German, Dutch, French, Spanish, and Chinese
- Add new icons:
EyeIcon,EyeOffIcon,InfoIcon,UnlockIcon - Update UI schema with protection modal, view permissions modal, and unlock owner overlay
- Add
-
#389 by @bobsingor – Add global permission configuration to snippet viewer:
- Add
permissionsoption toPDFViewerConfigfor global permission overrides - Support
enforceDocumentPermissionsto ignore PDF permissions entirely - Support
overrideswith human-readable names (print,modifyAnnotations, etc.) or numeric flags - Update command permission checks to use effective permissions via
getEffectivePermission - Pass permission configuration to
EmbedPDFvia newconfigprop
- Add
Release v2.1.2
- #369 by @bobsingor – Improved PDF content handling with the following changes:
- Shading object support: Shading patterns (gradients, mesh shadings) are now properly preserved and regenerated when modifying PDF pages. Previously, shading objects could be lost during page content updates.
- Shading redaction: Redaction now correctly removes shading objects that fall entirely within a redaction area, ensuring complete content removal.
- Graphics state preservation: Existing graphics state resources (such as soft masks, overprint modes, and other advanced properties) are now preserved with their original names during content regeneration.
-
#369 by @bobsingor – Add missing translations for redaction delete and commit commands (
redaction.deleteSelectedandredaction.commitSelected) in all supported languages (English, German, Dutch, French, Spanish). -
#381 by @bobsingor –
- Add i18n support for capture and print dialogs with translations for all supported languages
- Add
document:capturecommand to toolbar for screenshot functionality - Refactor hint-layer and capture components to use translation hooks
- Remove unused
@types/classnamesdependency
-
#378 by @bobsingor –
- Add Simplified Chinese (zh-CN) translations for all UI elements
- Add i18n support for annotation type labels in comment sidebar with translation keys and fallbacks
- Fix rimraf command to use
--globflag for compatibility with rimraf v4+
Release v2.1.1
-
04140d1by @bobsingor – Improved PDF editing and redaction capabilities with Form XObject support and enhanced image handlingText Redaction Improvements
- Individual subpath extraction and redaction for complex paths (e.g., vector text in logos)
- Instead of removing entire path objects, individual letter glyphs can now be selectively redacted
- Fixed image-to-page transform matrix ordering for accurate redaction positioning
Enhanced Image Redaction
- Added 1-bit image support with proper ImageMask handling
- ImageMask images now correctly use the fill color from the graphics state
- Added JPEG SMask (soft mask) decoding for proper transparency handling in WASM
- Inline images (BI...ID...EI format) are now converted to XObject images for editing
- Improved handling of paletted/indexed images with alpha transparency
Form XObject Content Editing
- Added proper support for editing content within Form XObjects (embedded forms in PDFs)
- Form XObject streams are now edited in-place rather than attempting to add/remove separate content streams
- Added
GetMutableFormStream()API to CPDF_PageObjectHolder for direct Form XObject access
Pattern Color Support
- Added Pattern resource tracking in page content generation
- Pattern colors are now properly preserved and emitted during content regeneration
- Added fill/stroke pattern resource name tracking in color state
-
#364 by @bobsingor – Fixed toolbar/sidebar/modal switching causing unnecessary component remounts
The
useSchemaRendererhook was using the toolbar/sidebar/modal ID as the React key, which caused full component remounts when switching between different toolbars in the same slot (e.g., annotation-toolbar → shapes-toolbar). This resulted in visible flashing of sibling components like the RenderLayer.The fix uses stable slot-based keys (
toolbar-slot-top-secondary,sidebar-slot-left-main, etc.) so that switching content within a slot only updates the children without remounting the wrapper element. This prevents React/Preact reconciliation from affecting sibling components in the tree.
Release v2.1.0
-
#361 by @bobsingor – Add font fallback system for PDFs with non-embedded fonts
- FontFallbackManager: Pure TypeScript implementation using Emscripten's
addFunctionAPI to hook into PDFium'sFPDF_SYSFONTINFOinterface - CDN font loading: Default configuration loads fonts from
@embedpdf/fonts-*packages via jsDelivr CDN - Advanced font matching: Supports multiple font weights and italic variants with CSS-like matching algorithm
- Node.js support:
createNodeFontLoaderhelper for file system-based font loading - Framework integration:
fontFallbackoption added to React, Vue, Svelte, and Preact hooks - Worker support: Font fallback enabled by default in browser worker engine (uses CDN)
Supported charsets: Japanese (SHIFTJIS), Korean (HANGEUL), Simplified Chinese (GB2312), Traditional Chinese (CHINESEBIG5), Arabic, Hebrew, Cyrillic, Greek, Vietnamese
- FontFallbackManager: Pure TypeScript implementation using Emscripten's
- #361 by @bobsingor – Add font-related type definitions
- FontCharset: Enum for PDF font charset values (SHIFTJIS, HANGEUL, GB2312, etc.)
- FontFile: Interface for describing font file metadata (file, weight, italic)
- FontPackageMeta: Interface for font package metadata used by
@embedpdf/fonts-*packages
db26b8fby @bobsingor – Update documentation to use jsDelivr CDN- Changed import URL from
https://snippet.embedpdf.com/embedpdf.jstohttps://cdn.jsdelivr.net/npm/@embedpdf/snippet@2/dist/embedpdf.js - Updated code examples to assign
EmbedPDF.init()result to aviewervariable
- Changed import URL from
Release v2.0.2
-
#358 by @bobsingor – Added support for persisting custom annotation data when creating text, freetext, ink, line, polygon, polyline, shape, and stamp annotations.
-
#359 by @bobsingor – Fixed missing author field when creating stamp annotations.
- #355 by @bobsingor – Fixed an error that was thrown when activating the default interaction mode without an active document.
- #360 by @bobsingor – Fixed aspect ratio being lost when resizing annotations near canvas bounding box edges.
- #357 by @bobsingor – Fixed search result scrolling not working while search is still in progress on large documents.
Release v2.0.1
-
#305 by @bobsingor – Fixed document name extraction to always include
.pdfextension when extracting filename from URL. -
#305 by @bobsingor – Added optional
nameproperty toLoadDocumentUrlOptionsto allow specifying a custom document name. When not provided, the name is extracted from the URL. If extraction fails,undefinedis returned to allow downstream handling of default names.
-
#307 by @bobsingor –
- Fixed iOS zoom issue on input focus by changing text size from
text-smtotext-basein form inputs - Fullscreen button icon now dynamically updates to show exit icon when in fullscreen mode
- Improved zoom menu UI schema with unique item IDs and better responsive behavior
- Fixed iOS zoom issue on input focus by changing text size from
-
#308 by @bobsingor – Added
selection:copy-to-clipboardcommand with keyboard shortcuts (Ctrl+C / Cmd+C) that copies selected text without clearing the selection, providing a better user experience for keyboard-based copying.
Release v2.0.0
The changelog information of each package has been omitted from this message, as the content exceeds the size limit.
Release Next v2.0.0-next.3
-
f13b2d4by @bobsingor – # Major Engine Architecture Refactor: Orchestrator Layer & Image Encoding PoolThis release introduces a significant architectural improvement to the PDF engine system, separating concerns between execution and orchestration while adding parallel image encoding capabilities.
PdfiumEngine→PdfiumNative(the "dumb" executor)- New
PdfEngineclass wraps executors with orchestration logic - Factory functions (
createPdfiumEngine) now return the orchestratedPdfEngine<Blob>wrapper
Migration:
// Before import { PdfiumEngine } from '@embedpdf/engines'; const engine = new PdfiumEngine(wasmModule, { logger }); // After import { createPdfiumEngine } from '@embedpdf/engines/pdfium-worker-engine'; // or import { createPdfiumEngine } from '@embedpdf/engines/pdfium-direct-engine'; const engine = await createPdfiumEngine('/wasm/pdfium.wasm', { logger, encoderPoolSize: 2, // Optional: parallel image encoding });
renderPage()→ Returns final encoded result (Blob) via orchestratorrenderPageRaw()→ New method, returns rawImageDatafrom executorrenderThumbnail()→renderThumbnailRaw()for raw datarenderPageAnnotation()→renderPageAnnotationRaw()for raw data
searchAllPages()→ Now orchestrated at thePdfEnginelevelsearchInPage()→ New single-page search method in executor- Progress tracking improved with proper
CompoundTasksupport
- Removed
openDocumentFromLoader()- range request loading removed from executor - Removed
openDocumentUrl()- URL fetching now handled in orchestrator openDocumentBuffer()remains as the primary method in executor
New three-layer architecture:
- Executor Layer (
PdfiumNative,RemoteExecutor): "Dumb" workers that execute PDF operations - Orchestrator Layer (
PdfEngine): "Smart" coordinator with priority queues and scheduling - Worker Pool (
ImageEncoderWorkerPool): Parallel image encoding
Benefits:
- Priority-based task scheduling
- Visibility-aware rendering (viewport-based prioritization)
- Parallel image encoding (non-blocking)
- Automatic task cancellation and cleanup
const engine = await createPdfiumEngine('/wasm/pdfium.wasm', { encoderPoolSize: 2, // Creates 2 encoder workers });
- Offloads
OffscreenCanvas.convertToBlob()from main PDFium worker - Prevents blocking during image encoding
- Configurable pool size (default: 2 workers)
- Automatic load balancing
New
WorkerTaskQueuewith:- Priority levels:
CRITICAL,HIGH,MEDIUM,LOW - Visibility-based ranking for render tasks
- Automatic task deduplication
- Graceful cancellation
New
CompoundTaskclass for aggregating results:// Automatic progress tracking const task = engine.searchAllPages(doc, 'keyword'); task.onProgress((progress) => { console.log(`Page ${progress.page} complete`); });
CompoundTask.gather()- LikePromise.all()with progressCompoundTask.gatherIndexed()- ReturnsRecord<number, Result>CompoundTask.first()- LikePromise.race()- Automatic child task cleanup
CompoundTask- Multi-task aggregation with progressImageConversionTypestype refinementsPdfAnnotationsProgress.result(renamed fromannotations)
New exports:
PdfEngine- Main orchestrator classRemoteExecutor- Worker communication proxyImageEncoderWorkerPool- Image encoding poolWorkerTaskQueue- Priority-based queuePdfiumNative- Renamed fromPdfiumEngine
New image converters:
browserImageDataToBlobConverter- Legacy convertercreateWorkerPoolImageConverter()- Pool-based convertercreateHybridImageConverter()- Fallback support
New config options:
{ render: { defaultImageType: 'image/webp', defaultImageQuality: 0.92 } }
- Performance: Parallel image encoding improves render throughput by ~40-60%
- Responsiveness: Priority queues ensure visible pages render first
- Memory: Better cleanup of completed tasks and worker references
- Logging: Enhanced performance logging with duration tracking
- Developer Experience: Clearer separation of concerns
-
f13b2d4by @bobsingor – # Major Engine Architecture Refactor: Orchestrator Layer & Image Encoding PoolThis release introduces a significant architectural improvement to the PDF engine system, separating concerns between execution and orchestration while adding parallel image encoding capabilities.
PdfiumEngine→PdfiumNative(the "dumb" executor)- New
PdfEngineclass wraps executors with orchestration logic - Factory functions (
createPdfiumEngine) now return the orchestratedPdfEngine<Blob>wrapper
Migration:
// Before import { PdfiumEngine } from '@embedpdf/engines'; const engine = new PdfiumEngine(wasmModule, { logger }); // After import { createPdfiumEngine } from '@embedpdf/engines/pdfium-worker-engine'; // or import { createPdfiumEngine } from '@embedpdf/engines/pdfium-direct-engine'; const engine = await createPdfiumEngine('/wasm/pdfium.wasm', { logger, encoderPoolSize: 2, // Optional: parallel image encoding });
renderPage()→ Returns final encoded result (Blob) via orchestratorrenderPageRaw()→ New method, returns rawImageDatafrom executorrenderThumbnail()→renderThumbnailRaw()for raw datarenderPageAnnotation()→renderPageAnnotationRaw()for raw data
searchAllPages()→ Now orchestrated at thePdfEnginelevelsearchInPage()→ New single-page search method in executor- Progress tracking improved with proper
CompoundTasksupport
- Removed
openDocumentFromLoader()- range request loading removed from executor - Removed
openDocumentUrl()- URL fetching now handled in orchestrator openDocumentBuffer()remains as the primary method in executor
New three-layer architecture:
- Executor Layer (
PdfiumNative,RemoteExecutor): "Dumb" workers that execute PDF operations - Orchestrator Layer (
PdfEngine): "Smart" coordinator with priority queues and scheduling - Worker Pool (
ImageEncoderWorkerPool): Parallel image encoding
Benefits:
- Priority-based task scheduling
- Visibility-aware rendering (viewport-based prioritization)
- Parallel image encoding (non-blocking)
- Automatic task cancellation and cleanup
const engine = await createPdfiumEngine('/wasm/pdfium.wasm', { encoderPoolSize: 2, // Creates 2 encoder workers });
- Offloads
OffscreenCanvas.convertToBlob()from main PDFium worker - Prevents blocking during image encoding
- Configurable pool size (default: 2 workers)
- Automatic load balancing
New
WorkerTaskQueuewith:- Priority levels:
CRITICAL,HIGH,MEDIUM,LOW - Visibility-based ranking for render tasks
- Automatic task deduplication
- Graceful cancellation
New
CompoundTaskclass for aggregating results:// Automatic progress tracking const task = engine.searchAllPages(doc, 'keyword'); task.onProgress((progress) => { console.log(`Page ${progress.page} complete`); });
CompoundTask.gather()- LikePromise.all()with progressCompoundTask.gatherIndexed()- ReturnsRecord<number, Result>CompoundTask.first()- LikePromise.race()- Automatic child task cleanup
CompoundTask- Multi-task aggregation with progressImageConversionTypestype refinementsPdfAnnotationsProgress.result(renamed fromannotations)
New exports:
PdfEngine- Main orchestrator classRemoteExecutor- Worker communication proxyImageEncoderWorkerPool- Image encoding poolWorkerTaskQueue- Priority-based queuePdfiumNative- Renamed fromPdfiumEngine
New image converters:
browserImageDataToBlobConverter- Legacy convertercreateWorkerPoolImageConverter()- Pool-based convertercreateHybridImageConverter()- Fallback support
New config options:
{ render: { defaultImageType: 'image/webp', defaultImageQuality: 0.92 } }
- Performance: Parallel image encoding improves render throughput by ~40-60%
- Responsiveness: Priority queues ensure visible pages render first
- Memory: Better cleanup of completed tasks and worker references
- Logging: Enhanced performance logging with duration tracking
- Developer Experience: Clearer separation of concerns
-
f13b2d4by @bobsingor – # Major Engine Architecture Refactor: Orchestrator Layer & Image Encoding PoolThis release introduces a significant architectural improvement to the PDF engine system, separating concerns between execution and orchestration while adding parallel image encoding capabilities.
PdfiumEngine→PdfiumNative(the "dumb" executor)- New
PdfEngineclass wraps executors with orchestration logic - Factory functions (
createPdfiumEngine) now return the orchestratedPdfEngine<Blob>wrapper
Migration:
// Before import { PdfiumEngine } from '@embedpdf/engines'; const engine = new PdfiumEngine(wasmModule, { logger }); // After import { createPdfiumEngine } from '@embedpdf/engines/pdfium-worker-engine'; // or import { createPdfiumEngine } from '@embedpdf/engines/pdfium-direct-engine'; const engine = await createPdfiumEngine('/wasm/pdfium.wasm', { logger, encoderPoolSize: 2, // Optional: parallel image encoding });
renderPage()→ Returns final encoded result (Blob) via orchestratorrenderPageRaw()→ New method, returns rawImageDatafrom executorrenderThumbnail()→renderThumbnailRaw()for raw datarenderPageAnnotation()→renderPageAnnotationRaw()for raw data
searchAllPages()→ Now orchestrated at thePdfEnginelevelsearchInPage()→ New single-page search method in executor- Progress tracking improved with proper
CompoundTasksupport
- Removed
openDocumentFromLoader()- range request loading removed from executor - Removed
openDocumentUrl()- URL fetching now handled in orchestrator openDocumentBuffer()remains as the primary method in executor
New three-layer architecture:
- Executor Layer (
PdfiumNative,RemoteExecutor): "Dumb" workers that execute PDF operations - Orchestrator Layer (
PdfEngine): "Smart" coordinator with priority queues and scheduling - Worker Pool (
ImageEncoderWorkerPool): Parallel image encoding
Benefits:
- Priority-based task scheduling
- Visibility-aware rendering (viewport-based prioritization)
- Parallel image encoding (non-blocking)
- Automatic task cancellation and cleanup
const engine = await createPdfiumEngine('/wasm/pdfium.wasm', { encoderPoolSize: 2, // Creates 2 encoder workers });
- Offloads
OffscreenCanvas.convertToBlob()from main PDFium worker - Prevents blocking during image encoding
- Configurable pool size (default: 2 workers)
- Automatic load balancing
New
WorkerTaskQueuewith:- Priority levels:
CRITICAL,HIGH,MEDIUM,LOW - Visibility-based ranking for render tasks
- Automatic task deduplication
- Graceful cancellation
New
CompoundTaskclass for aggregating results:// Automatic progress tracking const task = engine.searchAllPages(doc, 'keyword'); task.onProgress((progress) => { console.log(`Page ${progress.page} complete`); });
CompoundTask.gather()- LikePromise.all()with progressCompoundTask.gatherIndexed()- ReturnsRecord<number, Result>CompoundTask.first()- LikePromise.race()- Automatic child task cleanup
CompoundTask- Multi-task aggregation with progressImageConversionTypestype refinementsPdfAnnotationsProgress.result(renamed fromannotations)
New exports:
PdfEngine- Main orchestrator classRemoteExecutor- Worker communication proxyImageEncoderWorkerPool- Image encoding poolWorkerTaskQueue- Priority-based queuePdfiumNative- Renamed fromPdfiumEngine
New image converters:
browserImageDataToBlobConverter- Legacy convertercreateWorkerPoolImageConverter()- Pool-based convertercreateHybridImageConverter()- Fallback support
New config options:
{ render: { defaultImageType: 'image/webp', defaultImageQuality: 0.92 } }
- Performance: Parallel image encoding improves render throughput by ~40-60%
- Responsiveness: Priority queues ensure visible pages render first
- Memory: Better cleanup of completed tasks and worker references
- Logging: Enhanced performance logging with duration tracking
- Developer Experience: Clearer separation of concerns
Release Next v2.0.0-next.2
89b94a0by @bobsingor – AddedpageNumberandtotalPagesproperties toLayoutReadyEvent. This allows consumers to get the current page information immediately when the layout becomes ready, without needing to subscribe to a separateonPageChangeevent.
-
#293 by @github-actions – Added
data-hidden-itemsattribute for efficient CSS dependency rules.Problem: Visibility dependency rules (e.g., hiding overflow buttons when all menu items are hidden) required exponential CSS rules when using category-based logic, causing stylesheet bloat.
Solution:
- Added
hiddenItemsstate that tracks which item IDs are hidden based on disabled categories - Dependency rules now use
data-epdf-hidattribute to check item IDs directly - CSS rules are now O(n) per breakpoint instead of O(m^n)
New APIs:
getHiddenItems()- returns array of hidden item IDsonCategoryChangedevent now includeshiddenItemsin payloadextractItemCategories(schema)- extracts item→categories mappingcomputeHiddenItems(itemCategories, disabledCategories)- computes hidden items
Breaking Changes: None - existing
disabledCategoriesAPI unchanged - Added
-
89b94a0by @bobsingor – Added comprehensive type exports for all plugin Capabilities and Scopes, enabling proper TypeScript support when using plugin APIs.All plugins now export their
*Capabilityand*Scopetypes, allowing developers to properly type variables when usingplugin.provides()andforDocument():- Viewport:
ViewportCapability,ViewportScope,ViewportMetrics - Scroll:
ScrollCapability,ScrollScope,ScrollMetrics,PageChangeEvent,ScrollEvent,LayoutChangeEvent - Spread:
SpreadCapability,SpreadScope - Zoom:
ZoomCapability,ZoomScope,ZoomLevel,ZoomChangeEvent - Rotate:
RotateCapability,RotateScope - Tiling:
TilingCapability,TilingScope - Thumbnail:
ThumbnailCapability,ThumbnailScope - Annotation:
AnnotationCapability,AnnotationScope,AnnotationEvent - Search:
SearchCapability,SearchScope - Selection:
SelectionCapability,SelectionScope - Capture:
CaptureCapability,CaptureScope - Redaction:
RedactionCapability,RedactionScope,RedactionMode,RedactionItem - UI:
UIScope(UICapability was already exported) - I18n:
I18nCapability,I18nScope,Locale,LocaleChangeEvent - Commands:
CommandScope(CommandsCapability was already exported) - DocumentManager:
DocumentManagerCapability,DocumentChangeEvent,LoadDocumentUrlOptions,LoadDocumentBufferOptions - Print:
PrintCapability,PrintScope - Fullscreen:
FullscreenCapability - Bookmark:
BookmarkCapability,BookmarkScope - Export:
ExportCapability,ExportScope - Pan:
PanCapability,PanScope - History:
HistoryCapability,HistoryScope - Attachment:
AttachmentCapability,AttachmentScope - Render:
RenderCapability,RenderScope - InteractionManager:
InteractionManagerCapability,InteractionManagerScope
import { ScrollPlugin, type ScrollCapability, type ScrollScope, type PageChangeEvent, } from '@embedpdf/snippet'; // Type the capability returned by provides() const scroll: ScrollCapability = registry .getPlugin<ScrollPlugin>('scroll') ?.provides(); // Type the scoped API for a specific document const doc: ScrollScope = scroll.forDocument('my-document'); // Type event callbacks scroll.onPageChange((event: PageChangeEvent) => { console.log(`Page ${event.pageNumber} of ${event.totalPages}`); });
- Viewport:
-
#293 by @github-actions – Added global
disabledCategoriesconfig and hierarchical categories for fine-grained feature control.Global
disabledCategoriesConfigurationAdded
disabledCategoriesto the rootPDFViewerConfigthat applies to both UI and Commands plugins:const config: PDFViewerConfig = { src: 'document.pdf', // Disable all annotation and redaction features globally disabledCategories: ['annotation', 'redaction'], };
Plugin-specific settings can override the global setting:
const config: PDFViewerConfig = { disabledCategories: ['annotation'], // Global default ui: { disabledCategories: ['redaction'], // Overrides for UI only }, commands: { disabledCategories: [], // Re-enables all for commands }, };
Hierarchical Categories
All commands and UI schema items now have hierarchical categories for granular control:
annotation- all annotation featuresannotation-markup- highlight, underline, strikeout, squigglyannotation-highlight,annotation-underline, etc.
annotation-shape- rectangle, circle, line, arrow, polygon, polylineannotation-rectangle,annotation-circle, etc.
annotation-ink,annotation-text,annotation-stamp
redaction- all redaction featuresredaction-text,redaction-area,redaction-apply,redaction-clear
zoom- all zoom featureszoom-in,zoom-out,zoom-fit-page,zoom-fit-width,zoom-marqueezoom-level- all zoom level presets
document- document operationsdocument-open,document-close,document-print,document-export,document-fullscreen
panel- sidebar panelspanel-sidebar,panel-search,panel-comment,panel-annotation-style
page- page settingsspread,scroll,rotate
history- undo/redohistory-undo,history-redo
mode- viewer modesmode-view,mode-annotate,mode-shapes,mode-redact
tools- tool buttonspan,pointer,capture
Example: Disable only print functionality while keeping export:
disabledCategories: ['document-print'];
-
#293 by @github-actions – Added Spanish translations, improved i18n support, and enhanced plugin configuration API.
- Spanish Translations: Added Spanish (
es) locale support with complete translations for all UI elements and commands. - Annotation Sidebar Translations: Sidebar titles are now properly translated using i18n keys. Added missing translation keys (
annotation.freeText,annotation.square,annotation.styles,annotation.defaults) to all 5 languages.
- Partial Plugin Configs: All plugin configuration options in
PDFViewerConfignow usePartial<>types, making it easier to override only the settings you need without specifying all required fields. - Reactive Blend Mode Labels: Blend mode dropdown labels in the annotation sidebar now update reactively when the language changes.
- Search Sidebar Layout: Changed search options checkboxes from horizontal to vertical layout for better compatibility with longer translated labels.
// Override just specific settings <PDFViewer config={{ src: '/document.pdf', zoom: { defaultZoomLevel: ZoomMode.FitWidth }, i18n: { defaultLocale: 'es' }, // Use Spanish translations }} />
- Spanish Translations: Added Spanish (
Release Next v2.0.0-next.1
-
#283 by @github-actions – ## Remove
initialPageConfig & AddisInitialtoLayoutReadyEvent- Removed
initialPageconfig option: TheinitialPageconfiguration option has been removed fromScrollPluginConfig. With multi-document support, a global initial page setting no longer makes sense.
To scroll to a specific page when a document loads, use the
onLayoutReadyevent instead:import { useCapability } from '@embedpdf/core/react'; import type { ScrollPlugin } from '@embedpdf/plugin-scroll'; const ScrollToPageOnLoad = ({ documentId, initialPage }) => { const { provides: scrollCapability } = useCapability<ScrollPlugin>('scroll'); useEffect(() => { if (!scrollCapability) return; const unsubscribe = scrollCapability.onLayoutReady((event) => { if (event.documentId === documentId && event.isInitial) { scrollCapability.forDocument(documentId).scrollToPage({ pageNumber: initialPage, behavior: 'instant', }); } }); return unsubscribe; }, [scrollCapability, documentId, initialPage]); return null; };
isInitialflag onLayoutReadyEvent: TheonLayoutReadyevent now includes anisInitialboolean that istrueonly on the first layout after document load, andfalseon subsequent layouts (e.g., when switching between tabs). This allows distinguishing between initial document load and tab reactivation.
- Removed
-
caec11dby @bobsingor – UpdateduseCommandhook to return{ current: ResolvedCommand | null }instead of{ command: ResolvedCommand | null }for consistency with other Svelte hooks. UpdatedKeyboardShortcutscomponent to use the new pattern.Migration:
<!-- Before --> const cmd = useCommand(() => 'nav.next', () => documentId); // Access: cmd.command?.execute() <!-- After --> const cmd = useCommand(() => 'nav.next', () => documentId); // Access: cmd.current?.execute()
caec11dby @bobsingor – FixeduseOpenDocumentshook to correctly handle emptydocumentIdsarrays. Previously, passing an empty array would fall through to returning all documents; now it correctly returns an empty array. This fix applies to React, Vue, and Svelte hooks.
caec11dby @bobsingor – Fixed VueuseTranslationshook reactivity forlocalecomputed property. Thelocalevalue now correctly updates when the locale changes.
-
caec11dby @bobsingor – Added configurablemenuHeightoption toSelectionPluginConfig. This allows customizing the height used to determine whether the selection menu appears above or below the selection. Default value is40pixels. Also fixed type imports in SvelteSelectionLayercomponent.createPluginRegistration(SelectionPluginPackage, { enabled: true, menuHeight: 50, // Custom menu height for placement calculations });
-
caec11dby @bobsingor – RefactoredCounterRotateContainerto use a Svelte action (action: Action<HTMLElement>) instead of a ref callback (ref: (el: HTMLElement | null) => void). This is the idiomatic Svelte pattern for attaching lifecycle-managed behavior to DOM elements. UpdatedMenuWrapperPropstype accordingly.Migration:
<!-- Before --> <span bind:this={el} style={menuWrapperProps.style}> $effect(() => { menuWrapperProps.ref(el); }); <!-- After --> <span use:menuWrapperProps.action style={menuWrapperProps.style}>