hms5232/laravel-swagger
Laravel package for Swagger/OpenAPI documentation: generate interactive API docs from PHP annotations, serve the Swagger UI, and keep specs aligned with your routes and controllers—a simple drop-in way to document REST APIs in Laravel projects.
hms5232/laravel-swagger bundles Swagger UI and Swagger Editor v5 assets into a Laravel app so you can browse an OpenAPI spec without standing up a separate docs site. Treat it as a serving layer, not a spec generator — pair it with something like knuckleswtf/scribe or dedoc/scramble that produces the JSON/YAML.
Minimal path:
composer require hms5232/laravel-swagger:^0.2.0php artisan vendor:publish --tag=swagger-config (check php artisan vendor:publish output for the exact tag in this release; asset publishing is a separate tag).config/swagger.php and point the docs route at your spec URL — the annotated file is the primary documentation for this package, more so than the README./api/documentation or similar per config) in a browser and confirm the UI loads your spec.First real use case: local/staging API exploration. The package is most valuable when the UI is enabled for non-production environments only, so you get a clickable API browser during development without shipping it to customers.
Because 0.2.0 is a major bump with "no breaking changes," read that as "the behavior differs from what you'd get from the official Swagger UI/Editor distribution." Check the config file comments before assuming upstream Swagger docs apply verbatim.
Environment-scoped enablement. Gate the docs routes behind config driven by env, e.g. only register them when app()->environment(['local','staging']) or when an explicit LARAVEL_SWAGGER_ENABLED flag is set. Don't rely on the package's default route registration being safe for production.
Pin versions explicitly in config. The package ships defaults (Swagger UI 5.31.0, Swagger Editor 5.0.3 in this release), but those defaults move between releases. If the rendered UI matters to you — screenshots in docs, QA scripts, CSP allowlists — set the version keys in config/swagger.php yourself so a composer update can't silently change the frontend.
Custom spec sources. Keep the spec as a route rather than a static file where possible (/api/openapi.json served by a controller or by Scribe/Scramble), then point the UI/config at that URL. This keeps the spec in sync with the code and avoids stale generated files in public/.
Multiple UIs, one spec. If you need both Swagger UI (read-only docs) and Swagger Editor (interactive editing for internal teams), configure them as separate entries and, in practice, put the Editor behind auth middleware — it's a write-capable tool and a debugging surface you don't want public.
Auth for protected specs. If your OpenAPI document is behind auth:sanctum, the UI's fetch will 401. Either serve a public read-only spec variant on a separate route or add a small shim that injects a token into the Swagger UI request interceptor config. Prefer the former; interceptors get lost on version upgrades.
Asset publishing in deploy pipelines. Add the publish step to your deploy script (or a composer.json post-install hook) so new asset versions land consistently, and diff the published directory in CI to catch unexpected churn.
Middleware and route customization. Wrap the docs routes with your own middleware group (web, plus any IP allowlist or basic auth) rather than editing vendor files. This survives upgrades.
The config file is not auto-merged. This is the headline gotcha for 0.2.0: override_get_worker will be missing from your config/swagger.php unless you add it or republish. Laravel's vendor:publish --force overwrites your file entirely — copy your customized values aside first, republish, then re-apply. Alternatively add just the one key by hand as the upgrade guide shows, which is the safer move in a live app.
The new editor.monaco.override_get_worker flag deserves attention. It controls whether the package replaces Swagger Editor v5's apidom.worker.js. The default is true, i.e. the package's own worker file wins over upstream's. If you see a blank Editor pane, a Worker constructor error in the console, or the editor hanging on load after upgrading, this flag is the first thing to flip. Set it to false to defer to upstream's worker and see whether the symptom disappears — that's your fastest bisect.
Clear config cache after upgrading. php artisan config:cache on a deploy that ran before you added the new key will bake in the old config array. Always config:clear/config:cache as part of the upgrade step, otherwise you'll debug a flag that isn't actually being read.
Major version ≠ breaking changes, but ≠ drop-in either. The maintainer bumped to 0.2.0 specifically to make people look. Take the hint: re-read the published config file's comments against your own copy and diff them. The behavioral deltas are in the assets and defaults, not the PHP API surface.
Check the constraint before upgrading on older Laravel. The release notes mention Laravel 13 unit test support. "Unit test" support is not the same as "officially supported and documented" — verify your Laravel/PHP combo actually runs the package's routes and asset publishing in a staging deploy, not just that Composer resolves.
Cache-busting and CDN mismatches. If you front the assets with a CDN or long-lived cache headers, a UI version bump can leave browsers on stale JS paired with a new HTML shell — a classic source of "it works for me, not for them." Version the published asset paths or purge on deploy.
Where to extend. The package is intentionally thin, so resist patching vendor files. For anything beyond config — custom CSS, extra Swagger UI plugins, a different OAuth flow — publish the assets and template into your app and override there. If there's no publish tag for views, use a route override or a small custom controller returning your own Blade wrapper around the package's assets.
Debugging checklist, in order: (1) php artisan route:list | grep -i swagger, (2) browser console for worker/module errors → toggle override_get_worker, (3) confirm the spec URL returns 200 JSON directly, (4) confirm config('swagger') reflects your file after cache clear, (5) verify published assets were actually copied in the deployed release.
How can I help you explore Laravel packages today?