npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@docs.plus/extension-hyperlink

v2.1.0

Published

Tiptap extension for hyperlinks with built-in popovers, auto-linking, and 50+ URL scheme support

Downloads

1,194

Readme

@docs.plus/extension-hyperlink

Version Downloads License Discord

Tiptap hyperlink mark with optional prebuilt popovers for creating, previewing, and editing links.

It replaces the @tiptap/extension-link mark that StarterKit v3 bundles.

Open in StackBlitz

Why use it

  • Autolink covers more than web URLs. As you type, bare domains get https://, emails become mailto:, and E.164 phones become tel:. App schemes from a catalog of 47, such as whatsapp://, autolink too.
  • The link UI is included. Prebuilt create, preview, and edit popovers ship with the package. Mod-k opens the create-link form with no configuration. @tiptap/extension-link binds no keyboard shortcut.
  • Every boundary checks the scheme. isSafeHref blocks javascript:, data:, vbscript:, file:, and blob: on parse, import, write, serialize, and navigation. An embedded tab or newline cannot hide a scheme from the gate.
  • Your @tiptap/extension-link configuration ports over. isAllowedUri takes the same (uri, ctx) shape as @tiptap/extension-link, so an existing policy works unchanged. setLink, unsetLink, and toggleLink stay as aliases. [label](url) round-trips with @tiptap/markdown.

Install

npm install @docs.plus/extension-hyperlink

Or use pnpm add @docs.plus/extension-hyperlink, yarn add @docs.plus/extension-hyperlink, or bun add @docs.plus/extension-hyperlink.

Requires @tiptap/core ^3.31.3 and @tiptap/pm ^3.31.3 (Tiptap 3.x).

This package imports no React, Vue, or Next.js code. Use it from a plain page, Vite, React, Vue, Svelte, Next.js, Nuxt, or SvelteKit. Create the editor in the browser.

React Native has no DOM. Load the editor in a web view.

Installs two runtime dependencies, @floating-ui/dom and linkifyjs. The popover engine and the tooltip ship inside dist, so they add no third package.

Upgrading from 1.x? Option names, command names, and CSS class names all changed — see Migrating from 1.x.

Quickstart

Open in StackBlitz

Run this Quickstart in your browser first, with nothing to install. The app lives in examples/vanilla.

The host page needs one mount point: <div id="editor"></div>. The snippet also imports @tiptap/starter-kit. Add it with npm install @tiptap/starter-kit when your app has none yet.

import { Editor } from '@tiptap/core'
import StarterKit from '@tiptap/starter-kit'
import {
  Hyperlink,
  createHyperlinkPopover,
  editHyperlinkPopover,
  previewHyperlinkPopover
} from '@docs.plus/extension-hyperlink'
import '@docs.plus/extension-hyperlink/styles.css'

const editor = new Editor({
  element: document.querySelector('#editor'),
  content: '<p>Try <a href="https://example.com">this link</a>.</p>',
  extensions: [
    // Disable StarterKit's bundled link mark — see Caveats.
    StarterKit.configure({ link: false }),
    Hyperlink.configure({
      popovers: {
        previewHyperlink: previewHyperlinkPopover,
        editHyperlink: editHyperlinkPopover,
        createHyperlink: createHyperlinkPopover
      }
    })
  ]
})

The styles.css import is optional. The snippet also styles no document link — see Popovers and Style document links.

You should see a paragraph with one link. Click the link to open the preview popover, with copy, edit, and remove actions. Type example.org and a space, and the text becomes a link. Select a word and press Mod-k (Cmd on macOS, Ctrl elsewhere) to open the create-link form.

Caveats

  • StarterKit.configure({ link: false }) is required, not stylistic. StarterKit v3 bundles @tiptap/extension-link by default. The two marks collide on the setLink / unsetLink / toggleLink command names and on the a[href] parse rule. Your extensions array order then decides each contest, with no warning. If the upstream mark wins, this package's isSafeHref gate never runs on parsed or pasted HTML, and its popovers never attach.
  • A click on a link needs popovers.previewHyperlink. The three openers fall back to the prebuilt factory when a slot is null. The click handler does not: leave previewHyperlink at null and a click on a link opens no popover.
  • linkOnPaste: false does not stop every paste from linking. The linkify paste rule stays registered, so a pasted bare URL still becomes a link. To stop that path too, set shouldAutoLink: () => false, which every autolink path consults.
  • HTMLAttributes.target reaches the DOM. HTMLAttributes: { target: '_blank' } does emit <a target="_blank">. A browser-driven target="_blank" navigation skips the click gate. Leave target at null and let the click handler open the link.

The full list, with the reason for each, is in Caveats.

Common tasks

Set a link from your own button

Every command lands on editor.commands and on editor.chain(). On editor.commands, each returns boolean, and false marks a no-op.

editor.chain().focus().setHyperlink({ href: 'https://example.com' }).run()
editor.getAttributes('hyperlink').href // read the current href

setHyperlink returns false when href is empty, when the composed gate rejects it, or when the schema cannot apply the mark there. See Commands for the full list.

Open the create-link form

Mod-k calls this command. Call it from your own toolbar button too:

editor.commands.openCreateHyperlinkPopover()

openCreateHyperlinkPopover opens UI, so editor.can().openCreateHyperlinkPopover() reports availability without mounting anything. With nothing selected, the prebuilt form inserts the typed URL as its own link text.

Style document links

The styles.css stylesheet skins the popovers only. The mark renders a plain <a> with no class, so style your document links yourself:

Hyperlink.configure({ HTMLAttributes: { class: 'my-link' } })
a.my-link {
  color: #2563eb;
  text-decoration: underline;
}

For theme tokens, dark mode, and class names, see Styling.

Gallery

Prebuilt create, preview, and edit popovers (styles.css + popovers config). Each screenshot has a light and a dark version, and follows your system preference.

Documentation

| Guide | What it covers | | ----------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------- | | API reference | Options, commands, keyboard shortcuts, the full caveats list, server bundles, and TypeScript exports | | Popovers | The three popover slots, factory option shapes, openers, and custom popovers | | Styling | The stylesheet, --hl-* theme tokens, dark mode, and class names | | URL handling | Href normalization, scheme classification, and Markdown round-trip | | Security | The dangerous-scheme gate at each boundary, and the exported safety helpers | | Advanced | The floating-popover primitive, the UI controller, and the tooltip primitive | | Migrating from 1.x | Renamed options, commands, CSS classes, and popover APIs | | Changelog | Every release and its breaking changes | | For AI coding agents | This README as plain Markdown for your agent. The docs are also on Context7 |

Part of docs.plus

This extension is built for and maintained by docs.plus. docs.plus is a free, real-time collaboration tool that lets communities organize knowledge hierarchically, with a chat thread on every heading. docs.plus runs these packages from source in production, so every release is exercised there before it reaches npm.

Contributing

Bug reports and PRs welcome. Setup, test commands, and the playground harness live in CONTRIBUTING.md.

License

MIT — see LICENSE.