zoerb/filerevbundle
zoerb/filerevbundle is a Symfony bundle for file revisioning and cache busting. It helps generate revisioned references to static assets so browsers fetch updated files after changes, simplifying asset versioning in Symfony applications.
This is a Symfony2 bundle, not a Laravel package — it registers a custom Symfony asset VersionStrategy (FilerevStrategy) that reads a rev-manifest.json (the format emitted by gulp-rev / grunt-filerev) and rewrites asset URLs to their hashed filenames. The "Laravel" analogy is a mix-manifest.json reader, but there is no service provider, facade, or config/assets.php hook — you wire it through Symfony's DI and asset packages.
Minimal steps:
composer require zoerb/filerevbundle (pin to the 2016-era Symfony ^2.3/^2.7 constraints; it will not install cleanly against Symfony 4+).app/AppKernel.php: new Zoerb\FilerevBundle\FilerevBundle().gulp-rev writing web/rev-manifest.json is the canonical source.default package or a dedicated one), then reference assets through {{ asset('css/app.css') }} in Twig.First use case: cache-busting a single bundled CSS/JS file in a Symfony2 app where the hashed filenames are produced at build time. Look first at the bundle's DependencyInjection/Configuration.php (for the manifest path/key options) and FilerevStrategy.php (to see the exact manifest JSON shape it expects and its fallback behavior).
Manifest-driven URL rewriting. The core pattern is: build tool hashes files → emits { "css/app.css": "css/app.8f3a1c.css" } → strategy looks up the logical path in the manifest and returns the hashed path. Any asset not present in the manifest is the tell that your pipeline and your manifest path are out of sync.
Gulp/Grunt build integration. Treat the manifest as a build artifact, not source. A typical workflow:
// gulpfile.js
gulp.task('rev', () =>
gulp.src('assets/**/*.{css,js}')
.pipe(rev())
.pipe(gulp.dest('web'))
.pipe(rev.manifest('web/rev-manifest.json'))
.pipe(gulp.dest('.'))
);
Then reference assets only via the strategy (through asset()) so every URL is rewritten consistently.
Dedicated asset package. Rather than replacing the default strategy globally, create a named package in config.yml and apply filerev to it. This keeps vendor/third-party assets on the default strategy while your compiled bundles get revisioned — important when you don't control the hashing of every asset on the page.
Environment scoping. Apply the strategy only in prod (and maybe staging) so local dev doesn't 500 or emit broken URLs when the manifest hasn't been built yet. In dev you generally want the plain asset path.
Deploy/CI wiring. Generate the manifest during the build step and commit it (or ship it as a release artifact) alongside the hashed files. Your deploy should rebuild hashes and regenerate the manifest in the same step — never hand-edit it.
Template-level usage. Once configured, existing asset('...') calls just work. If the bundle exposes a Twig extension, prefer it over concatenating paths so the lookup path stays centralized.
symfony/asset's JsonManifestVersionStrategy (essentially the same idea, first-party). If you're on Laravel, skip this entirely — mix()/Vite::asset() already does manifest-based rewriting.rev-manifest.json location or a web-root-relative vs. filesystem-path confusion. Log the resolved manifest path once and verify it exists.css/app.css), sometimes with a leading / or build/ prefix. A leading-slash mismatch produces misses that look like "the strategy isn't registered" when it actually is.php artisan vendor:publish, and there's no config file to publish — configuration goes through Symfony's DI/config loader (config.yml, XML, or YAML). Don't expect a config/filerev.php.StaticVersionStrategy expecting both to run.applyVersion(). Given the low star count and age, expect little documentation — reading the ~2 service classes is faster than searching for help.How can I help you explore Laravel packages today?