mrshanebarron/code-block
mrshanebarron/code-block is a Laravel/PHP package for defining, managing, and rendering code blocks in your application. It provides a simple, reusable approach to keeping formatted code snippets organized and displaying them consistently across your views and content.
composer require mrshanebarron/code-block:1.0.2 — the 1.0.2 release changed how hyphenated identifiers map to PHP class names, so take that deliberately rather than via a floating ^1.0 constraint.composer dump-autoload && php artisan optimize:clear && php artisan view:clear. Restart php-fpm/Octane workers so OPcache drops the old symbol table.vendor/mrshanebarron/code-block/src/ and read the service provider. You are looking for three things: the Blade component alias (almost certainly <x-code-block> → CodeBlock), whether a config file exists (vendor:publish --tag=code-block-config), and whether views are publishable. Documentation is thin and the package has no community footprint, so the provider is the real spec.<x-code-block language="php">
@verbatim
{{ $user->name }}
@endverbatim
</x-code-block>
The @verbatim is not optional — see Gotchas.
Wrap, don't repeat. The package gives you one primitive; your app should own the policy. Create resources/views/components/code-example.blade.php that wraps <x-code-block> with your house styling, a caption, and a copy button. When you change the design, you change one file.
Keep documentation samples in sync with source. The highest-value pattern for docs and internal tooling is rendering from the real file rather than pasting:
<x-code-block language="php">
@verbatim
{{ Illuminate\Support\Facades\File::get(base_path('app/Actions/CreateOrder.php')) }}
@endverbatim
</x-code-block>
Guard it behind @env('local') or a build step so you are not shipping source code to production.
Merge attributes for per-instance variation. Blade components receive $attributes; if the package's view includes {{ $attributes }} on the wrapper, class="max-h-96" and id="example-1" pass straight through. Confirm this in the published view before you build styling on it — if $attributes is missing, you will need to publish and amend the view.
Compose with a copy action. Alpine is the least-friction option and needs no build step:
<div x-data="{ copied: false }">
<x-code-block language="bash">...</x-code-block>
<button @click="navigator.clipboard.writeText($refs.src.textContent); copied = true">Copy</button>
</div>
Give the block a x-ref only if the wrapper is attribute-pass-through; otherwise target it by a stable class.
Test it like any Blade component. $this->blade('<x-code-block>foo</x-code-block>')->assertSee('foo') catches the aliasing and escaping regressions that are this package's realistic failure surface. A single smoke test is enough — the value is in detecting a future patch that renames the component class.
Isolate it behind your own alias. In AppServiceProvider::boot(), Blade::component('code-block', App\View\Components\CodeExample::class) gives you an escape hatch. If the package is abandoned, you swap the implementation and no template changes.
Blade will compile code inside your code block. This is the number one trap. A sample containing {{ $x }}, @if, @foreach, @include, or a nested <x-...> tag is executed, not displayed. Wrap sample content in @verbatim…@endverbatim, or escape single occurrences with @{{ $x }}. There is no way for the package to protect you here — compilation happens before the component ever sees the string.
Escaping direction is a security decision. If the component renders the slot with {!! !!}, any user-supplied content is an XSS vector. Never feed request data into a code block. If it uses {{ }}, expect < and > in the output and check it is not double-escaped when you pass pre-escaped strings.
Whitespace is preserved verbatim, including the ugly kind. Slot content carries the indentation of your template. Indented blocks will render with leading spaces on every line. Either flush content to column zero, or add {{ trim($slot) }} to your published view override.
The 1.0.2 naming fix is a case-only rename, and those are invisible on macOS/Windows. If you upgraded from 1.0.0/1.0.1 with the package already vendored on a case-insensitive filesystem, git may not have registered the rename and both files can survive. On Linux CI you then get intermittent "class not found." Fix: clean vendor/ reinstall from a fresh checkout, not an incremental deploy. Add a case-sensitive CI runner — this is the exact bug that passes locally and fails in production.
Tailwind will purge the package's classes. If your app uses Tailwind and the component ships its own classes, they are not in your content globs. Either add ./vendor/mrshanebarron/code-block/resources/views/**/*.blade.php to tailwind.config.js content, or safelist the classes. Symptom: an unstyled block in production but styled in local dev with a warm JIT cache.
Config and view caching hide every change you make. php artisan config:cache after touching the config, view:clear after publishing views, optimize:clear after upgrading. When "my change did nothing," that is almost always the answer.
Publishing views is a commitment. Publish when you need to add $attributes, change escaping, or restyle. Do not publish if you only want different colors — pass a class. Once published, upstream fixes stop reaching you, and this package's low release cadence means fixes are rare and worth keeping.
Zero stars and no ecosystem is a real signal. Pin the exact version, keep your own wrapper component, and add one Blade smoke test. That combination means an abandonment or a breaking patch costs you a fifteen-minute swap rather than a template rewrite. Do not adopt it for anything user-facing where the rendered content is untrusted.
Debugging checklist when a block renders wrong: Blade::getClassComponentAliases() in tinker to confirm registration → php artisan view:clear → inspect the compiled view in storage/framework/views/ to see what Blade actually produced before rendering. The compiled file usually tells you instantly whether the problem is escaping, compilation, or styling.
How can I help you explore Laravel packages today?