Skip to main content

Overview

The Link plugin provides inline hyperlinks within text blocks. Links are inline elements that can be added to any text content.

Installation

npm install @yoopta/link

Basic Usage

import { useMemo } from 'react';
import YooptaEditor, { createYooptaEditor } from '@yoopta/editor';
import Link from '@yoopta/link';
import Paragraph from '@yoopta/paragraph';

const plugins = [Paragraph, Link];

export default function Editor() {
  const editor = useMemo(() => createYooptaEditor({ plugins, marks: [] }), []);
  return <YooptaEditor editor={editor} onChange={() => {}} />;
}

Features

  • Inline Links: Add links within any text content
  • URL Validation: Automatic URL handling
  • Custom Attributes: Set target, rel, and title attributes
  • Keyboard Shortcuts: Cmd/Ctrl+K to insert/edit links
  • Auto-detection: Paste URLs to automatically create links

Configuration

import Link from '@yoopta/link';

const plugins = [Link];

Options

display
object

Element Props

Commands

Link commands are available via LinkCommands. Insert or update a link at the current selection.
import Link, { LinkCommands } from '@yoopta/link';

LinkCommands.insertLink(editor, {
  slate: slateEditor,
  props: {
    url: 'https://example.com',
    title: 'Example Site',
    target: '_blank',
    rel: 'noopener noreferrer',
  },
});
slate
SlateEditor
required
Slate editor instance for the current block
props.url
string
required
Link URL
props.title
string
Link text (defaults to URL if not provided)
props.target
string
Link target attribute
props.rel
string
Link rel attribute
selection
Location
Custom selection range (optional)
Remove a link and unwrap the text.
import { LinkCommands } from '@yoopta/link';

LinkCommands.deleteLink(editor, {
  slate: slateEditor,
});
slate
SlateEditor
required
Slate editor instance for the current block

buildLinkElements

Build link element structure (used internally).
import { LinkCommands } from '@yoopta/link';

const linkElement = LinkCommands.buildLinkElements(editor, {
  props: {
    url: 'https://example.com',
    title: 'Example',
  },
});

Usage Examples

// Insert link with selected text
const handleAddLink = (url: string) => {
  const slate = Blocks.getBlockSlate(editor, { id: currentBlockId });
  
  LinkCommands.insertLink(editor, {
    slate,
    props: { url },
  });
};

Open in New Tab

LinkCommands.insertLink(editor, {
  slate,
  props: {
    url: 'https://example.com',
    target: '_blank',
    rel: 'noopener noreferrer',
  },
});
// Updates the link at current selection
LinkCommands.insertLink(editor, {
  slate,
  props: {
    url: 'https://new-url.com',
    title: 'Updated Link',
  },
});
const handleRemoveLink = () => {
  const slate = Blocks.getBlockSlate(editor, { id: currentBlockId });
  
  LinkCommands.deleteLink(editor, { slate });
};

Keyboard Shortcuts

  • Cmd/Ctrl+K: Insert or edit link at selection
  • Cmd/Ctrl+Shift+K: Remove link (unlink)
The Link plugin can automatically detect and convert pasted URLs:
// When user pastes a URL, it's automatically wrapped in a link
// "https://example.com" → <a href="https://example.com">https://example.com</a>

Parsers

HTML

  • Deserialize: <a> elements with href, target, rel, and title attributes
  • Serialize: Link element → <a> with all attributes preserved

Markdown

  • Serialize: Link → [title](url) format

Email

  • Serialize: <a> with inline styles for email client compatibility

Working with Slate

Since Link is an inline element, you need to work with the Slate editor instance:
import { Blocks } from '@yoopta/editor';
import { LinkCommands } from '@yoopta/link';

// Get the Slate editor for a block
const slate = Blocks.getBlockSlate(editor, { id: blockId });

// Insert link
LinkCommands.insertLink(editor, {
  slate,
  props: { url: 'https://example.com' },
});

Best Practices

Security

Always use rel="noopener noreferrer" when opening links in new tabs:
LinkCommands.insertLink(editor, {
  slate,
  props: {
    url: externalUrl,
    target: '_blank',
    rel: 'noopener noreferrer', // Prevents security vulnerabilities
  },
});

Accessibility

Provide meaningful link text instead of “click here”:
// Good
LinkCommands.insertLink(editor, {
  slate,
  props: {
    url: 'https://docs.example.com',
    title: 'View documentation',
  },
});

// Avoid
LinkCommands.insertLink(editor, {
  slate,
  props: {
    url: 'https://docs.example.com',
    title: 'click here',
  },
});
  • Mention — User and entity mentions
  • Embed — External embeds
  • Video — Video embeds

Build docs developers (and LLMs) love