parsedown/laravel
Parsedown Laravel integrates the fast Parsedown Markdown parser with Laravel, offering a simple facade and service provider to convert Markdown to HTML. Configure safe mode and custom extensions easily in your views, controllers, or Blade templates.
This release targets PHP >= 7.2.3, so bump your composer.json platform requirement (and any CI images) before upgrading.
composer require <vendor>/<package>), then publish the new config file:
php artisan vendor:publish --tag=parsedown
The package works without publishing — the shipped defaults are used — but publishing is now the intended way to configure the singleton.config/parsedown.php. Every option you see there is applied to the singleton returned by the parsedown() helper.$html = parsedown('# Hello'); // block-level parse, wrapped in <p> etc.
$html = parsedown('# Hello', true); // inline parse, no block wrapper
@parsedown($post->body)
@parsedown($post->title, true)
If you need the raw Parsedown object (custom extension, manual calls), call the helper with no arguments:
$parser = parsedown(); // configured singleton
$parser->text($markdown);
Config-driven singleton. Treat config/parsedown.php as the single source of truth for parser behaviour (breaks, markup escaping, URL handling, safe mode, etc.). The helper builds and configures one Parsedown instance from this file; keep environment-specific tweaks in .env-backed config values rather than mutating the object at runtime.
Blade directive for display. Use @parsedown($markdown) in views for long-form content, and @parsedown($string, true) for short, inline fragments such as post titles, table cells, tooltips, or headings where the extra <p> wrapper would break layout.
Helper in application code. For content assembled in controllers, mailables, or API resources, parsedown($text) and parsedown($text, true) keep call sites short. Reserve the zero-argument form for cases where you genuinely need the object:
$parser = parsedown();
$parser->setMarkupEscaped(true);
return $parser->text($userInput);
Container injection. Because the helper returns a singleton, you can also type-hint Parsedown in constructors and methods and let the container hand you the configured instance — useful for testability and for services that render markdown repeatedly.
Safe rendering of user content. For any untrusted input, enable the safe-mode/markup-escaping options in the config rather than post-processing the HTML. This is the cleanest integration point and applies uniformly to the helper, the Blade directive, and injected instances.
Custom extensions. Subclass Parsedown (or use its inline/block extension hooks) and bind your subclass in a service provider so the singleton resolution picks it up; keep the config file responsible for the built-in options and the subclass responsible for structural changes.
Testing. Assert on rendered output from the helper/directive rather than on parser internals, and add a test that the published config values are actually applied — that catches config-cache and publish-tag mistakes early.
parsedown() and then changing options (e.g. setBreaksEnabled(true)) mutates the instance for the rest of the request — including later @parsedown calls and injected instances. Configure via the config file, or instantiate a fresh Parsedown when you need a one-off variant.parsedown() always gives you the same configured object; don't assume it is unconfigured because you didn't pass markdown.{{ }} is. Sanitise or enable safe mode before rendering untrusted markdown; this is the most common source of XSS in markdown-backed Laravel apps.true omits the block wrapper but still runs inline parsing — block constructs (lists, fenced code, tables) inside an inline call won't render as you expect. Use it only for genuinely inline fragments.config/parsedown.php, run php artisan config:clear (or re-run config:cache) in cached environments; otherwise your changes silently won't take effect.parsedown() with no arguments is the fastest way to inspect the live configuration (var_dump(parsedown())) and confirm the config file is being read as expected.How can I help you explore Laravel packages today?