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

Kurenai Laravel Package

orchestra/kurenai

Orchestra Kurenai is a Laravel package for managing URL redirects in a clean, centralized way. It helps preserve SEO and keep legacy links working by letting you define and handle redirections that integrate smoothly with modern Laravel applications.

View on GitHub
Deep Wiki
Context7

Getting Started

  • Install the package with Composer and publish its config: php artisan vendor:publish --tag=markdown-config. The config file is where the parser/driver is selected — from v0.2.0 onward you can point it at the CommonMark implementation rather than the legacy renderer.
  • Look first at three things: the config file (driver selection and extension list), the service container binding (which concrete parser class gets resolved), and the renderer's public convert() / toHtml() method. Those are the only surfaces you normally touch.
  • First use case — rendering user-authored Markdown in a Blade view:
// config/markdown.php
'driver' => 'commonmark',
'commonmark' => [
    'html_input' => 'escape',   // or 'strip'
    'allow_unsafe_links' => false,
],
<div class="prose">{!! $markdown->convert($post->body) !!}</div>

Once that round-trips correctly, add extensions (tables, autolinks, strikethrough) one at a time rather than all at once, so you can attribute any output change to a single feature.

Implementation Patterns

Facade/helper in views and mailables. Wrap conversion in a small Blade component (<x-markdown :text="$body" />) so sanitization and caching live in one place instead of being repeated with {!! !!} across templates. The same component is the natural fit for Mailables rendered server-side.

Store raw, render on read (with cache). Keep the Markdown source in the database and cache the HTML keyed by a hash of the source plus a parser-version string. This lets you re-render every post when you change config (for example, enabling CommonMark extensions) without a data migration.

$html = Cache::remember(
    "md:".sha1($post->body).":".config('markdown.version'),
    now()->addDay(),
    fn () => $markdown->convert($post->body)
);

Register extensions explicitly. With CommonMark as the engine, GitHub-flavoured extras are opt-in. Enable tables, autolinks and strikethrough in config, and register custom extensions in a service provider so they're discoverable and testable in isolation.

Sanitization as a pipeline stage. Treat the parser as one step and an HTML sanitizer (or html_input => 'escape'/'strip') as the next. Do this in the component, not at every call site — it's the single easiest way to avoid an XSS regression when someone adds a new render path.

Testing. Assert on rendered HTML in feature tests, and keep a fixture corpus of tricky documents (nested lists, fenced code containing Markdown, mixed indentation). The CommonMark spec examples make a good smoke test, and pinning a few of them guards against behaviour drift on future upgrades.

Integration tips. Register the package's parser as a singleton if you enable extensions with state; resolve it from the container in queued jobs that pre-render content; and if you expose a preview endpoint, run it through the exact same component so preview and published output can't diverge.

Gotchas and Tips

  • Raw HTML is the pitfall, not the parser. CommonMark permits inline HTML; whether it reaches the browser depends entirely on your html_input / sanitizer config. Verify with a payload like <img src=x onerror=alert(1)> before trusting any output path.
  • CommonMark is stricter than Markdown Extra. Tables, footnotes, definition lists and ~~strikethrough~~ are not core — they need extensions enabled. If content rendered fine on the previous driver, diff the output after switching; indentation rules and list-marker handling are the usual regressions.
  • Line breaks. CommonMark does not convert single newlines to <br> by default. If your authors rely on that, you need the hard_break/breaks option or an extension — otherwise every paragraph silently reflows.
  • config:cache in production. Config is read once at boot; a stale cached config after changing driver or extensions produces confusing "my change did nothing" behaviour. php artisan config:clear before debugging anything about output.
  • Cache invalidation on config change. Because you cached by content hash, bump a markdown.version value whenever you change driver, extensions, or sanitizer settings — otherwise old HTML survives the deploy.
  • Debugging output. When a construct renders unexpectedly, inspect the AST rather than guessing at the HTML; most environments expose the parsed document, and dumping it shows immediately whether the problem is parsing or post-processing. Also confirm which driver actually resolved (app('markdown')::class) — a wrong binding looks exactly like a parsing bug.
  • Extension points. Custom syntax goes in as an inline/block parser or a DocumentParsedEvent listener; keep these in dedicated classes and unit-test them against a string in / AST or HTML out, since they're the part most likely to break on a minor upgrade.
  • Upgrade discipline. A minor version that swaps or widens the parser engine can change rendered output without changing the API. Pin the version, keep the fixture corpus, and eyeball a diff of rendered output on upgrade rather than trusting the green test suite alone.
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.
uni-method/symfony-lib
tacticmedia/scim-server-bundle
neika-ai/symfony-bundle
mattleads/agent-publishing-bundle
glavweb/framework-bundle
glavweb/extra-bundle
glavweb/api-bundle
glavweb/admin-bundle
adachsoft/api-version-bundle
elsayed85/laravel-api-exceptions
ouhssini/laravel-demo-mode
daworks/ncloud-outbound-mailer-driver
gp247/cms
ignibyte/aic-gates
nexa-merchant/blog
novasa/laravel-language-center
opencage/geocode
adolfoholzer/parameters
livenetworks/ln-starter
shitoudev/permissionmanager