# Configure hyperlink behavior

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



Clicking a hyperlink can open SuperDoc's built-in editor, follow the link, or run behavior from your application.

## Try hyperlink activation [#try-hyperlink-activation]

Expand the Editor. Choose an activation behavior, then click **SuperDoc documentation**:

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.

> **Interactive editor: Try hyperlink activation**
>
> Sample: [open the fixture](/fixtures/hyperlinks-sample.docx).
>
> Preset: `hyperlinks`.
>
> Hyperlink behaviors available in the interactive Editor:
>
> - **Default:** SuperDoc opens its built-in hyperlink editor in Editing and Suggesting modes.
> - **Do nothing — `hyperlinks: false`:** activation has no effect.
> - **Custom action — `hyperlinks.onActivate`:** your application renders an action beside the hyperlink.
>
> The fixture contains one real external hyperlink. Changing the behavior recreates the Editor from its current DOCX.
>
> Local DOCX selection: disabled.


Changing the behavior recreates the Editor from its current DOCX. Document edits remain, while the open hyperlink
surface and selection reset.

## Use the mode-aware default [#use-the-mode-aware-default]

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

| Document mode | Default activation                      |
| ------------- | --------------------------------------- |
| Editing       | Open the built-in hyperlink editor.     |
| Suggesting    | Open the built-in hyperlink editor.     |
| Viewing       | Navigate 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` only when every hyperlink activation should do nothing.

## Handle activation in your application [#handle-activation-in-your-application]

Use `hyperlinks.onActivate` when your application needs to route, measure, suppress, or render an action for one
activation. Create `src/hyperlink-activation.ts`:

```ts
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: 'suppress' };

  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](/editor/quickstart):

**Vanilla — `src/main.ts`**

```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', items: { center: ['link'] } },
  },
});

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

```

**React — `src/App.tsx`**

```tsx
import { SuperDocEditor, type SuperDocEditorProps } from '@superdoc/react';
import '@superdoc/react/style.css';
import { handleHyperlinkActivation } from './hyperlink-activation';

const editorConfig = {
  hyperlinks: {
    onActivate: handleHyperlinkActivation,
  },
  ui: {
    toolbar: { items: { center: ['link'] } },
  },
} satisfies Pick<SuperDocEditorProps, 'hyperlinks' | 'ui'>;

export default function App() {
  return <SuperDocEditor document='/sample.docx' hyperlinks={editorConfig.hyperlinks} ui={editorConfig.ui} />;
}

```


Vanilla also needs toolbar and Editor mounts:

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

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

```

Return one of these values:

* `undefined` or `{ type: 'default' }` uses the mode-aware default.
* `{ type: 'suppress' }` stops the activation.
* `{ type: 'render', render }` mounts an application-owned action beside the hyperlink.

The render callback receives an empty positioned `container` and `close()`. Return `destroy()` when the application
adds listeners or mounts a framework root.

## Configure activation [#configure-activation]

Choose the field to see its generated TypeScript signature and copy a focused configuration fragment.

### Behavior

| Field | Type | Default | Status | Summary | API details | Guide |
| --- | --- | --- | --- | --- | --- | --- |
| `onActivate` | `(context: HyperlinkActivationContext) => HyperlinkActivationResult \| null \| undefined` | `undefined` | Optional | Choose what happens when a user activates a hyperlink. | Use SuperDoc's default behavior, suppress this activation, or render a small custom action near the hyperlink. | — |


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. Work started by the handler may continue asynchronously. Call
`await context.getDocumentTarget()` from that work to resolve the exact `HyperlinkTarget` for
`editor.doc.hyperlinks.get()`, `patch()`, or `remove()`. It returns `null` when the activated link cannot be matched.

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 [#choose-the-right-extension-point]

Use `onActivate` for behavior tied to one activation. Use [Custom UI](/editor/custom-ui/overview) for a persistent
toolbar, sidebar, dialog, or complete hyperlink workflow. The handler can open that custom UI.

Use the [Document API hyperlink reference](/document-api/reference/hyperlinks) when code needs to list, create, update,
or remove hyperlinks without a visual interaction.
