eminos/statamic-tabs
A Statamic addon that adds tabbed sections to publish forms, letting you group fields into clean, navigable tabs in the control panel. Keep long field sets organized and make editing easier with simple tab configuration.
Install the addon from your project root:
composer require eminos/statamic-tabs
php artisan vendor:publish --tag=statamic-tabs # only if the repo documents asset/config publishing
php artisan statamic:stache:clear
php artisan cache:clear
Statamic addons auto-register through package discovery, so there is usually no service provider to add to config/app.php. After install, open CP → Blueprints → (any collection) → Fields and confirm a Tab fieldtype appears in the fieldtype picker under the structural/container group. If it does not, the assets weren't rebuilt — run php artisan vendor:publish --force and hard-refresh the CP.
Where to look first
vendor/eminos/statamic-tabs/src/ — the fieldtype class (Tab.php or similar). This tells you the handle (tab), whether it is containable, and what it does on preProcess/augment.vendor/eminos/statamic-tabs/resources/js/ — the Vue component. This is the source of truth for how the tab bar is rendered and how sibling tabs are grouped.vendor/eminos/statamic-tabs/README.md — the only reliable place for the exact YAML shape, since the nesting convention differs from the core group fieldtype.First use case
Take the longest blueprint in the project — typically a Page or a global Settings set with 40+ fields — and split it into 3–4 logical tabs: Content, SEO, Settings, Advanced. You are not changing the data model, only the editing surface, so this is a safe first refactor. Verify a saved entry round-trips unchanged before rolling it into other blueprints.
YAML shape. The addon exposes a single containable fieldtype. In practice you stack one tab field per tab, and consecutive tab fields render as one tab bar:
tabs:
main:
display: Main
sections:
-
fields:
-
handle: content_tab
field:
type: tab
display: Content
fields:
- title
- slug
- content
-
handle: seo_tab
field:
type: tab
display: SEO
fields:
- meta_title
- meta_description
- og_image
-
handle: advanced_tab
field:
type: tab
display: Advanced
fields:
- canonical_url
- noindex
Confirm the sibling-vs-container convention against the Vue component before committing to it — a container shape (one tab field, with a tabs list inside) changes every blueprint you write, so settle this once, early, and record it in the repo's conventions doc.
Reuse through fieldsets. The highest-leverage pattern is to put the tab block in a fieldset (resources/fieldsets/seo.yaml) and import it in every blueprint that needs the same editor experience:
# resources/fieldsets/seo.yaml
title: SEO
fields:
- handle: seo_tab
field:
type: tab
display: SEO
fields: [ meta_title, meta_description ]
Imports keep tab order stable across collections and mean a label change happens in one file.
Localization. display is a normal Statamic display string, so display: 'site.tabs.content' works with resources/lang/en/site.php. Do this from day one on multilingual sites — retrofitting means touching every blueprint.
Companion pattern with conditionals. Fields inside a tab keep their if: / show_when behaviour, but the tab itself does not disappear when all its children are hidden. For settings-heavy blueprints, that leaves an empty pane. Either accept it, or gate the whole tab with visibility on the tab field using the same condition as its children.
Integration with the rest of the stack. Tabs are a structural fieldtype, so they hold no data and should not appear in:
augment/API output (check with curl against a GraphQL or REST endpoint — an empty key named after the tab handle means you need to filter it out),$entry->get('...') template code.If a tab handle does leak into output, filter it in config/statamic/api.php or a resource/transformer rather than editing the addon.
composer update, a new tab that "doesn't show" is almost always a stale stache or a cached CP bundle. Run php artisan statamic:stache:clear && php artisan cache:clear and hard-refresh before debugging anything else.tab.js/CP-hook snippet that activates the tab containing the first .has-error, or keep required fields in the first tab. Test this explicitly — it is the most common day-to-day complaint with any CP tab implementation.tab inside a Replicator set or Grid row multiplies the component per row and frequently fights the set's own field rendering. Keep tabs at the blueprint/fieldset top level unless the README explicitly blesses deeper nesting, and smoke-test set add/reorder if you try it.composer.json constraint against your Statamic major (4 vs 5 vs 6) before upgrading either. Pin with "eminos/statamic-tabs": "^1.0" in composer.json and review the changelog on every bump — you are effectively the QA for this addon in your project.resources/fieldsets/*.yaml for tab entries with empty fields.vendor/ — composer install will erase the latter.tabs: at the top level. Use the addon only where that native mechanism can't reach — imported fieldsets, nested groups, or third-party field bundles — otherwise you're adding a dependency for something the core already does.How can I help you explore Laravel packages today?