nucleos/shariff-bundle
Symfony bundle that integrates Shariff, the privacy-friendly social sharing buttons. Adds share buttons for popular networks without tracking users, with configurable services, templates, and styling. Easy to install and customize for Symfony applications.
A word before you start: this bundle is archived (3.3.0, December 2021, was the final release) and has no meaningful dependents. It still works as a thin Symfony wrapper around heise/shariff, and 3.3.0 modernised its support matrix to PHP 8.0+ and Symfony 5.4/6.0 (Symfony 4 and PHP 7 were dropped). That means it is genuinely usable on a Symfony 6 app without --ignore-platform-reqs hacks — but Symfony 7, PHP 8.3 tooling and any future security fixes are off the table. For a greenfield project, seriously consider wiring shariff-php (the backend) plus the @heise/shariff JS/CSS yourself — it is a few dozen lines and removes the abandoned dependency. Use the bundle if you already have a Symfony 5.4/6 app and want the Twig glue, the DI wiring and the count controller for free.
Minimal setup:
Install the package and its backend:
composer require nucleos/shariff-bundle heise/shariff
If Flex doesn't auto-register it, add Nucleos\ShariffBundle\NucleosShariffBundle::class => ['all' => true] to config/bundles.php.
Create config/packages/nucleos_shariff.yaml. This is where all the real work happens — the bundle mostly maps this file into a Heise\Shariff\Backend instance plus a Twig extension:
nucleos_shariff:
services:
- Facebook
- Reddit
- Twitter
- Whatsapp
cache:
ttl: 3600
Only enable services you actually want counts from; each one adds an outbound HTTP call per uncached count request.
Publish Shariff's frontend assets. The bundle ships the PHP side, not the JS/CSS. Grab them from npm (@heise/shariff or the heise/shariff package) and copy shariff.min.js / shariff.min.css into public/. There is no assets:install magic here.
Render buttons in a Twig template — this is the first use case you'll hit:
{{ shariff() }}
The Twig function emits the <div class="shariff" data-services="..." data-backend-url="..."> markup pointing at the bundle's built-in count endpoint. Include the JS/CSS you published and Shariff handles the rest.
Where to look first in the source: DependencyInjection/Configuration.php (the config schema), the Shariff controller (the /shariff count endpoint), and the Twig extension (rendering + defaults).
Server-side counts, not client-side. The whole point of Shariff is privacy: the browser never talks to Facebook/Twitter directly. The bundle registers a controller (typically under a path like /shariff) that the JS calls, and the controller delegates to Heise\Shariff\Backend, which fetches counts from the enabled services. Keep that route behind your normal firewall/anonymous access rules as appropriate.
Override the default markup via a Twig partial. Rather than fighting the Twig function's options, render your own <div class="shariff"> in a reused partial (templates/_shariff.html.twig) and pass data-services, data-theme, data-orientation, data-url. This is the pattern that ages best if you later drop the bundle.
Configuration-as-deployment. Keep the service list in nucleos_shariff.yaml per environment. In dev you may want cache.ttl: 0 so you're not staring at stale counts while iterating; in prod set a longer TTL (e.g. 3600) because most share-count APIs rate-limit aggressively.
Caching backend. shariff-php caches via a CacheInterface. The bundle wires its own adapter by default. If you run multiple web nodes, configure a shared cache (or override the cache adapter service) so counts are consistent and you don't hammer external APIs from every pod.
CSP and privacy policies. Because everything is same-origin, you usually don't need connect-src allowances for social networks — that's the selling point. But do add the Shariff CSS/JS to your CSP script-src/style-src self allow-list, and document the single /shariff endpoint in your privacy notice (some auditors want it named).
Testing. You don't want unit tests hitting Facebook. Override the Heise\Shariff\Backend service in config/services_test.yaml with a stub returning fixed counts, or skip the Twig function in tests and assert on config/markup instead. The bundle's own services are constructor-injected, so a decoration of the backend service is the clean seam.
LogicException when the Twig block is rendered with no template configured. If you call the block-rendering entry point directly (rather than {{ shariff() }}), make sure the template option is set — the older failure mode was a silently-empty render, so a hard exception can surface as a new 500 after upgrade. It's a good failure, but it is a behaviour change.facebook, twitter (now X), and google share-count APIs have changed dramatically since 2021. Google+ is dead, X's count endpoint has been restricted, Facebook's Graph count changed. Expect some configured services to silently return 0 — that is not a bundle bug, it's upstream API rot. Verify each service's count endpoint independently with curl before blaming the integration.div but nothing visible appears until shariff.min.js runs. Check the browser console for a 404 on the JS/CSS first.shariff-php fetches counts with cURL. In a minimal Docker image without ext-curl you get empty counts and only a log line. Verify php -m | grep curl.curl 'https://yoursite/shariff?url=https://example.com/article') to see whether the problem is frontend wiring or the backend fetch. Shariff's JS will happily render 0 with no error.config/services.yaml rather than patching the vendor directory. This is the one real advantage over using shariff-php directly — you get DI wiring and Twig defaults for free.Heise\Shariff\Backend as a service yourself, expose a small controller returning json_encode($backend->getCounts($url)), and render the markup in Twig with no bundle at all. You lose ~nothing — the bundle's surface is a config tree, one controller and one Twig function — and gain Symfony 7 / PHP 8.3+ support. Doing this on 3.3.0 while it still works is far cheaper than doing it under pressure later.How can I help you explore Laravel packages today?