bardh78 / laravel-wisra
Inject HTML comments into compiled Blade templates showing view file paths. Useful for debugging and IDE integration (e.g. Wisra).
Requires
- php: ^8.2
- illuminate/support: ^10.0|^11.0|^12.0
Requires (Dev)
- orchestra/testbench: ^8.0|^9.0
- phpunit/phpunit: ^10.0|^11.0|^12.0
Suggests
None
Provides
None
Conflicts
None
Replaces
None
README
Inject HTML comments and attributes into compiled Blade templates to expose view file paths and source line numbers. Useful for debugging, IDE integration (e.g. Wisra), and AI/LLM-assisted development.
Installation
Install via Composer as a development-only dependency:
composer require --dev bardh78/laravel-wisra
The package auto-discovers its service provider. Laravel Wisra is always local-only and should not be installed as a production/runtime dependency.
Configuration (optional)
Publish the config file to customize behavior:
php artisan vendor:publish --tag=config
Or publish only this package's config:
php artisan vendor:publish --provider="Bardh78\LaravelWisra\LaravelWisraServiceProvider"
Environment variables:
| Variable | Default | Description |
|---|---|---|
LARAVEL_WISRA_ENABLED |
true |
Enable or disable the instrumentation |
LARAVEL_WISRA_SKIP_LIVEWIRE |
true |
Suppress view/translation comments around Livewire-rendered content |
LARAVEL_WISRA_ANNOTATE_LIVEWIRE |
true |
Add safe element file/line attributes to Livewire views |
LARAVEL_WISRA_INJECT_CONTEXT_META_TAGS |
true |
Inject request-level Wisra meta tags into the document <head> |
Note: After enabling or disabling Wisra, clear the compiled view cache so changes take effect:
php artisan view:clear
What it does
- View path comments — Wraps each compiled view with
<!-- [view] /path/to/view.blade.php -->and<!-- [/view] --> - Line annotations — Adds
wisra-start-lineandwisra-end-lineattributes to HTML elements for source mapping - Translation comments — Wraps
__()andtrans()echoes with<!-- [laravel-translation] /path/to/lang/file.php -->for easier translation debugging
How LLMs benefit from it
When AI coding assistants (Cursor, Copilot, Claude, etc.) work with your Laravel app, they often need to:
- Inspect rendered output — Via browser tools, DOM snapshots, or page source
- Map HTML back to source — Find which Blade file and line produced a given element
- Suggest precise edits — Know exactly where to change code
Without Laravel Wisra: The assistant sees raw HTML with no trace to the Blade source. It must guess files, search the codebase, or rely on structure alone.
With Laravel Wisra: The rendered HTML includes:
- Exact file paths in comments, so the assistant knows which view file to edit
- Line numbers on elements via
wisra-start-lineandwisra-end-line, so it can target the correct line - Translation file paths for
__()calls, so it can update the right lang file
Example
Rendered HTML with Wisra:
<!-- [view] /project/resources/views/welcome.blade.php --> <div class="hero" wisra-start-line="5" wisra-end-line="12"> <!-- [laravel-translation] /project/lang/en/welcome.php --> <h1>Welcome to our app</h1> <!-- [/laravel-translation] --> </div> <!-- [/view] /project/resources/views/welcome.blade.php -->
An LLM can now:
- Open
resources/views/welcome.blade.phpand edit around lines 5–12 - Open
lang/en/welcome.phpto change the translation for the heading - Avoid searching or guessing which files to modify
Best practices for LLM workflows
- Install in development only — Use
composer require --dev; the package also refuses to instrument non-local Laravel environments - Use with browser MCP tools — When the assistant inspects the page, it gets file/line hints
- Combine with Cursor rules — Mention that view comments are present so the assistant knows to use them
Livewire compatibility
Livewire receives file/line attributes without view or translation comments outside the component root. Compiled output is independent of the HTTP request, so initial renders and AJAX updates share the same mapping. PHP, JavaScript, CSS, comments, and verbatim content are preserved.
Class-based components, custom view paths, and Livewire 4 single-file components are supported. Livewire 4's compiler hook annotates the original source before it creates cached views, preserving the original file and line numbers.
data-wisra-view identifies the Blade file that owns each annotated element. Wisra inspection prefers this attribute over legacy view comments, captures the containing Livewire component name, and distinguishes direct element mapping from an ancestor hint.
Keep LARAVEL_WISRA_SKIP_LIVEWIRE=true for safe comment behavior. Set LARAVEL_WISRA_ANNOTATE_LIVEWIRE=false to disable attributes on recognized Livewire templates. Clear compiled views after upgrading or changing these settings:
php artisan view:clear
Request context meta tags
When a Blade document contains a <head> tag, Wisra can inject request-level meta tags like:
<meta name="wisra-current-route" content="/app/panel"> <meta name="wisra-current-route-name" content="panel.index"> <meta name="wisra-current-controller" content="App\Http\Controllers\PanelController"> <meta name="wisra-current-action" content="index">
These values are rendered at runtime, so they stay correct even when Blade views are cached.
Requirements
- PHP 8.2+
- Laravel 10.x, 11.x, 12.x, or 13.x
License
MIT
React, Inertia and Vue (Vite)
Blade instrumentation cannot map browser-rendered JSX back to its source. This Composer package also ships a Vite plugin for React .tsx/.jsx (and JSX in .js) and Vue HTML templates in .vue single-file components. It works with Inertia and standalone framework apps.
After Composer installation, install the frontend companion from the package directory:
npm install --save-dev --install-links ./vendor/bardh78/laravel-wisra
Add it before the React/Vue compiler in vite.config.ts or vite.config.js:
import wisra from 'vite-plugin-laravel-wisra'; export default defineConfig({ plugins: [ wisra(), // laravel(...), react() or vue(), and your other plugins ], });
Run npm run dev, then refresh the page in Wisra. Run Composer installation before npm installation on fresh checkouts. For local package development, use a Composer path repository with symlinking enabled; Composer reads PHP changes immediately. Reinstall the frontend companion after changing plugin code.
The plugin parses source code and annotates native DOM elements with their absolute source file, original start/end lines, framework and owning component. It preserves source maps and leaves custom component props, fragments, scripts, CSS and directives intact. Reused React components identify the component implementation; Wisra can additionally show its containing component tree. Library-generated children can inherit a nearby source hint, but Wisra does not report that ancestor range as an exact element range.
The Vite plugin runs only during development (vite serve), is disabled for production mode, and never instruments vite build output. wisra({ enabled: false }) disables it explicitly. Keep it in devDependencies; the Laravel environment flag controls Blade instrumentation separately. Vue external templates and non-HTML template preprocessors are left unchanged. Other frameworks are not yet instrumented.
A rendered React button looks like:
<button data-wisra-view="/project/resources/js/components/SaveButton.tsx" wisra-start-line="8" wisra-end-line="12" data-wisra-framework="react" data-wisra-component="SaveButton"> Save </button>
Wisra includes this mapping in both inspection and annotation chat context. Source attributes update naturally during HMR and Inertia page changes; no DOM mutation observer or React DevTools hook is required. Optional component-tree hints use available framework debug information. The inspector does not capture React/Vue props or Inertia page props.
Frontend package regression tests:
npm ci
npm test