jezzdk/statamic-kontainer
A Statamic addon for Laravel projects that adds Kontainer support, helping you organize and manage reusable content containers in the control panel. It integrates with Statamic’s field and content APIs for flexible, developer-friendly content structures.
Install and wire it up
composer require jezzdk/statamic-kontainer
php artisan vendor:publish --provider="Jezzdk\Kontainer\ServiceProvider" # publish config/assets if offered
php please cache:clear
Then, in order:
src/Fieldtypes/*.php and check process() / preProcess(). The single most important thing to learn on day one is whether the saved value is a Kontainer asset ID, a full URL, or an array of metadata. Everything downstream (Antlers, augmentation, caching, imports) depends on this.# resources/fieldsets/hero.yaml
title: Hero
fields:
-
handle: hero_image
field:
type: kontainer
display: Hero image
# container/folder/max-files style options: verify exact keys in src/Fieldtypes
First use case: a marketing hero image or press/logo asset on a Page collection — approved brand media that lives in the DAM and must not be re-uploaded into assets/. That's the cheapest end-to-end test: select in CP → preview renders → save → inspect the YAML in content/collections/pages/*.md → render on the front end.
Where to look first (in this order): the fieldtype class (preload() tells you what the Vue component receives), the Vue component under resources/js/components/fieldtypes/, the config file, then the README. With a package this small and this thinly documented, the source is the documentation.
Fieldtype as the only integration surface. Treat this addon as "a picker plus a reference," not as a media pipeline. The realistic pattern:
Resolution + caching pattern (adjust to the actual stored shape):
// app/Tags/KontainerAsset.php — or an augmentor on the field
public function url(): string
{
$ref = $this->context['hero_image'] ?? null;
if (! $ref) {
return '';
}
return Cache::remember("kontainer:{$ref}:url", now()->addDay(), function () use ($ref) {
return app(\Jezzdk\Kontainer\Kontainer::class)->asset($ref)['url'] ?? '';
});
}
If the addon ships no client/service binding, instantiate its HTTP wrapper directly or (simpler, and often safer) call Kontainer's REST API from your own thin service class and use the addon purely for the CP picker.
Consistent fieldsets across collections. Define the Kontainer field once in resources/fieldsets/ and import it into every collection that needs approved media. This is also the cheapest way to later restrict containers/folders per context (e.g. a "Brand" folder for the About page, a "Campaign" folder for landing pages) without touching content.
Coexistence with Statamic's native asset field. Use assets for things editors upload ad hoc (PDFs, per-page images) and kontainer for centrally governed media. Mixing them on the same fieldset is normal and encouraged — don't try to force everything through the DAM.
Seeding/importing content. Because the value is a plain reference, you can write it straight into content YAML from a migration or importer. Do a dry run against one entry and diff the resulting markdown file before writing a bulk importer; if the fieldtype stores extra JSON, your importer must reproduce that shape exactly or the CP field will load as empty even though the data is "there."
Globals for site-wide assets. Logos, OG defaults, and favicons belong in a global set using the Kontainer field — one reference, one cache key, one place to update when the DAM asset changes.
composer.json and expect to read the source. Budget for the possibility that you maintain a fork; a Statamic major upgrade will likely break it and no fix may arrive.assessment-pm.md does not describe this package. It talks at length about read_only enforcement and model attributes — that's a different project's notes. Ignore it entirely; it is not evidence about this addon's behavior, and it inflates the apparent "score" misleadingly. Verify every capability against the code.{{ hero_image }} renders an <img> — dump the value from a template first.resources/addons/ and get committed. If the addon supports env vars in its config, use them; otherwise confirm the credential file is gitignored or the key is scoped read-only.Cache::remember keys silently serve stale media. Define an invalidation story (short TTL, or a webhook/hook that flushes by reference ID).preload() to pass extra config to Vue, process()/preProcess() to normalize the stored shape), publishable views/config, and the Vue component if you need a different picking UX. Since the surface is small, a subclassed fieldtype is usually cleaner than patching the vendor file.How can I help you explore Laravel packages today?