External links
ExternalLinkExtension classifies destinations that contain a host and
decorates external ones with controlled classes, relations, and target
behavior.
Install
This extension is bundled with alto/markdown:
composer require alto/markdownConfigure
List the hosts that belong to the application:
<?php
use Alto\Markdown\Extension\ExternalLink\ExternalLinkExtension;
use Alto\Markdown\Extension\ExternalLink\ExternalLinkPolicy;
use Alto\Markdown\Markdown;
$markdown = Markdown::github()->with(
new ExternalLinkExtension(new ExternalLinkPolicy(
internalHosts: ['internal.test'],
)),
);Markdown
See [outside](https://outside.test/docs) and [inside](https://internal.test/docs).HTML
<p>See <a rel="noopener noreferrer" href="https://outside.test/docs">outside</a> and <a href="https://internal.test/docs">inside</a>.</p>
Options
ExternalLinkPolicy controls classification and every added attribute.
| Option | Default | Purpose |
|---|---|---|
internalHosts |
[] |
Hosts classified as internal |
includeSubdomains |
false |
Classify subdomains of internal DNS hosts as internal |
openInNewWindow |
false |
Add target="_blank" to external links |
htmlClass |
'' |
Class added to external links |
nofollow |
ExternalLinkScope::None |
Scope receiving nofollow |
noopener |
ExternalLinkScope::External |
Scope receiving noopener |
noreferrer |
ExternalLinkScope::External |
Scope receiving noreferrer |
Each relation accepts ExternalLinkScope::None, All, Internal, or
External.
Security
The extension classifies links and adds attributes; it does not make a URL safe. Every destination remains subject to the active HTML policy, which filters unsafe schemes and escapes emitted attributes.
noopener and noreferrer apply to external links by default. Keep these
relations enabled when opening external links in a new window.
Behavior
Host comparison is case-insensitive and ignores a trailing dot. Subdomain
matching is disabled unless includeSubdomains is enabled. A sibling domain
such as notexample.com never matches example.com.
Absolute and scheme-relative destinations can contain a host. Relative links, fragments, and email links do not.