juststeveking/laravel-redoc
Laravel Redoc makes it easy to serve beautiful API documentation in your Laravel app using Redoc. Point it at an OpenAPI/Swagger spec, customize the route and view, and publish interactive docs with minimal setup.
Prerequisite (the only real one): you need a valid OpenAPI 3.x or Swagger 2.0 document — YAML or JSON, local or remote. If you don't have a spec, stop and produce one first (Scramble, l5-swagger, or a hand-maintained contract file). The package renders a spec; it does not generate one.
Install and publish:
composer require juststeveking/laravel-redoc
# list tags first — tag names vary by package version
php artisan vendor:publish
Publish the config (typically config/redoc.php) and point it at your spec:
// config/redoc.php — illustrative; confirm exact keys in the published file
return [
'title' => env('REDOC_TITLE', 'API Reference'),
'spec' => env('REDOC_SPEC', resource_path('openapi.yaml')),
'route' => env('REDOC_ROUTE', 'docs'),
// ReDoc display options, Alfred flag, etc.
];
Where to look first:
config/redoc.php — route path, page title, spec location, ReDoc options. This is the whole package surface.<script> and the spec URL are wired up.route:list — confirm the route registered and that it doesn't collide with an existing /docs or /api/documentation.First use case: visit the configured route in a browser and confirm the sidebar of endpoints renders. That's your smoke test — if the page loads but the spec is empty, 99% of the time the spec URL is unreachable from the browser (see Gotchas). Day-one value is an internal API reference for your own team: endpoints, schemas, examples, auth notes — read-only, no build step, no separate docs site to deploy.
Local spec, committed to the repo. Keep openapi.yaml (or openapi.json) in resources/ or a docs/ directory and reference it from config. The spec becomes a versioned deliverable that moves in the same PR as the API change. This is the pattern that ages best — review the spec diff alongside the code diff, and the docs stop drifting.
Remote / CI-published spec. If the spec is generated in CI or lives in a docs bucket, point the config at its URL. Useful for monorepos that generate specs per service, and for keeping the spec out of the app repo. The tradeoff: the docs page now depends on an external host being up and CORS-open. Verify Access-Control-Allow-Origin from the docs page's origin before relying on it.
Gate internal docs behind auth. Most teams don't want an internal API reference public. Add middleware by wrapping or configuring the route (per the package's route config) — e.g. ['web', 'auth'] — so internal API surfaces are only visible to logged-in staff. This is a config change, not a fork.
Environment-driven configuration. Drive title, spec, and route through env() so staging renders the staging spec and production renders production. Keep the spec path relative/resolved at runtime where possible, because absolute paths baked into config break under config:cache on a different host.
Generate from annotations, render with Redoc. Common stack: dedoc/scramble or l5-swagger emits the OpenAPI JSON, and this package renders it. That splits concerns cleanly — the generator owns spec correctness, this package owns the presentation. You still get the forcing function of OpenAPI-as-contract, which unlocks SDK generation and contract testing later.
Alfred opt-in (2.1.0+). Treat it as an experiment, not a default. Wire it to an env flag, default off, and enable per environment only after a CSP / data-egress review. Run it on an internal or non-public docs surface first and measure engagement and ticket deflection before considering a customer-facing rollout.
Validate the spec in CI. Add a step that fails the build on an invalid OpenAPI document (@redocly/cli lint or openapi-validator). A broken spec renders as an empty or half-broken page, and it's much cheaper to catch in CI than in a support ticket.
Content-Type: application/yaml. Open devtools → Network and confirm the spec URL returns 200 with the right content type. This is the #1 empty-page cause.config:cache and route:cache. The usual failure mode for config-gated view packages. After editing config, run php artisan config:clear; in deploy pipelines verify behaviour with caches warm (spec resolves, route is registered, title renders). Test in a cached state before you ship.script-src/connect-src/style-src policy will break it. Add the CDN origin to your policy (or host the bundle yourself if you need to be offline/air-gapped). Note the ReDoc bundle version is outside your composer.lock — pin or record it in your dependency inventory.$ref resolution. ReDoc accepts both, but relative $refs resolve against the spec's served URL. If you serve the spec from a temporary route or a signed URL, cross-file $refs break. Keep the spec at a stable, predictable URL.l5-swagger, Scribe, or Scramble, check route:list for a clash and decide deliberately whether you want two docs surfaces (usually you don't).config:cache is not serving stale config, (5) the route isn't shadowed by a middleware redirect to login. That sequence isolates nearly every failure.How can I help you explore Laravel packages today?