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

Markdown Laravel Package

vtalbot/markdown

A Laravel package that integrates Markdown parsing into your app, with a Markdown facade and Blade directive for converting Markdown text to HTML. Useful for rendering user content, documentation, and other formatted text with configurable parser options.

View on GitHub
Deep Wiki
Context7

Getting Started

Install via Composer:

composer require vtalbot/markdown

Laravel 5.5+ – auto-discovery registers the service provider and alias. No config changes needed.

Laravel ≤5.4 (and any framework without discovery) – register manually in config/app.php:

// providers
Vtalbot\Markdown\MarkdownServiceProvider::class,

// aliases
'Markdown' => Vtalbot\Markdown\Facades\Markdown::class,

First thing to look at: open the facade class and service provider in vendor/vtalbot/markdown/src. The entire package surface is small — a single binding plus a parse() method (and typically a parseFile() helper). Reading them takes two minutes and tells you exactly which underlying compiler it wraps (Historically michelf/php-markdown), which matters for dialect support and later debugging.

First use case – the canonical "render a string as HTML":

use Vtalbot\Markdown\Facades\Markdown;

$html = Markdown::parse('# Hello **world**');
// <h1>Hello <strong>world</strong></h1>

From here, the most common integration is rendering a .md document or a user-submitted field into a Blade view. The package simply gives you a Laravel-idiomatic facade over a PHP Markdown compiler; treat it as a thin convenience layer, not a full content pipeline.

Implementation Patterns

Render inside a view / Blade directive

// Controller
return view('docs.show', ['body' => Markdown::parse($doc->markdown)]);

// Or inline in Blade with raw output
{!! Markdown::parse($post->body) !!}

If you want a reusable directive, register a Blade @markdown in a service provider:

Blade::directive('markdown', function ($expression) {
    return "<?php echo app('markdown')->parse($expression); ?>";
});

Render markdown stored on disk

$html = Markdown::parseFile(resource_path('docs/getting-started.md'));

For anything beyond trivial, prefer file_get_contents() + Markdown::parse() so you control the path, encoding, and error handling yourself. parseFile will fail silently or throw on missing paths depending on the underlying engine.

Cache compiled output – markdown compilation is CPU work you don't need to repeat on every request. Cache at the source-hash level so edits invalidate automatically:

$html = Cache::remember('md:'.md5($markdown), now()->addDay(), function () use ($markdown) {
    return Markdown::parse($markdown);
});

Sanitize before saving or rendering – this package deliberately does not escape HTML. Pair it with a sanitizer (HTMLPurifier, or league/html-sanitizer) if the source is user-controlled:

$html = Markdown::parse($input);
$safe = Purifier::clean($html);

Notifications and mail – markdown output pairs well with Laravel's Mailable ->markdown() view helper, but the two systems are independent. Use vtalbot/markdown when you already have stored markdown strings you want to render; use Laravel's native markdown mail components when the content is authored as a Blade-markdown template.

Testing – mock the facade when asserting controller output, so you don't couple tests to the compiler's HTML formatting:

Markdown::shouldReceive('parse')->once()->andReturn('<h1>Stubbed</h1>');

Gotchas and Tips

Output is unsafe by default. Markdown permits inline HTML, and the underlying engine passes it through. An attacker can embed <script> or onerror= inside a code fence escape. Never render user markdown with {!! !!} without sanitization. This is the single biggest production risk with the package.

Laravel version drift. The last tagged release is from March 2021 and the description only claims Laravel 4 and 5. Auto-discovery was added for Laravel 5.5 but later versions (9/10/11) are untested. The facade binding still works in practice because the package is thin, but if you hit "target class [markdown] does not exist" or a container resolution error, fall back to manual provider registration — and don't expect upstream fixes for modern-version issues.

Facade alias collisions. If your app also pulls in a different markdown wrapper (GrahamCampbell's, spatie/laravel-markdown, etc.), the Markdown alias will clash. Use the FQCN in code or rename the alias in config/app.php to something like 'Md'.

Dialect quirks. The behavior of tables, fenced code blocks, footnotes, and strikethrough depends entirely on the underlying compiler version pinned in composer.lock. If a feature "doesn't work," check the engine before assuming the Laravel wrapper is at fault. Compare raw output against the engine's own CLI/example to isolate.

parseFile path resolution. Relative paths are resolved against the process working directory, not base_path(). Always pass an absolute path (base_path(), resource_path(), storage_path()) to avoid surprises when running queue workers, artisan commands, or tests from different directories.

No config file to publish. There's generally nothing to php artisan vendor:publish. Tuning (line breaks, HTML escaping, extensions) requires either editing the underlying engine or subclassing/replacing the binding. If you need GFM, footnotes, or custom extensions, it's often cheaper to swap the package for league/commonmark than to patch this one.

Watch for PHP 8 deprecations. With a 2021 release and a small dependency tree, dynamic property deprecations or null-to-string deprecations in the wrapper can surface on PHP 8.2+. Run your test suite on the target PHP version before shipping; pin PHP if you must.

When to reach for something else. This package is best when you need a five-line "markdown string → HTML" helper inside an existing Laravel 5 app. For a new install, a CMS, or anything requiring sanitization guarantees, GFM parity, or active maintenance, league/commonmark (with league/html-sanitizer) is the safer day-to-day choice.

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.
store-doc/laravel-storage-driver
plus-it/laravel-translation-manager
diephp/perhaps
diephp/telegraph
osmaviation/spreadsheet
microsoft/fluentui-system-icons
mmccook/php-json-canonicalization-scheme
middlewares/firewall
qubiqx/montapacking
nyoncode/laravel-package-console
pnscripts/filament-broadquill-lite
pnscripts/laravel-sentfold-lite
vleap/mx-sdk-laravel-internal
twidpay/utils
htetmyathlaing/scout-elasticsearch-driver
artisan-toolbox/front-awesome
ls/client-assistant
users-au/laravel-client
cgv/localized-resource
noith/settings