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

Filament Syntax Entry Laravel Package

parallax/filament-syntax-entry

A Filament form field that adds a syntax-highlighted code editor to your admin panels. SyntaxEntry makes editing code, JSON, and config in forms easier with configurable languages, themes, and a clean developer-friendly input experience.

View on GitHub
Deep Wiki
Context7

Getting Started

This is a read-only infolist entry, so the mental model is: render code on a "view" page (resource view, relation manager, or a custom infolist page). It is not a form field, not a table column, and it does not let users edit code.

  1. Install

    composer require parallax/filament-syntax-entry
    

    Check the README for the exact version constraint against your Filament major (v3 vs v4). With 18 stars and a single maintainer, pin the tag rather than floating ^1.0.

  2. Assets/config Most Filament asset packages either auto-register a service provider or expose a publish tag. Look for one of:

    php artisan vendor:publish --tag="filament-syntax-entry-config"
    php artisan vendor:publish --tag="filament-syntax-entry-assets"
    

    If a plugin class is shipped (Filament v4 style), register it in your panel provider:

    ->plugin(FilamentSyntaxEntryPlugin::make())
    
  3. First use case — drop it into an existing Resource::infolist() (or a ViewRecord page's schema) to show a stored payload such as a webhook body, a JSON config blob, or a stored SQL migration:

    use Parallax\FilamentSyntaxEntry\Infolists\Components\SyntaxEntry;
    
    public static function infolist(Infolist $infolist): Infolist
    {
        return $infolist->schema([
            SyntaxEntry::make('payload')
                ->language('json'),
        ]);
    }
    
  4. Look here first when something is off: the package's resources/views for how it emits the <pre><code> block, and resources/js for which highlight.js build/plugins it loads (core vs. common languages, line numbers, etc.).

Implementation Patterns

Explicit language beats auto-detection. highlight.js's auto-detect is slow and frequently wrong on short snippets. Always pass ->language('php'), ->language('json'), etc., and derive it from the record when it varies:

SyntaxEntry::make('source')
    ->language(fn ($record) => $record->file_extension === 'php' ? 'php' : 'plaintext')

Theme per-entry vs. global. Themes (github-dark, atom-one-dark, monokai, …) are highlight.js stylesheet names. Set a sane default in config and override only where a view needs it:

SyntaxEntry::make('diff')->theme('github-dark')->language('diff')

Compose inside infolist layout primitives. It is an ordinary entry, so it nests in Section, Grid, and Split alongside TextEntrys. A common pattern is a metadata section (author, size, updated_at) followed by the syntax entry spanning full width.

Reuse via a named wrapper. If you render the same kind of payload in several resources, extract it:

class JsonPayloadEntry extends SyntaxEntry
{
    protected function setUp(): void
    {
        parent::setUp();
        $this->language('json')->theme('github-dark');
    }
}

Then use JsonPayloadEntry::make('payload'). This also gives you one place to react to upstream API changes.

Feed it computed content, not just raw columns — a diff, a normalized JSON dump, or a generated snippet:

SyntaxEntry::make('payload')
    ->state(fn ($record) => json_encode($record->payload, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES))
    ->language('json')

On custom pages, build an Infolist the same way you would for a resource; nothing about the package is resource-specific.

Test the schema, not the JS. Feature tests can assert the entry is present and configured (assertSeeLivewire, schema assertComponentExists), but highlight.js rendering happens in the browser — cover it manually or with a Dusk test that asserts the hljs class is applied.

Gotchas and Tips

  • Highlighting is client-side. The raw code is in the HTML payload. Do not use this to protect secrets — gate the page with policy/authorization as you would any other entry.
  • Language aliases matter. highlight.js expects registered aliases (js, ts, bash, sh, yml, json, php, html). An unregistered name silently produces unhighlighted output — no exception. If a snippet is blank of color, suspect the language string first.
  • Unknown themes fail quietly. A typo in ->theme() just falls back to unstyled (or the default). Verify against highlight.js's styles/ directory.
  • Dark mode. highlight.js themes are static stylesheets, so a github (light) theme will look wrong on Filament's dark panel. Either configure a dark-friendly theme globally, or scope two stylesheets and toggle by Filament's dark class in your own CSS.
  • Livewire re-renders. If the infolist entry is inside a live-updating context and its state changes after the initial page load, highlight.js will not re-run automatically. Keep these entries in static view pages where you can, or wire up a hook that calls hljs.highlightAll() on the relevant DOM node after update.
  • Large content kills the page. A multi-megabyte column will be dumped into the DOM and tokenized in the browser. Truncate before handing it off (str($record->payload)->limit(20000)) or paginate the content.
  • Config caching. If a theme or default language is set in a published config, remember php artisan config:cache in production will serve the cached value — a config edit in a deploy script needs a cache clear.
  • Version pinning. With 18 stars and low activity, treat upgrades as deliberate: read the diff for the version you're moving to, especially across Filament majors, and pin in composer.json.
  • Extension points to keep in mind: the underlying Blade view (publish and override if the package supports view publishing) for things like a copy-to-clipboard button or a filename header, and subclassing the entry (see the wrapper pattern above) rather than reopening the vendor class.
  • Debugging order: (1) is the asset loaded — check the network tab for the highlight.js bundle and theme CSS; (2) is the language registered; (3) is the class applied to the <code> element — inspect the DOM; (4) is the content actually populated on the entry (->state() returning null is a common cause of an empty block that looks like a broken highlighter).
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.
jinas/dhivatar
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