Some test text!

Custom appearanceskeyboard_arrow_down

Custom annotation appearances

WebViewer supports adding a PDF object or page as an appearance to any annotation type. This allows an annotation to be displayed in a custom way which overrides the default rendering based on the annotation properties. This custom appearance is also compatible with the PDF specification so after downloading the file the annotation will appear identically in other PDF viewers.

The addCustomAppearance function is defined on all annotations and expects a PDF Document object to be passed in along with an optional page number or PDF object number. The normal annotation appearance will then be overridden by the PDF document's content when the file is downloaded.

  // options
}, document.getElementById('viewer'))
  .then((instance) => {
    const { Annotations, docViewer, CoreControls } = instance;

    docViewer.on('documentLoaded', async () => {
      const rectangle = new Annotations.RectangleAnnotation();
      rectangle.PageNumber = 1;
      rectangle.X = 10;
      rectangle.Y = 150;
      rectangle.Width = 235;
      rectangle.Height = 200;
      rectangle.FillColor = new Annotations.Color(0, 0, 0);

      // note that if you are adding multiple appearances you should make sure they have unique file names
      const doc = await CoreControls.createDocument('', { 
        useDownloader: false,
        filename: 'tiger.pdf' 
      rectangle.addCustomAppearance(doc, { pageNumber: 1 });


Then you can see the rectangle has the appearance of the tiger PDF document.

Appearance after download

Custom appearances with XFDF

If you download the PDF using getFileData then the annotation appearances will be saved with the PDF and visible in other PDF viewers.

However if you save your annotations separately from the PDF as XFDF then you'll need to use the annotManager.setCustomAppearanceHandler API so that the appearance can be reloaded into WebViewer when you import the XFDF. The XFDF only contains a reference to the appearance name and not the entire contents of the PDF file describing the appearance.

  // options
}, document.getElementById('viewer'))
  .then((instance) => {
    const { annotManager, CoreControls } = instance;

    annotManager.setCustomAppearanceHandler(async (filename) => {
      // filename is the name of the appearance

      // this is assuming that you have saved the file referenced by the appearances somewhere on your server with the same filename
      return CoreControls.createDocument(`${filename}`, { useDownloader: false });

    // later call annotManager.importAnnotations or annotManager.importAnnotCommand

Get the answers you need: Support


Free Trial

Get unlimited trial usage of PDFTron SDK to bring accurate, reliable, and fast document processing capabilities to any application or workflow.

Select a platform to get started with your free trial.

Unlimited usage. No email address required.