DocsReactUnderstanding Plugins

Understanding Plugins

Plugins are the heart of EmbedPDF’s headless architecture. They are modular packages that add specific features and capabilities to your core viewer. This à la carte approach ensures your application remains lean, loading only the functionality you actually need.

Think of the <EmbedPDF> component as a smartphone: it’s powerful on its own, but it’s the apps (plugins) you install that give it new features like navigation, social media, or games.

How Plugins Work

Adding a new feature to your viewer follows a simple three-step process:

1. Install the Plugin Package

Each plugin is its own NPM package. For example, to add zooming capabilities, you would install the zoom plugin:

npm install @embedpdf/plugin-zoom

2. Register the Plugin

Next, you import the plugin’s ...PluginPackage and register it in the plugins array that you pass to the <EmbedPDF> component. This is done using the createPluginRegistration helper function.

PDFViewer.tsx
import { createPluginRegistration } from '@embedpdf/core'; import { EmbedPDF } from '@embedpdf/core/react'; // ... other imports import { DocumentManagerPluginPackage } from '@embedpdf/plugin-document-manager/react'; import { ZoomPluginPackage, ZoomMode } from '@embedpdf/plugin-zoom/react'; const plugins = [ // ... other essential plugins like DocumentManager, Viewport, etc. createPluginRegistration(DocumentManagerPluginPackage, { initialDocuments: [{ url: 'https://snippet.embedpdf.com/ebook.pdf' }], }), createPluginRegistration(ViewportPluginPackage), createPluginRegistration(ScrollPluginPackage), createPluginRegistration(RenderPluginPackage), // Add the zoom plugin to the array createPluginRegistration(ZoomPluginPackage, { defaultZoomLevel: ZoomMode.FitPage, // You can pass options here! }), ]; // ... rest of your component

Registering the plugin activates its core logic and makes its features available to the rest of your application.

3. Use the Plugin’s Components and Hooks

Once a plugin is registered, you can use its associated React components and hooks to build your UI. For example, the zoom plugin provides a <MarqueeZoom /> component for drag-to-zoom functionality and a useZoom hook to control zoom levels from a toolbar.

Since EmbedPDF supports multiple documents, hooks and components require a documentId parameter to know which document they’re working with. You’ll get the activeDocumentId from the <EmbedPDF> component’s children function.

ZoomToolbar.tsx
import { useZoom } from '@embedpdf/plugin-zoom/react'; interface ZoomToolbarProps { documentId: string; } export const ZoomToolbar = ({ documentId }: ZoomToolbarProps) => { const { provides: zoomProvides, state: zoomState } = useZoom(documentId); if (!zoomProvides) { return null; } return ( <div> <span>Current Zoom: {Math.round(zoomState.currentZoomLevel * 100)}%</span> <button onClick={zoomProvides.zoomOut}>-</button> <button onClick={zoomProvides.zoomIn}>+</button> <button onClick={() => zoomProvides.requestZoom(1.0)}>Reset</button> </div> ); };

This clear separation of logic (the plugin) from the view (your components) gives you complete control over your UI.

4. Add the Component to Your Viewer

Finally, import and place your new <ZoomToolbar /> component inside the <EmbedPDF> provider. This is essential, as it allows the useZoom hook to access the context provided by the ZoomPluginPackage.

Since we’re working with multiple documents, you’ll need to:

  1. Get the activeDocumentId from the <EmbedPDF> children function
  2. Use <DocumentContent> to ensure the document is loaded before rendering
  3. Pass the documentId to all components and hooks that need it
PDFViewer.tsx
import { EmbedPDF } from '@embedpdf/core/react'; // ... other imports import { DocumentContent } from '@embedpdf/plugin-document-manager/react'; import { Viewport } from '@embedpdf/plugin-viewport/react'; import { Scroller } from '@embedpdf/plugin-scroll/react'; import { RenderLayer } from '@embedpdf/plugin-render/react'; import { ZoomToolbar } from './ZoomToolbar'; // 1. Import the toolbar // ... plugins array and PDFViewer component setup export const PDFViewer = () => { // ... return ( <div style={{ height: '500px', border: '1px solid black', display: 'flex', flexDirection: 'column' }}> <EmbedPDF engine={engine} plugins={plugins}> {({ activeDocumentId }) => activeDocumentId && ( <DocumentContent documentId={activeDocumentId}> {({ isLoaded }) => isLoaded && ( <div style={{display: 'flex', height: '100%', flexDirection: 'column'}}> <ZoomToolbar documentId={activeDocumentId} /> {/* 2. Add the component here with documentId */} <div style={{ flex: 1, overflow: 'hidden' }}> <Viewport documentId={activeDocumentId}> <Scroller documentId={activeDocumentId} renderPage={({ width, height, pageIndex }) => ( <div style={{ width, height }}> <RenderLayer documentId={activeDocumentId} pageIndex={pageIndex} /> </div> )} /> </Viewport> </div> </div> ) } </DocumentContent> ) } </EmbedPDF> </div> ); };

5. Live Demo

This is the result of the code above—a fully functional PDF viewer with zoom controls that you built from the ground up.

Loading PDF Engine...

Types of Plugin Features

Plugins can provide several types of tools:

  • Core Logic: Some plugins work entirely in the background to manage state (e.g., ScrollPluginPackage).
  • React Components: Most plugins offer functional components that you place in your viewer to add UI features (e.g., <RenderLayer />, <SelectionLayer />, <MarqueeZoom />).
  • React Hooks: Functions like useZoom(documentId) or useSearch(documentId) allow your custom components to access plugin data and trigger actions. Since EmbedPDF supports multiple documents, these hooks require a documentId parameter.

By combining plugins, you can compose a feature-rich PDF experience that is perfectly tailored to your application’s design and needs.

Last updated on December 5, 2025

Need Help?

Join our community for support, discussions, and to contribute to EmbedPDF's development.