Link
The link feature lets you insert hyperlinks into your content and provides a UI to create and edit them. Thanks to the autolink plugin, typed or pasted URLs and email addresses automatically turn into working links.
# Demo
Use the link toolbar button or press Ctrl/Cmd+K to create a new link. Clicking a link opens a contextual toolbar. The toolbar lets you edit existing links or unlink them with a click.
Valletta
The capital city of Malta is the top destination this summer. It’s home to cutting-edge contemporary architecture, baroque masterpieces, delicious local cuisine, and at least 8 months of sun.
It’s also a top destination for filmmakers, so you can take a tour through locations familiar to you from Game of Thrones, Gladiator, Troy, and many more.
This demo presents a limited set of features. Visit the feature-rich editor example to see more in action.
# Typing around links
CKEditor 5 allows for typing both at the inner and outer boundaries of links to make editing easier for the users.
To type inside a link, move the caret to its (start or end) boundary. As long as the link remains highlighted (by default: blue), typing and applying formatting happens within its boundaries:
To type before or after a link, move the caret to its boundary, then press the Arrow key (← or →) away from the link once. The link is no longer highlighted and whatever text you type or formatting you apply will not be inside the link:
# Installation
⚠️ New import paths
Starting with version 42.0.0, we changed the format of import paths. This guide uses the new, shorter format. Refer to the Packages in the legacy setup guide if you use an older version of CKEditor 5.
After installing the editor, add the feature to your plugin list and toolbar configuration:
import { ClassicEditor, AutoLink, Link } from 'ckeditor5';
ClassicEditor
.create( document.querySelector( '#editor' ), {
plugins: [ Link, AutoLink, /* ... */ ],
toolbar: [ 'link', /* ... */ ],
} )
.then( /* ... */ )
.catch( /* ... */ );
# Custom link attributes (decorators)
By default, all links created in the editor have the href="..."
attribute in the editor data. If you want your links to have additional link attributes, link decorators provide an easy way to configure and manage them.
There are two types of link decorators you can use:
- Automatic – They match links against predefined rules and manage their attributes based on the results.
- Manual – They allow users to control link attributes individually using the editor UI.
Link decorators are turned off by default and it takes a proper configuration to enable them in your rich-text editor.
# Demo
In the editor below, all external links get the target="_blank"
and rel="noopener noreferrer"
attributes (automatic decorator). Click a link and edit it to see that you can control the download
attribute of specific links using the switch button in the editing balloon (manual decorator). Take a look at the editor data below (updated live) to see the extra link attributes.
The following code runs this editor. Learn more about the configuration of the feature.
ClassicEditor
.create( document.querySelector( '#editor' ), {
toolbar: {
items: [
'link',
// More toolbar items.
// ...
],
},
link: {
// Automatically add target="_blank" and rel="noopener noreferrer" to all external links.
addTargetToExternalLinks: true,
// Let the users control the "download" attribute of each link.
decorators: [
{
mode: 'manual',
label: 'Downloadable',
attributes: {
download: 'download'
}
}
]
}
} )
.then( /* ... */ )
.catch( /* ... */ );
# Configuration
You can configure decorators through definitions provided in the config.link.decorators
configuration option.
Each decorator definition must have a unique name. For manual decorators, the name also represents the decorator in the document model.
Link decorators work independently of one another and no conflict resolution mechanism exists. For example, configuring the target
attribute using both an automatic and a manual decorator at the same time could end up with quirky results. The same applies if you define more manual or automatic decorators for the same attribute.
# Adding target
and rel
attributes to external links
A common use case for (automatic) link decorators is adding the target="_blank"
and rel="noopener noreferrer"
attributes to all external links in the document. A dedicated config.link.addTargetToExternalLinks
configuration exists for that purpose. When you set this option to true
, all links starting with http://
, https://
, or //
are “decorated” with target
and rel
attributes.
ClassicEditor
.create( document.querySelector( '#editor' ), {
link: {
addTargetToExternalLinks: true
}
// More of the editor's configuration.
// ...
} )
.then( /* ... */ )
.catch( /* ... */ );
Internally, this configuration corresponds to an automatic decorator with the following definition:
ClassicEditor
.create( document.querySelector( '#editor' ), {
link: {
decorators: {
addTargetToExternalLinks: {
mode: 'automatic',
callback: url => /^(https?:)?\/\//.test( url ),
attributes: {
target: '_blank',
rel: 'noopener noreferrer'
}
}
}
}
// More of the editor's configuration.
// ...
} )
.then( /* ... */ )
.catch( /* ... */ );
If you want to leave the decision whether a link should open in a new tab to the users, do not use the config.link.addTargetToExternalLinks
configuration. Define a new manual decorator with the following definition instead:
ClassicEditor
.create( document.querySelector( '#editor' ), {
link: {
decorators: {
openInNewTab: {
mode: 'manual',
label: 'Open in a new tab',
attributes: {
target: '_blank',
rel: 'noopener noreferrer'
}
}
}
}
// More of the editor's configuration.
// ...
} )
.then( /* ... */ )
.catch( /* ... */ );
# Adding default link protocol to external links
A default link protocol can be useful when the user forgets to type the full URL address to an external source or website. Sometimes copying the text, like for example ckeditor.com
, and converting it to a link may cause some issues. As a result, the created link will direct you to yourdomain.com/ckeditor.com
because of the missing protocol. This makes the link relative to the site where it appears.
After you enable the config.link.defaultProtocol
configuration option, the link feature will be able to handle this issue for you. By default, it does not fix the passed link value, but when you set config.link.defaultProtocol
to, for example, http://
, the plugin will add the given protocol to every link that may need it (like ckeditor.com
, example.com
, etc. where [protocol://]example.com
is missing).
See a basic configuration example:
ClassicEditor
.create( document.querySelector( '#editor' ), {
link: {
defaultProtocol: 'http://'
}
// More of the editor's configuration.
// ...
} )
.then( /* ... */ )
.catch( /* ... */ );
With the config.link.defaultProtocol
option enabled, you are still able to link things locally using #
or /
. The protocol will not be added to these links.
When enabled, this feature also provides the email address autodetection feature. When you submit hello@example.com
in your content, the plugin will automatically change it to mailto:hello@example.com
.
# Adding custom protocols in links
By default, a minimal set of protocols is allowed to be used in the links. Any URL with an unrecognized protocol will be changed to ‘#’. You can overwrite the list of protocols by using config.link.allowedProtocols
.
See a configuration example:
ClassicEditor
.create( document.querySelector( '#editor' ), {
link: {
// You can use `s?` suffix like below to allow both `http` and `https` protocols at the same time.
allowedProtocols: [ 'https?', 'tel', 'sms', 'sftp', 'smb', 'slack' ]
}
// More of the editor's configuration.
// ...
} )
.then( /* ... */ )
.catch( /* ... */ );
Please keep in mind that you customize this list at your own risk – adding unsafe protocols like javascript
can lead to serious security vulnerabilities!
# Adding attributes to links based on predefined rules (automatic decorators)
Automatic link decorators match all links in the editor content against a function which decides whether the link should receive some set of attributes, considering the URL (href
) of the link. These decorators work silently and the editor applies them during the data downcast.
For instance, to create an automatic decorator that adds the download="file.pdf"
attribute to all links ending with the ".pdf"
extension, you should add the following definition to config.link.decorators
:
ClassicEditor
.create( document.querySelector( '#editor' ), {
link: {
decorators: {
detectDownloadable: {
mode: 'automatic',
callback: url => url.endsWith( '.pdf' ),
attributes: {
download: 'file.pdf'
}
}
}
}
// More of the editor's configuration.
// ...
} )
.then( /* ... */ )
.catch( /* ... */ );
If you want add the target
and rel
attributes to all external links in your content, we prepared a dedicated configuration for that purpose. Thanks to this, you do not have to define the automatic decorator by yourself.
# Adding attributes to links using the UI (manual decorators)
Manual link decorators are represented in the link editing balloon as switch buttons. The users can use them to control the presence of attributes of a particular link (check out the demo to learn more). Each manual decorator definition has a human-readable label displayed next to the switch button in the link editing balloon. Make sure it is compact and precise for the convenience of the users.
To configure a “Downloadable” switch button in the link editing balloon that adds the download="file"
attribute to the link when turned on, add the following definition to config.link.decorators
:
ClassicEditor
.create( document.querySelector( '#editor' ), {
link: {
decorators: {
toggleDownloadable: {
mode: 'manual',
label: 'Downloadable',
attributes: {
download: 'file'
}
},
openInNewTab: {
mode: 'manual',
label: 'Open in a new tab',
defaultValue: true, // This option will be selected by default.
attributes: {
target: '_blank',
rel: 'noopener noreferrer'
}
}
}
}
// More of the editor's configuration.
// ...
} )
.then( /* ... */ )
.catch( /* ... */ );
# Autolink feature
The AutoLink
feature will automatically turn URLs or email addresses into working links.
To use the autolink function, press Space, Enter, or Shift+Enter after a link.
You can always revert autolinking by the undo feature (Ctrl/Cmd+Z).
Press Space after a link to see the magic of autolinking: https://ckeditor.com/
This feature also works with e-mail addresses: example@example.com
…and IP addresses: http://172.217.18.110
You can use Enter or Shift + Enter to achieve the same result: https://ckeditor.com/
# Common API
The Link
plugin registers the UI button component ('link'
) and the following commands:
- The
'link'
command implemented byLinkCommand
. - The
'unlink'
command implemented byUnlinkCommand
.
You can execute the commands using the editor.execute()
method:
// Applies the link to the selected content.
// When the selection is collapsed, it creates new text wrapped in a link.
editor.execute( 'link', 'http://example.com' );
// If there are decorators configured, the command can set their state.
editor.execute( 'link', 'http://example.com', { linkIsExternal: true } );
// Removes the link from the selection (and all decorators if present).
editor.execute( 'unlink' );
The package provides a plugin for linking images. See the Linking images guide in the Images section.
Links are represented in the model using the linkHref
attribute. Manual link decorators are represented in the model using text attributes corresponding to their names, as configured in config.link.decorators
.
We recommend using the official CKEditor 5 inspector for development and debugging. It will give you tons of useful information about the state of the editor such as internal data structures, selection, commands, and many more.
# Contribute
The source code of the feature is available on GitHub at https://github.com/ckeditor/ckeditor5/tree/master/packages/ckeditor5-link.
Every day, we work hard to keep our documentation complete. Have you spotted outdated information? Is something missing? Please report it via our issue tracker.
With the release of version 42.0.0, we have rewritten much of our documentation to reflect the new import paths and features. We appreciate your feedback to help us ensure its accuracy and completeness.