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

Shout Laravel Package

awcodes/shout

Shout is a simple inline contextual notice component for Filament forms and infolists—essentially a fancy placeholder. Add it to any schema() method and customize the content, colors, icons, and icon sizes. Install via Composer, then add the vendor views to your theme CSS. Supports Filament 4.x and...

View on GitHub
Deep Wiki
Context7

Getting Started

Install and wire up the theme (2 minutes, but the second step is the one people skip).

composer require awcodes/shout

Then, in your panel's theme CSS (resources/css/filament/admin/theme.css):

@source '../../../../vendor/awcodes/shout/resources/**/*.blade.php';

If you have no custom theme yet, create one first (Filament docs → custom theme) — Shout does not ship compiled CSS into the panel's default asset bundle. Skipping the @source line is the #1 cause of "it renders but looks like plain text."

Rebuild (npm run build) and drop the component into any schema():

use Awcodes\Shout\Components\Shout;

Shout::make('trial-notice')
    ->heading('Trial ends in 5 days')
    ->content('Add a payment method to keep your data and integrations active.')
    ->color('warning')
    ->icon('heroicon-o-exclamation-triangle');

Where to look first: the README is the full API surface — there is no config file, no service provider you need to touch, no migrations, no routes. Everything is Shout::make()-><modifier>(). vendor/awcodes/shout/resources/views is the only other place worth reading, because it tells you exactly which props are consumed and how the markup is structured.

First real use case: a panel-wide context banner on the resource form. Put it as the first item in form(Form $form): Form's schema so it appears above the fields, and gate it on state:

Shout::make('prod-warning')
    ->content('You are editing a record in the production tenant.')
    ->color('danger')
    ->visible(fn () => app()->environment('production'))
    ->columnSpanFull()

Version matrix — get this right before anything else:

Shout Filament
4.x 4.x & 5.x
3.x 4.x
2.x 3.x
1.x 2.x

For new Filament 4/5 work, require ^4.1 — 4.1.1 is the release that made icon aliases resolve, gave dark mode its own tinted palette, and fixed inline action alignment. On 4.0.x your notice will be near-unreadable in dark mode.

Implementation Patterns

Treat it as a schema citizen, not a field

Shout is a presentational schema component, so every Filament component modifier works on it: visible(), hidden(), columnSpanFull(), columnSpan(), key(). It renders in forms and infolists. That's the whole integration story — no domain model impact, no persistence, no controller changes.

Conditional, record-aware notices

The highest-value pattern is turning static help text into state-driven context. Because the component lives in the schema, its modifiers can close over $record/$get:

Shout::make('sync-state')
    ->heading('Sync failed')
    ->content(fn (?Model $record) => "Last attempt: {$record?->last_synced_at?->diffForHumans()}")
    ->color('danger')
    ->icon('heroicon-o-arrow-path')
    ->actions([
        Action::make('retry')->label('Retry now')->action(fn ($record) => $record->retrySync()),
    ])
    ->visible(fn (?Model $record) => $record?->sync_status === 'failed');

Note the general rule: Filament evaluates modifier closures with the usual injection set (Get $get, ?Model $record, $livewire). Closure support has been patched in over time (e.g. closures in the type modifier landed in 2.0.3), so if a specific modifier silently ignores a closure on an older tag, upgrade rather than work around it.

Actions as the CTA slot

actions() accepts real Filament\Actions\Action objects, which is what makes Shout more than a styled <p>. Day-to-day uses: link out to docs, "Upgrade plan," "Re-run import," "Dismiss for this session."

->actions([
    Action::make('docs')->label('Read the migration guide')->url('https://docs.example.com/migrate')->link(),
])

Prefer url() or simple closures over modal-based actions. Shout is not a form field and does not participate in form state; a modal action that depends on $get() from the surrounding form will frustrate you. If you need a modal, pass explicit ->arguments() or resolve data from the record.

Build a semantic vocabulary, not ad-hoc colors

The package resolves per-type icon aliases (shout::icon.info, shout::icon.success, shout::icon.warning, shout::icon.danger). Lean on that: define a tiny app-level factory so the team stops hand-rolling colors and icons.

final class Notice
{
    public static function info(string $name, string $content): Shout
    {
        return Shout::make($name)->content($content)->color('info');
    }
    // warning / success / danger...
}

Then register brand overrides once, globally, in a service provider:

FilamentIcon::register([
    'shout::icon.warning' => 'heroicon-o-shield-exclamation',
]);

This is the cleanest extension point in the package — it lets you change iconography across every notice in the app without touching schema code.

Layout placement

  • Above the first field for record-level context (locked/draft/legacy state, quota warnings).
  • Below a Section header for section-scoped guidance where Section::description() isn't loud enough.
  • Inside wizard steps for step-specific caveats — this is where Shout genuinely beats a description string.
  • On infolist view pages for "what this record means" explanations, deprecations, and data-freshness notes.
  • In a grid, remember it's one column by default — add ->columnSpanFull() or it'll sit awkwardly beside a field.

Gotchas and Tips

Unique make() keys. The make() argument becomes the component's key. Two Shouts with the same name in one schema — easy to do when generating notices in a loop — will collide and mis-render. Suffix with an index or an ID: Shout::make("notice-{$index}").

It is not a field. No state, no validation, no dehydration, no ->rules(). Don't try to persist content through it, and don't use it to display validation errors — that's what Filament's notifications and field error states are for.

CSS is a hard dependency. Missing @source, wrong relative depth (the four ../ assume resources/css/filament/{panel}/theme.css; a theme file elsewhere needs a corrected path), or a stale build all produce the same symptom: correct markup, ugly output. If colors or the dark-mode tint are missing, check the theme build before you check the PHP.

Dark mode only became usable in 4.1.1. On earlier releases, link actions and outlined buttons inside a notice were effectively invisible against the light-colored background. Same release fixed icon(false) leaving an empty indent slot and an empty <h2> rendering when no heading was set. Pin ^4.1.1 minimum.

Empty action bar spacing. "Remove UI gap when actions are not visible" (3.0.1 / 4.0.1) — if you're on an older tag and see phantom whitespace under a notice, that's why.

Heading vs. content escaping. heading() accepts an HtmlString when you need a non-<h2> element. Assume content() is text-safe and reach for HtmlString when you genuinely need markup — and never pass user-supplied strings into raw HTML without sanitizing.

Version-matrix errors look like unrelated bugs. Installing 4.x on a Filament 3 app yields class-not-found or "component not found" errors that don't mention Shout. Confirm the matrix row first.

Debugging. It's one Blade view. php artisan view:clear after any publish/override, and read the compiled view in storage/framework/views to see exactly what data reached the template — faster than guessing which modifier did nothing. For rendered output assertions in tests, a plain assertSee('Trial ends') on the page response is usually enough; add a dark-mode screenshot check if you rely on the colored notices for anything important.

Reach for the smaller tool first. If the message needs no color, icon, heading, or action, Section::description() or a Placeholder is less CSS to maintain. Shout earns its place precisely when you need notice semantics — severity color, a CTA, and conditional visibility — inside the schema flow.

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.
gmostafa/php-graphql-client
xeviant/paystack
snowsoft/faker
meditationsteps/blogetc
animalyoung/laravel-influxdb
onix-solutions/sms-telera
lonely-lights/prosetta
oxygen/data
oxygen/core
jengo/base
xiloryx/log-collector
a21ns1g4ts/filament-stripe
la-php/laravel-admin
artisan-build/community-prompts
vleroy/smart
ayles-software/laravel-australian-public-holidays
cboxdk/laravel-id-spatie
cboxdk/laravel-id-billing
cboxdk/laravel-id-billing-bridge
simple-as-fuck/php-performance-log