holadev/amp-toolbox-bundle
A Symfony bundle integrating AMP Toolbox to transform, optimize, and validate AMP HTML. It provides services for server-side AMP rendering, performance enhancements, and validation workflows, helping you deliver faster, mobile-friendly pages with less setup.
This is a Symfony bundle, not a Laravel package. Confirm you're on Symfony (5.x/6.x era) before anything else; a Laravel developer cannot composer require this and expect it to wire up. On Laravel, treat the repo as a reference implementation for wiring ampproject/amp-toolbox into a service container, and port the small amount of glue yourself.
v0.1.6 is the release that finally matters. It bumps ampproject/amp-toolbox from ^0.1 to ^0.11.2 — a jump across roughly two years of the underlying library's evolution. That makes this the first version worth installing, and also the first version that behaves differently from every snippet and tutorial written against the bundle before it. If you evaluated this package previously and bounced off the stale dependency, re-evaluate.
For Symfony users:
composer require holadev/amp-toolbox-bundle:^0.1.6 — but first run composer why-not ampproject/amp-toolbox 0.11.2 against your platform. The 0.11 line expects PHP 7.4+/8.x and ext-dom; older PHP pins will block the install and Composer will quietly resolve you back to an older bundle release with the old library.Holadev\AmpToolboxBundle\AmpToolboxBundle in config/bundles.php.DependencyInjection/Configuration.php, and vendor/ampproject/amp-toolbox/src/Optimizer/Configuration.php from the version you actually installed. As of v0.1.6 the bundle's tree is a thin re-key of the library's, so the library file is the authoritative schema and the bundle file is just the mapping into it. Diffing the two is the fastest way to spot a config key the bundle doesn't expose.If a service definition for what you need doesn't exist, instantiate AmpProject\Optimizer\TransformationEngine directly with an AmpProject\Optimizer\Configuration. The bundle's value is convenience, not unique capability — and with 0.11.2 underneath, the direct-library path is now genuinely viable.
Response listener pattern (most common). A kernel.response listener that checks Content-Type plus an AMP marker (request attribute, or a <html amp> check), pulls $response->getContent(), transforms it, and calls setContent(). Guard non-HTML responses, streamed responses, and HEAD requests.
Service injection into controllers. Inject the engine (or your own thin wrapper) and call the transform before building the Response. Most testable form, no listener-ordering surprises. With 0.11.x you can pass a per-call Configuration override, which makes A/B-ing transformer sets trivial.
Twig extension. An amp_optimize filter is handy for partials, but the optimizer performs whole-document transformations — filters on fragments will not do boilerplate removal or runtime preloading. Treat it as a utility, not the integration point.
CLI / build-time optimization. For static AMP sites, wrap the engine in a Symfony command that globs .html files, optimizes, and writes them back. Sidesteps runtime cost and is the safest production pattern for high-traffic pages. It's also the pattern that makes the v0.1.6 upgrade cheap to validate: run it over your corpus and diff.
Configuring transformers. The 0.11.x Configuration is keyed by transformer FQCN, and Configuration::DEFAULT_TRANSFORMERS gives you the stock set. Configure via the bundle's tree where it exposes a transformer; otherwise override the service with your own Configuration instance. Disable what you don't use — image optimization and amp-img SSR are the expensive ones and often duplicate CDN work.
Custom transformers. Implement AmpProject\Optimizer\Transformer\Transformer and register alongside the built-ins. Cleanest way to add org-specific preconnect or preload logic without forking. In 0.11.x registration is by FQCN, so your class names become part of your config surface — namespace them deliberately.
Caching. Optimization is deterministic given input HTML plus config. Cache keyed by a hash of the source plus a version constant that includes both the bundle version and the amp-toolbox version — v0.1.6 would otherwise serve stale output from a v0.1.5-populated cache after deploy. Invalidate on deploy; a listener pattern with no cache adds meaningful latency to every request.
Testing. Snapshot the transformation: fixture AMP document in, assert stable optimized output out. When upgrading, keep a pre-upgrade fixture set and diff it against the new output — that diff is your entire changelog for a dependency jump this large.
0.1.5 → 0.1.6 reads as a patch, but it swaps a major transitive dependency. A routine composer update will drag production across it silently. Pin the bundle and ampproject/amp-toolbox explicitly, commit the lock, and put the fixture diff in CI before you let it through.Configuration is keyed by transformer class name; the old short-name keys are ignored rather than rejected. You get valid-looking output with transformers you thought you'd configured quietly not running. Dump the constructed Configuration in a debug command and assert the transformer count and names.Optimizer entry point became TransformationEngine; transformHtml()'s signature and the Document/Dom\Document helpers moved. Any code copy-pasted from pre-2021 blog posts will fatal or, worse, half-work. Verify against vendor/ — not against the docs site, which tracks latest.ErrorCollection for a sample of pages during rollout, and fail closed in staging. Silent transformer failure plus no error surfacing is how you ship invalid AMP and find out in Search Console weeks later.ampproject/amp-toolbox (Apache-2.0) avoids the wrapper's copyleft entirely if you only need the optimizer; porting the ~200 lines of glue is often the pragmatic path. Get legal sign-off either way.artisan will never load the bundle class.debug:event-dispatcher kernel.response.How can I help you explore Laravel packages today?