rokka/twig
A Twig extension for the Rokka image service that adds template helpers to generate image URLs and render optimized, dynamically processed images. Use Rokka stacks and transformation options directly in Twig views for responsive image markup.
Minimal steps
Install the package alongside your Twig setup:
composer require rokka/twig
It depends on the Rokka PHP client; if you need to construct the client yourself, require rokka/client explicitly.
Create/configure a Rokka image client with your organization and API key. Keep the API key server-side:
use Rokka\Client\Factory;
$client = Factory::getImageClient(
config('services.rokka.api_key'),
config('services.rokka.organization')
);
Register the Twig extension with the same Twig environment used by your views. In Laravel this usually means your TwigBridge/Twig integration, not Blade:
use Rokka\Twig\RokkaExtension; // confirm exact namespace in src/
$twig->addExtension(new RokkaExtension($client));
In a Laravel service provider, bind the client and extension as singletons so you do not rebuild them per render.
Look first at:
README.md for the exact Twig function/filter names and options.src/ for the extension class and the methods it exposes.composer.json for Twig/PHP version constraints.First use case
Render one image from a hash already stored in your database, using a named Rokka stack:
<img
src="{{ rokka_image_url(image.hash, 'card', { width: 640, format: 'webp' }) }}"
alt="{{ image.alt }}"
>
If your installed version exposes a tag helper instead, it may look like rokka_image(...); verify the callable names in the README before wiring templates. The key workflow is: upload/process in PHP, store the Rokka hash, and let Twig build public delivery URLs.
Keep uploads and URL generation separate
Do not upload images from Twig. Upload in a controller/job/service, persist the returned hash plus metadata (alt, dimensions, focal point), and pass those values to the view. Twig should only build URLs.
Use named stacks as your design system
Define stack names in config rather than embedding transformation options throughout templates:
// config/rokka.php
return [
'stacks' => [
'card' => ['width' => 640, 'format' => 'webp'],
'hero' => ['width' => 1600],
'thumb' => ['width' => 120],
],
];
Then keep template calls boring:
{{ rokka_image_url(image.hash, 'card') }}
This makes stack changes a config/deploy concern instead of a template-search concern.
Build responsive images with a Twig macro
Wrap repeated srcset logic once:
{% macro responsive(image, stack, widths, sizes) %}
<img
src="{{ rokka_image_url(image.hash, stack, { width: widths|last }) }}"
srcset="{% for w in widths %}{{ rokka_image_url(image.hash, stack, { width: w }) }} {{ w }}w{% if not loop.last %}, {% endif %}{% endfor %}"
sizes="{{ sizes }}"
alt="{{ image.alt }}"
>
{% endmacro %}
This is where the package earns its keep: templates stay readable while PHP owns configuration and image lifecycle.
Use the extension as a thin URL builder, not an API layer
The extension should be treated as a presenter for Rokka URLs. Avoid custom Twig functions that call the Rokka API on every render. If you need metadata lookup, cache it or resolve it before the view. Rokka hashes are content-addressed, so generated URLs are highly cacheable.
Laravel integration pattern
RokkaUrl service/helper, expose URLs through a view composer, or call the PHP client in your Blade model/presenter. Do not try to force the Twig extension into Blade.Testing pattern
Unit-test URL output with a Twig environment and the extension registered. Mock or stub the client where possible; do not hit Rokka in normal view tests. Assert the generated URL contains the expected organization, stack, hash, and options so upgrades do not silently change delivery URLs.
Low adoption means pin and verify
This package has 0 stars and 0 dependents. That does not make it unusable, but treat it as a small, pinned dependency. Pin a known version, read the release diff before upgrading, and keep a test that asserts generated URLs. Check composer.json constraints against your Twig version; Laravel Twig integrations often pin Twig independently.
Confirm the exact callable names
The extension is small, but function/filter names matter. If Twig throws “Unknown function” or “Unknown filter”, the extension is not registered on that environment, or you are using a different Twig instance than expected. Clear compiled Twig/view caches after registration changes.
Do not leak the API key
Rokka delivery URLs are public; the API key is for upload/admin operations. Keep the key in server-side env/config only. Do not pass it into Twig globals, JavaScript, or rendered HTML.
Organization, base URL, and custom domains
The default Rokka host may not match your custom CDN/domain, staging setup, or region. Check how the extension/client builds the base URL. A correct hash and stack can still produce a broken URL if the organization or host is wrong.
Validate stack options outside Twig
Invalid transformation options often surface as 404s or fallback images, not Twig exceptions. Keep option arrays in PHP config, validate them there, and avoid ad-hoc option arrays scattered across templates. Watch naming and types: booleans, arrays, format extensions, and crop/focal-point options must match Rokka’s expected syntax.
Escape HTML correctly
If you use a helper that returns a full <img> tag, mark it raw only when the content is trusted and the alt text is escaped. If you use a URL helper inside src/srcset, let Twig autoescape normally. Double-escaping & in URLs is a common self-inflicted bug.
Cache deliberately
Generated URLs are deterministic and cheap. Cache rendered fragments or image metadata, but remember that changing/deleting a stack can invalidate delivery even though the hash is unchanged. Version stack names when you need safe rollouts.
Debug by inspecting the URL first
When an image does not load, inspect the generated URL before debugging Twig: organization, stack name, hash, file extension, and query/options. Compare it with the Rokka dashboard or a manually built client URL. Then check Twig registration, cache, and escaping.
Extension points
If you need picture, art direction, signed URLs, or custom CDN behavior that the extension does not expose, write your own small Twig extension/macro around the Rokka client rather than forking. The package is a thin adapter; your application should own stack policy, caching, and responsive-image conventions.
How can I help you explore Laravel packages today?