stillat/social-media-image-kit
Stillat's Social Media Image Kit helps Laravel/PHP developers generate social media share images, such as Open Graph cards and post previews, with tools for building and rendering customizable image templates.
This is a Statamic addon (v1.4.0 supports Statamic 3.x–6.x), so install it into an existing Statamic site rather than a bare Laravel app:
composer require stillat/social-media-image-kit
php artisan vendor:publish --tag=social-media-image-kit-config
Look at these first, in order:
config/social-media-image-kit.php — template name, route/URL prefix, image dimensions, and any driver/browser settings. This is the single place that determines what URL you will be embedding in your <head>.resources/views/social-media-image.antlers.html (or whichever template the config points to) — the Antlers view that is rendered to a PNG/JPEG. Everything visual (background, logo, title, tagline) lives here, not in PHP.routes/ in the addon — confirm the URL pattern the addon registers, since you will hard-code it into your layout.The first useful thing to build is a single OG image for a blog/news collection:
{{# resources/views/layout.antlers.html #}}
<meta property="og:image" content="{{ social_media_image url }}?id={{ id }}&v={{ last_modified }}">
<meta name="twitter:card" content="summary_large_image">
Then visit the generated URL directly in the browser. If the template renders as HTML for a moment before the image is produced, that is expected on a cold cache — the addon renders the Antlers template, screenshots it, and stores the result. Once you have one entry working, add the field to the blueprint or template loop and move on to the patterns below.
Template-per-context. Keep a base Antlers template and use Statamic's view resolution (or a template variable in the config / query string, depending on your version) to render a different layout per collection — e.g. social/blog, social/product, social/event. This keeps typography and brand assets consistent while letting each content type show the right fields.
Augmented entry data (new in 1.4.0). The headline change is that the template now receives an augmented entry, which means relationship fields and tag-driven data resolve properly inside the image template. Practical consequences:
{{ author:name }}, {{ hero_image:url }}, {{ categories }}{{ title }}{{ /categories }} now work without manually reaching into the entry's raw data or writing a custom tag.sponsor relationship is set) can be authored directly in the image template.{{ if tags }}
<div class="pill">{{ tags limit="1" }}{{ title }}{{ /tags }}</div>
{{ /if }}
Because augmentation is now happening, be deliberate about it — see the gotchas on performance.
Recreate from the Control Panel (new in 1.4.0). The CP action lets editors regenerate an image without touching the CLI. This is most useful in two scenarios:
Pair it with sensible cache-busting in the layout (?v={{ last_modified }}) so the new file is actually picked up by social scrapers.
Regenerate on save. For a hands-off workflow, hook into the entry saved event and clear/regenerate the cached image. Combined with the CP action, this gives you "automatic by default, manual override when needed."
Warm the cache on publish. Generated images are the slowest part of the request. For scheduled posts or imports, dispatch a job that requests the image URL (or calls the addon's generation routine) at publish time rather than letting the first social scraper eat the cold-start cost.
Shared meta partial. Put the og:image / twitter:image tags in one Antlers partial and include it from every layout, so the URL construction (and the v= cache-buster) lives in exactly one place.
Preview loop. While designing a template, keep the image URL open in a browser tab alongside the Antlers file and hard-refresh. Design at the target dimensions from the config, not at whatever size your browser renders — text that fits at 1200×630 often clips when the real renderer kicks in.
og:image must be an absolute URL. Relative paths silently fail on most scrapers. Use {{ social_media_image url }} or {{ url }} rather than a raw path.How can I help you explore Laravel packages today?