TechEarl

ACF Field Naming Conventions That Actually Scale

A few naming conventions for ACF field groups, field names, and field keys keep a multi-year codebase navigable: snake_case names, hierarchy-encoded keys, post-type prefixes, sub-field consistency. The cost is zero; the benefit compounds.

Ishan Karunaratne⏱️ 6 min readUpdated
Share thisCopied
Naming conventions for ACF field groups, field names, and field keys that keep a multi-year codebase navigable. Real patterns from directory-scale work.

ACF gives you complete freedom in how you name field groups, field names, and field keys. That freedom is the trap. A few conventions kept consistently across a multi-year codebase make the difference between "I can find this field in five seconds" and "I have to grep the whole repo and the database to figure out what controls this." Cost of conventions: zero. Benefit: compounds across every team member, every refactor, every audit, every WP-CLI script for years.

Jump to:

Field names: snake_case, lowercase, no abbreviations

Field names appear in wp_postmeta.meta_key, in template code as get_field( 'name' ), in update_field calls, and in WP-CLI queries. They are the most-used identifier across the codebase.

The convention:

  • snake_case. hero_heading, not heroHeading, Hero_Heading, or hero-heading.
  • Lowercase only. ACF is case-sensitive, and inconsistent casing is the source of "the field returns nothing" bugs.
  • No abbreviations. description not desc, featured_image not feat_img. Two extra characters today saves five minutes of confusion next year.
  • Singular for single-value fields, plural for arrays. author for a Post Object field, authors for a Relationship or Repeater of authors.
  • No leading underscore. Underscored meta keys are conventionally hidden from the WordPress admin meta box list; ACF uses _fieldname for its field-key reference rows, and your own field names should not collide.

Examples:

GoodBad
hero_headingheroHeading, Hero_Heading
featured_imagefeat_img, featuredImg
team_membersteam_member_list, members
is_featuredfeatured_flag, feat
event_start_datestart, startDate

Field keys: hierarchy-encoded and globally unique

Every ACF field has a unique key (field_abc123...) that identifies it across the system. You can let ACF auto-generate keys, but if you register field groups via PHP, choosing readable keys yourself helps debugging immensely.

The convention I use:

  • group_ prefix for field group keys. group_listing_core.
  • field_ prefix for field keys. field_listing_hero_heading.
  • layout_ prefix for Flexible Content layout keys. layout_listing_stat_row.
  • Hierarchy encoded in the key. A field inside the stat_row layout of the page_builder Flexible Content field on the listing post type might be field_listing_pb_stat_row_label. The prefix encodes where it lives.

Why this matters: when you see a _fieldname reference in wp_postmeta pointing at field_listing_pb_stat_row_label, you know immediately what field that is and where it is defined. Auto-generated keys (field_5f8a1b3c2d4e5) require you to look them up against the field group registration.

Example registration:

php
acf_add_local_field_group( [
    'key' => 'group_listing_core',
    'title' => 'Listing Core',
    'fields' => [
        [
            'key' => 'field_listing_hero_heading',
            'name' => 'hero_heading',
            'type' => 'text',
        ],
        [
            'key' => 'field_listing_page_builder',
            'name' => 'page_builder',
            'type' => 'flexible_content',
            'layouts' => [
                'layout_listing_pb_hero' => [
                    'key' => 'layout_listing_pb_hero',
                    'name' => 'hero',
                    'sub_fields' => [
                        [
                            'key' => 'field_listing_pb_hero_heading',
                            'name' => 'heading',
                            'type' => 'text',
                        ],
                    ],
                ],
            ],
        ],
    ],
] );

The keys read top-to-bottom as a path: field_listing_pb_hero_heading is "the heading field inside the hero layout of the page_builder field on the listing post type." Self-documenting.

Field group keys: post-type prefixed

Group field groups by the post type they belong to. group_listing_core, group_listing_meta, group_listing_seo. When you have 20+ field groups across the site, prefixing makes them sortable in the admin UI and easy to find in the JSON-sync directory.

Avoid:

  • Generic names like group_main, group_settings, group_fields. They tell you nothing.
  • Project-prefixed names like group_acme_listing_core. The project context is the entire repo; restating it in every key is noise.

Sub-field naming inside Repeaters and Flexible Content

Sub-field names live in their parent context (a sub-field label inside the stats Repeater is only label from that context). So the SHORT name in the sub-field is fine: label, value, unit: but the KEY should encode the full hierarchy: field_listing_pb_stat_row_stats_label.

Why: when you read wp_postmeta, you see meta keys like page_builder_2_stats_3_label. The corresponding _field_key reference row points at the field key. If the key is descriptive, you immediately know what label means in context. If it is auto-generated, you have to chase the reference.

The same logic applies to ACF Block sub-fields, Group field children, and any other nesting structure.

True/False fields: prefix with is_ or has_

Naming convention specifically for True/False fields:

  • is_featured: boolean state of the post.
  • has_video: boolean presence of related content.
  • should_index: boolean instruction to other code.
  • allow_comments: boolean permission.

The prefix tells the reader "this is a boolean, not a string." get_field( 'is_featured' ) reads naturally; get_field( 'featured' ) is ambiguous about what type comes back.

Avoid generic boolean names like flag, option, setting, enabled. They tell you nothing about what is being toggled.

Avoid these patterns

A non-exhaustive list of antipatterns I have seen on inherited codebases:

  • CamelCase field names. HeroHeading. Inconsistent with WordPress meta key conventions, hard to type, breaks get_field lookups when someone tries heroHeading.
  • Field names with hyphens. hero-heading. PHP variable rules do not allow hyphens; you cannot do $post['hero-heading'] directly. snake_case is friendlier.
  • Numbered field names. image_1, image_2, image_3. Use a Repeater. Numbered fields cannot be iterated cleanly.
  • Single-letter prefixes. f_heading, s_subtitle. Saves three characters; costs your sanity.
  • Auto-generated keys for hand-registered field groups. If you write PHP registration, write descriptive keys. The auto-generated field_5f8a1b3c2d4e5 is fine for editor-managed field groups but terrible for code-managed ones.
  • Duplicate field names across post types with different shapes. Two post types both have a details field; one is a Repeater, the other is a wysiwyg. Cross-post-type code is now confused.

The local-JSON convention

ACF supports local JSON: drop field group export JSON files into your theme's acf-json/ directory and ACF auto-syncs them. The filename follows the field group key: group_listing_core.json.

The benefit: field group changes go through git. Editors edit fields in wp-admin; ACF saves the JSON; you commit the JSON. Different developers see each other's field group changes in the diff just like code.

The convention I add:

  • Keep acf-json/ at the theme root, not in mu-plugins. ACF defaults to the active theme's directory.
  • One JSON file per field group, named after the group key.
  • Do NOT also register field groups via PHP for the same field group. Pick one source of truth.

For the broader pattern of agency-scale ACF organization, see Using ACF Like a Lightweight Component System. For the AI-assisted scaffolding of new field groups following these conventions, see Using Claude CLI to Manage WordPress Sites.

Sources

Authoritative references this article was fact-checked against.

TagsWordPressACFArchitectureConventions

Found this useful? Pass it on.

Copied

Ishan Karunaratne

Tech Architect · Software Engineer · AI/DevOps

Tech architect and software engineer with 20+ years building software, Linux systems, and DevOps infrastructure, and lately working AI into the stack. Currently Chief Technology Officer at a healthcare tech startup, which is where most of these field notes come from.

Keep reading

Related posts