Weave Code
Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Url Auto Converter Bundle Laravel Package

liip/url-auto-converter-bundle

A Symfony bundle that automatically turns plain URLs in text into clickable HTML links. It provides a Twig filter and configurable URL detection, making it easy to render user-generated content with safe, consistent link markup.

View on GitHub
Deep Wiki
Context7

Getting Started

Treat liip/url-auto-converter-bundle as a legacy reference implementation, not a dependency. It is archived, last released in March 2017, and targets Symfony 2/3, Twig 1, and PHP 5.x/7.x. It will not install cleanly on a modern Laravel or Symfony application, and there will be no security or compatibility fixes. The useful part is its behavior: a Twig filter that turns plain-text URLs and email addresses into HTML anchors.

If you are maintaining a legacy Symfony app that already has it installed, the minimal setup is:

composer require liip/url-auto-converter-bundle

Register the bundle in AppKernel.php (Symfony 2/3 style):

$bundles = [
    // ...
    new Liip\UrlAutoConverterBundle\LiipUrlAutoConverterBundle(),
];

There is typically no application configuration required. The first use case is auto-linking user-generated plain text, such as comments, descriptions, support messages, or notification emails:

{# Twig #}
{{ comment.body|url_auto_converter }}

Where to look first in the repository:

  • The Twig extension class under Twig/ — this defines the filter name and whether output is marked safe.
  • The converter class it delegates to — this contains the URL/email regex and is where most behavior lives.
  • The bundle’s service definition — this shows how the converter is wired and where you can override it.

For a Laravel application, do not try to install the Symfony bundle. Port the idea into a small, tested helper:

<?php

namespace App\Support;

class Autolink
{
    public function convert(?string $text): string
    {
        // Escape first. Everything after this point is trusted markup.
        $safe = e($text ?? '');

        // http/https URLs only. Never allow javascript: or data: schemes.
        $safe = preg_replace(
            '~(?<![\w@])(https?://[^\s<]+)~i',
            '<a href="$1" rel="nofollow noopener noreferrer" target="_blank">$1</a>',
            $safe
        );

        // Email addresses.
        $safe = preg_replace(
            '~(?<![\w.+-])([A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,})~i',
            '<a href="mailto:$1">$1</a>',
            $safe
        );

        return $safe;
    }
}

Then in Blade:

{!! app(\App\Support\Autolink::class)->convert($comment->body) !!}

The key detail is that e() runs before the regex replacement, so user input cannot inject markup. The helper only inserts the anchor tags.

A cleaner Laravel pattern is a small value object implementing Htmlable, which lets Blade’s normal {{ }} syntax produce safe HTML:

use Illuminate\Contracts\Support\Htmlable;

class AutolinkedText implements Htmlable
{
    public function __construct(private string $text) {}

    public function toHtml(): string
    {
        return app(\App\Support\Autolink::class)->convert($this->text);
    }
}
{{ new \App\Support\AutolinkedText($comment->body) }}

Implementation Patterns

Convert at render time, not at storage time. Store the raw comment or message body. Apply auto-linking when rendering the view or email. This keeps the original text intact and lets you change link behavior — nofollow, target="_blank", URL truncation, email obfuscation — without a data migration.

Centralize link options. Day-to-day you will want different behavior for public comments, internal admin notes, and transactional emails. Put the rel, target, CSS class, and maximum display length into one service or config array rather than repeating HTML in templates.

class Autolink
{
    public function __construct(
        private bool $openInNewTab = true,
        private bool $nofollow = true,
    ) {}

    public function convert(?string $text): string
    {
        $rel = $this->nofollow ? 'nofollow noopener noreferrer' : 'noopener';
        $target = $this->openInNewTab ? ' target="_blank"' : '';

        // ... escape, then replace URLs with:
        // <a href="$1" rel="{$rel}"{$target}>$1</a>
    }
}

Compose formatting in a deliberate order. If the content is plain text with newlines, the usual pipeline is: escape → autolink → nl2br. If the content is Markdown, do not chain an autolinker after the Markdown renderer; use the Markdown library’s autolink extension instead, because it understands Markdown link syntax and code fences. Mixing the two produces links inside code blocks and double-converted markup.

Use it in HTML emails. This is one of the more valuable uses: user-submitted text inside notification emails often contains URLs. Ensure the helper produces absolute http:// or https:// links and test the rendered email in a real client, because escaped ampersands and long URLs behave differently in email HTML.

Test with a data provider, not one happy-path example. A useful test set includes:

  • https://example.com
  • http://example.com/path?foo=bar&baz=qux
  • URLs followed by . or ,
  • URLs inside parentheses, e.g. Wikipedia links
  • www.example.com without a scheme
  • [email protected]
  • Unicode/IDN domains
  • <script>alert(1)</script> mixed with a URL
  • A URL containing a quote or angle bracket

If you use Twig in Laravel via TwigBridge, you can re-register a custom extension, but the original bundle’s service wiring is Symfony-specific. It is usually less work to copy the converter logic into a Laravel service than to make the old bundle’s container definitions work.

Gotchas and Tips

The package is archived and deprecated. This is the dominant risk. Do not add it to a new project. If it is already in a legacy app, plan to replace it with a maintained autolinker or a small in-house helper. There will be no fixes for PHP 8 deprecations, Twig 2/3 incompatibilities, or regex edge cases.

Escaping is the main pitfall. The Twig filter may mark its output as HTML-safe. If it does, verify that it escapes the input internally before inserting anchors; otherwise user text can inject markup around a matched URL. If it does not mark output safe, Twig’s autoescaping will escape the generated <a> tags and the links will render as visible text. Whichever path you use, confirm the escape order with a real XSS payload such as http://example.com"><script>alert(1)</script>.

Do not double-escape URL entities. If you escape the whole string first, a URL query string like ?a=1&b=2 becomes ?a=1&amp;b=2. That is correct inside HTML, but running another escaper over the generated anchor can turn it into &amp;amp;. Test query-string URLs specifically. In Laravel, prefer escaping once at the start and never calling e() again on the result.

Trailing punctuation is commonly swallowed. Naive regexes include the final period, comma, semicolon, or closing parenthesis in the href. A practical fix is to capture the URL, trim trailing punctuation, and re-append it outside the anchor:

$url = rtrim($url, '.,;:!?)');

Parentheses are trickier: Wikipedia-style URLs legitimately contain ), so simple rtrim can truncate a valid URL. If that matters, implement balanced-parenthesis handling or accept the limitation and test the specific URLs your application sees.

Only allow http and https schemes. Never build an autolinker that turns arbitrary scheme-like text into a link. javascript:, data:, and vbscript: URLs are injection vectors. The same applies to mailto:: only generate it for strings that actually match your email regex.

www. URLs and bare domains are not handled by a simple https?:// regex. Decide whether www.example.com should become a link. If yes, normalize it to https://www.example.com in the href while displaying the original text. Bare domains like example.com are harder to detect without false positives and are usually not worth supporting.

Unicode and IDN domains may not match. Older regexes often assume ASCII. If your users submit internationalized domain names, test them explicitly or normalize with PHP’s idn_to_ascii() before matching.

Performance is usually fine, but avoid repeated conversion. Do not call the converter multiple times on the same large string in a loop. Convert once per render, and if you have a page with hundreds of comments, consider whether each one needs autolinking or only the expanded detail view.

Extension point: replace the converter, not the template. If you inherit the Symfony bundle and need different regex behavior, override the converter service with your own class or fork the bundle. The Twig extension is a thin wrapper; the useful customization point is the converter implementation. In Laravel, the equivalent is a container-bound Autolink service with constructor options.

Consider maintained alternatives. For Markdown content, league/commonmark has an autolink extension. For plain text with richer link detection, s9e/text-formatter provides a maintained Autolink plugin. For a Laravel-only solution, a 40-line tested helper is often more predictable than resurrecting a 2017 Symfony bundle.

Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
novasa/laravel-language-center
opencage/geocode
adolfoholzer/parameters
livenetworks/ln-starter
shitoudev/permissionmanager
johannesclimacus/laravel-tui
hocvt/seotools
vitalybaev/sypexgeo
amphibee/themosis-ignition
gito-me/fast-excel
frankyso/laravel-ipaymu
geolize-studio/laravel-chile
boomerangui/chat
cgv/localized-resource
noith/settings
kda/laravel-package
kda/filament-dynamic-navigation
bypersoft/signbox
pairus/product-data
fayne/laravel-filament-cms-core