
The Velt Apryse WebViewer integration is documented for React. This guide covers the React integration only.
Setup
Step 1: Add Comment components
- Add the
Velt Commentscomponent to the root of your app. - This component is required to render comments in your app.
- Set the
text modeprop tofalseto hide the default text comment tool.
- React / Next.js
Step 2: Install the Velt Apryse package
@veltdev/apryse-velt-comments lists @pdftron/webviewer as a peer dependency — install it yourself (the package won’t bring its own copy, to avoid running two WebViewer runtimes in the same browser):
node_modules/@pdftron/webviewer/public/. The browser loads these at runtime over HTTP from a URL on your site (the path option you pass to WebViewer(...)), not via a JS import. Your bundler won’t pick them up on its own, so you need to copy them into your app’s static folder so the browser can fetch them.
Most teams automate this with a postinstall script:
package.json:
public/lib/webviewer/core/ (WASM + PDF/Office engines) and public/lib/webviewer/ui/ (WebViewer UI shell) — which is exactly what the path: 'lib/webviewer' option in WebViewer(...) (see Step 3) points to.
Step 3: Create an Apryse WebViewer component with Velt Comments
- Attach the extension to the WebViewer instance once it’s created. The instance is then the handle that every
addComment/renderCommentscall uses. @pdftron/webviewertouches the DOM, so import it dynamically (only in the browser) to stay SSR-safe in Next.js, Remix, etc.
- React / Next.js
Step 4: Add a comment button to your WebViewer
- Add a button that users can click to add comments after selecting text in the document.
- Unlike DOM-based editors, Apryse selections live in the WebViewer’s canvas — clicking a button in the host page does not clear the selection, so no
onMouseDown/preventDefaultdance is needed. Just calladdComment({ instance }).
- React / Next.js
Step 5: Call addComment to add a comment
- Call this method to add a comment to the currently selected text in the WebViewer. You can use this when the user clicks on the comment button or presses a keyboard shortcut.
- Params:
AddCommentArgs. It has the following properties:instance: The ApryseWebViewerInstancereturned byWebViewer(...).
- Returns:
AddCommentResultornull. Resolves tonullif no text is selected or the Velt SDK is not yet loaded. On success it returns:veltAnnotationId: The Velt annotation id assigned by the SDK.textEditorConfig: The durable logical anchor stored on the annotation ({ editorId, text, pageNumber, occurrence }).
- React / Next.js
Step 6: Render comments in the WebViewer
- Use the
useCommentAnnotationshook from@veltdev/reactto get comment data from Velt and render it in the WebViewer. - Params:
RenderCommentsArgs. It has the following properties:instance: The ApryseWebViewerInstance.commentAnnotations: Array of Comment Annotation objects from Velt.
- React / Next.js
Step 7: Clean up when the component unmounts
ApryseVeltComments.configure(...).attach(instance)returns anAttachedExtensionhandle. Calldetach()from your effect cleanup so every Apryse listener and per-instance cache is released.- If you switch documents inside the same WebViewer (e.g. via
instance.UI.loadDocument(...)), you do not need to detach/re-attach — the extension listens for Apryse’sbeforeDocumentLoaded/documentLoadedevents and re-syncs the comment highlights automatically.
- React / Next.js
Step 8: Style the commented text
- Comment highlights are rendered as positioned
<div>elements inside<velt-comment-text>annotation overlays that Apryse manages on each page. - The default styles are set via inline
!importantrules, so to override them target the inner highlight class with a higher-specificity selector or!important.
<velt-comment-text> lives inside the <apryse-webviewer> shadow root, so global CSS automatically reaches it (the browser applies host-page styles into open shadow roots for unknown custom elements).APIs
ApryseVeltComments.configure()
Creates the Velt Comments extension for the Apryse WebViewer. It exposes aconfigure(...).attach(instance) pattern — each .attach() returns a handle whose .detach() undoes everything for that instance.
- Params:
config?:ApryseVeltCommentsConfigeditorId?: string- Unique identifier for this WebViewer instance (for multi-viewer scenarios). Default:'apryse'.
- Returns:
ApryseVeltComments(call.attach(instance)to wire it to a WebViewer, which returns anAttachedExtension)
- React / Next.js
addComment()
Creates a comment annotation for the currently selected text in the WebViewer.- Params:
request:AddCommentArgsinstance: WebViewerInstance
- Returns:
Promise<AddCommentResult| null>
- React / Next.js
renderComments()
Renders and highlights comment annotations in the WebViewer.- Params:
request:RenderCommentsArgsinstance: WebViewerInstancecommentAnnotations:CommentAnnotation[]
- Returns:
void
- React / Next.js

