Built-in UI

Configure hyperlink behavior

Keep SuperDoc's defaults, suppress activation, or handle one hyperlink activation in your application.

By default, SuperDoc opens the built-in editor when a hyperlink can be edited and follows the link when it cannot. Configure activation only when your application needs different behavior.

Expand the Editor, then click SuperDoc documentation after each change:

  1. Default opens the built-in hyperlink editor in Editing mode.
  2. Do nothing suppresses activation.
  3. Custom action renders an action from your application beside the hyperlink.
Try hyperlink activationClick the hyperlink to try the selected activation behavior.
Loading…
Activation

The hyperlinks editor is loading.

Changing the behavior reloads the current DOCX because hyperlinks is a startup option. Document edits remain; the open hyperlink surface and selection reset.

Keep the mode-aware default

Omit hyperlinks when SuperDoc should choose the behavior from the document mode:

Document modeDefault activation
EditingOpen the built-in hyperlink editor.
SuggestingOpen the built-in hyperlink editor.
ViewingNavigate to the URL or document anchor.

Links outside editable text, such as linked images and links in headers or footers, navigate in every mode.

Set hyperlinks: false when activation should do nothing in every mode.

Render a custom action

Use hyperlinks.onActivate when your application should decide what happens for one activation. Create src/hyperlink-activation.ts with a small DOM surface for open and close actions:

import type { HyperlinkActivationHandler } from 'superdoc';

const SAFE_PROTOCOLS = new Set(['http:', 'https:', 'mailto:', 'tel:']);
const HAS_PROTOCOL = /^[a-z][a-z0-9+.-]*:/i;

function getSafeHref(rawHref: string) {
  const href = rawHref.trim();
  if (!href) return null;
  if (href.startsWith('#')) return href;

  const candidate = HAS_PROTOCOL.test(href) ? href : `https://${href}`;

  try {
    return SAFE_PROTOCOLS.has(new URL(candidate).protocol) ? candidate : null;
  } catch {
    return null;
  }
}

export const handleHyperlinkActivation: HyperlinkActivationHandler = ({ href }) => {
  const safeHref = getSafeHref(href);
  if (!safeHref) return { type: 'none' };

  return {
    type: 'render',
    render: ({ container, close }) => {
      const panel = document.createElement('div');
      const link = document.createElement('a');
      const closeButton = document.createElement('button');

      link.href = safeHref;
      link.target = '_blank';
      link.rel = 'noopener noreferrer';
      link.textContent = 'Open hyperlink';

      closeButton.type = 'button';
      closeButton.textContent = 'Close';
      closeButton.addEventListener('click', close);

      panel.append(link, closeButton);
      container.append(panel);

      return {
        destroy() {
          closeButton.removeEventListener('click', close);
          panel.remove();
        },
      };
    },
  };
};

Add the handler to the /sample.docx project from the Quickstart:

src/main.ts
import { SuperDoc } from 'superdoc';
import 'superdoc/style.css';
import { handleHyperlinkActivation } from './hyperlink-activation';

const superdoc = new SuperDoc({
  selector: '#editor',
  document: '/sample.docx',
  hyperlinks: {
    onActivate: handleHyperlinkActivation,
  },
  ui: {
    toolbar: { container: '#toolbar', groups: { center: ['link'] } },
  },
});

window.addEventListener('beforeunload', () => superdoc.destroy());

Vanilla also needs separate toolbar and Editor mounts:

<div id="toolbar"></div>
<div id="editor"></div>

<script type="module" src="/src/main.ts"></script>

Return { type: 'default' } to use SuperDoc's default for that activation or { type: 'none' } to suppress it. The render callback receives an empty positioned container and a close() function. Return destroy() when the application adds listeners or mounts a framework root.

The context includes the href, current documentMode, and defaultAction. The default action is edit when SuperDoc can edit the link and navigate otherwise.

onActivate must return synchronously. Code it starts may continue asynchronously. From that code, call await context.getDocumentTarget() to get the exact HyperlinkTarget to pass as target to editor.doc.hyperlinks.get(), patch(), or remove(). It returns null when SuperDoc cannot match the activated link to a Document API hyperlink.

If onActivate throws, returns a Promise, returns an invalid result, or its render callback throws, SuperDoc suppresses the activation and reports the failure through onException.

Choose the right extension point

Use onActivate for work tied to one activation: analytics, application routing, suppression, or a small anchored action. Use Custom UI for a persistent toolbar, sidebar, or dialog and for complete insert, edit, and remove workflows. An onActivate handler can open that custom UI.

Use the Document API hyperlink reference when code needs to list, create, update, or remove hyperlinks without a visual interaction.

On this page