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

Badger Laravel Package

cachethq/badger

Badger is CachetHQ's badge generator, producing SVG status badges for your Cachet status page components so you can embed live uptime and status indicators in READMEs, dashboards, or docs.

View on GitHub
Deep Wiki
Context7

Getting Started

Badger is Cachet's SVG badge generator for Laravel — a self-hosted shields.io for things like build status, coverage, version numbers, and download counts that you can drop into a README or dashboard.

Minimum setup:

composer require cachethq/badger

v5 requires PHP 8.2+ and targets Laravel 11/12/13. If you're on Laravel 8–10, pin the 4.x branch (composer require cachethq/badger:^4.0) — do not attempt to force v5 onto an older skeleton.

Then:

  1. Check composer show cachethq/badger and confirm the service provider is auto-discovered.
  2. Publish the config (php artisan vendor:publish --tag=badger-config or equivalent — check vendor/cachethq/badger/config for the exact tag) and read config/badger.php first; that's where the default style, color, and route prefix live.
  3. Run php artisan route:list | grep -i badge to see the registered badge endpoint(s).

First use case: render a static badge in a Blade view or Markdown file.

{!! Badger::badge('build', 'passing', 'green') !!}

Or hit the HTTP endpoint and paste the URL into README.md — that's the day-to-day use for most teams.

Implementation Patterns

Facade / inline rendering. Use the Badger facade when you already have the data in PHP and want to embed the SVG directly:

use CachetHQ\Badger\Facades\Badger;

return view('dashboard', [
    'coverage' => Badger::badge('coverage', '87%', 'yellowgreen'),
]);

Cast to string (or ->toSvg()) when you need the raw markup — useful for caching the output in Redis/file storage rather than regenerating per request.

Dynamic badge endpoints. The highest-value pattern is a small controller behind the package's route that computes a value live:

Route::get('/badge/tests', function () {
    $count = Cache::remember('badge.tests', now()->addMinutes(10), fn () => Tests::count());

    return response(Badger::badge('tests', (string) $count, 'blue'))
        ->header('Content-Type', 'image/svg+xml');
});

Wrap the DB query in Cache::remember — badges get hit by GitHub's camo proxy and CI scrapers far more often than you'd expect.

Style selection. v5 adds the for-the-badge style, modeled on shields.io, alongside the existing flat/plastic variants. Pass the style wherever the badge is constructed, or expose it as a query parameter on your own endpoint so consumers can pick:

// e.g. /badge/tests?style=for-the-badge
Badger::badge('tests', '342', 'blue', style: 'for-the-badge');

Confirm the exact parameter name/signature against the package source — the positional arguments have historically been subject, status, color.

README / docs integration. Point the URL at your app's domain and commit the URL, not the SVG, so the badge stays live. If the repo is public but the app is private, keep badge endpoints unauthenticated (and rate-limited) or render badges at build time into a static file.

Testing. v5's suite is on Pest 3/4 + Testbench 10/11, so mirror that for your own app tests. Assert on the response content type and on presence of the subject/status text rather than byte-matching the SVG:

$this->get('/badge/tests')
    ->assertOk()
    ->assertHeader('Content-Type', 'image/svg+xml')
    ->assertSee('tests', false);

Gotchas and Tips

  • The v3 → v5 version jump is real. There's no v4 assessment history to lean on; the release notes skip straight from v3.0.0 to v5.0.0, so diff v3.0.0...v5.0.0 and re-read the facade signature before upgrading. Treat the constructor/argument order as potentially changed.
  • PHP 8.2 is a hard floor. v5 also explicitly fixed implicitly-nullable parameters for PHP 8.4+, which means older code passing null positionally into badge methods may now fail loudly. Audit any Badger::badge(..., null) calls.
  • Laravel 8–10 users must stay on 4.x. Don't let a composer update silently try to resolve v5 — constrain the version explicitly if you're on an older skeleton, and be aware that future security fixes may only land on the 5.x line.
  • for-the-badge is visually wide. The uppercase, bolder, letter-spaced style takes noticeably more horizontal space than flat. In README tables or sidebars it can wrap or overflow — prefer it for hero badges, not dense badge rows.
  • Escape special characters in URL-path badges. Shields.io conventions generally apply: - becomes --, _ becomes __, and spaces are _. If you're generating badge URLs from user-controlled strings, this is a correctness bug and an injection surface.
  • Sanitize everything you interpolate into the SVG. A badge label is {!! !!}-rendered markup. Never pass raw request input into the subject/status without stripping <, >, &, and quotes — otherwise you've built a stored-XSS vector on a .svg response that browsers will happily render as a document.
  • Set explicit cache headers. SVGs are cheap but the queries behind them aren't. Cache-Control: public, max-age=300 plus a short server-side cache is the right default; add ETag if you want GitHub's camo to revalidate instead of refetching.
  • Debugging "badge 404s": check route:list first, then the config's route prefix, then whether a catch-all route in your app is shadowing the badge path. If the SVG renders but looks wrong, the style string is the usual culprit — an unrecognized style typically falls back to a default rather than erroring.
  • Extension points are the config file (defaults for color/style) and the package's published views, if it ships a view-based renderer — check vendor/cachethq/badger/resources/views before writing your own SVG builder.
  • Automated releases now trigger on v* tags. If you mirror or vendor this package, pin a tag rather than a branch — the changelog is regenerated on release, so diffs between tags are the source of truth.
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.
coleus/frame
thtg88/journalism
filagora/filagora-ai-forums
rlacerda83/query-parser
socialdept/atp-orm
cboxdk/laravel-assistant-client
socialdept/atp-resolver
socialdept/tenant-domains
tautvydasr/blade-class-names
socialdept/color-scales
maherelgamil/controller
coleus/widgets
coleus/table
coleus/users
coleus/music
coleus/health
coleus/calendar
coleus/notes
coleus/support
coleus/settings