New: ShopBar Theme — faster, lighter, refreshed

See what's new
WordPress

Add Custom Fields to WordPress Media (3 Working Ways)

Editor Team

Spiracle Themes

12 min read

WordPress stores every image, PDF and video as a post of type attachment, which means it can hold custom fields exactly like a post can. What it does not give you is a screen to type them into. There is no “custom fields” panel on the media library, and the attachment editor is deliberately minimal.

So you have three ways to add a custom field to WordPress media: a small free plugin if you need one or two plain text fields, a field framework like ACF or Meta Box if you want a proper editing UI, or roughly twenty lines of code using two filters that still ship in WordPress 7.1. This guide covers all three, with the code that actually works on current WordPress and the traps that break each approach.

Key takeaways

  • Media files are posts of type attachment, so their custom fields live in wp_postmeta keyed to the attachment ID.
  • WordPress has no built-in UI for media custom fields. You need a plugin, a field framework, or the attachment_fields_to_edit / attachment_fields_to_save filters.
  • ACF’s Attachment location rule (available since ACF 5.6) puts fields on the attachment edit screen and in the Add Media modal, which is why most agencies use it instead of custom code.
  • Custom field values survive theme changes; the templates that display them do not. Read them with get_post_meta( $attachment_id, 'key', true ), not with image size functions.

Why the media library has no custom fields panel

When you upload a file, WordPress inserts a row in wp_posts with post_type = 'attachment', then stores the file path, dimensions and EXIF data as a serialised array in the _wp_attachment_metadata post meta key. Everything else about that file — title, caption, description, alt text — is a column on the post row itself.

Because the attachment is a post, add_post_meta() and update_post_meta() work on it immediately, with no registration step. The gap is purely in the interface: the media modal exposes only the core fields, and the block editor’s media modal is a React application that does not render arbitrary meta boxes.

That last point is where most tutorials fall apart. Code written for the classic editor’s Insert Media modal will appear to do nothing on a modern block-editor site, because the block editor replaced that modal entirely. The filters below still work — they fire on the classic media screens and anywhere that uses wp-admin/includes/media.php — but they will not paint fields inside the Gutenberg media modal. If you need fields there, use ACF or a plugin built for it.

What people actually store in a media custom field

Before choosing a method, be clear about what the field is for. The patterns that come up repeatedly:

  • Photographer or source credit — a licence requirement on stock and editorial images.
  • Licence and expiry — “Creative Commons BY-SA, expires 2027-04” so you can audit what has to come down.
  • Per-image call to action — a link and button label stored on the image, rendered by the theme instead of hardcoded in the template.
  • Consent or model-release status — a checkbox recording that a person in the photo signed off.
  • Alt text audit flags — a value that marks images as “alt text reviewed” so you can find the ones that were never checked.

If your need is alt text, captions or compression, you do not need a custom field at all — a media library hygiene plugin handles that, and media hygiene tooling is the right starting point. Custom fields are for metadata that is specific to your site.

Method 1: The dedicated plugin (fastest, one or two fields)

There is a plugin named almost exactly after this problem: Add Custom Fields to Media. It is free, currently at version 2.0.4 (last updated March 2026), and has around 80 active installations. It adds a set of fields to the media uploader and lets you output them in template files with a short helper function — the documented use case being copyright and image meta.

Install it from Plugins ? Add New, then open any image in the media library. The extra fields appear in the attachment details panel. Save, then output them in a template with the plugin’s function, passing the attachment ID.

The honest caveats. Two reviews and eighty active installs is a thin safety net. If the plugin stops being maintained, your data does not disappear — it is ordinary post meta — but the editing UI does, and you will be back to writing code or moving to ACF. Use it when you need one text field on a few hundred images and you are comfortable reading PHP if it breaks. Do not build a design system on it.

For comparison, Custom Field Suite, the older free alternative that many tutorials still recommend for this job, is now closed on WordPress.org. Anything recommending it is out of date.

Method 2: ACF or Meta Box (best for editors)

If non-developers will be entering this metadata, use a field framework. Both of the major ones support attachments natively, and both keep the data in wp_postmeta, so switching later is a migration, not a rewrite.

Adding an attachment field group in ACF

  1. Go to ACF ? Field Groups ? Add New.
  2. Add your fields — a text field for the credit, a select for the licence, a true/false for consent.
  3. Under Location Rules, choose Attachment and set it to All, or narrow it to a specific MIME type such as image if the field only makes sense for images.
  4. Publish the field group.

ACF documents three places where the fields then appear: the attachment edit screen reached from Media ? Library, the Add Media modal while editing a post, and any ACF image or file field that selects the attachment. Values are read with the second parameter set to the attachment ID:

$credit = get_field( 'photo_credit', $attachment_id );
if ( $credit ) {
    echo '<span class="credit">' . esc_html( $credit ) . '</span>';
}

ACF free covers text, select and true/false fields. ACF PRO costs $49/year for one site, $149/year for ten, or $249/year unlimited, and adds repeaters, flexible content and clone fields — worth it only if you need structured, repeating metadata per image.

Adding an attachment field group in Meta Box

Meta Box takes the same approach: create a field group, set the location to Post type ? Media, and assign fields. Meta Box 5.15.3 was updated in October 2026 and runs on about 500,000 sites with a 96% rating. The Basic bundle is $149/year, the Ultimate bundle $229/year, and a $699 one-time lifetime licence is available.

Choose between them on workflow, not features: ACF has the larger install base and more third-party integrations, Meta Box is cheaper if you also want its custom post type and settings-page builders bundled in.

Approach Cost Editor UI Works in block editor media modal Best for
Custom code (filters) Free Classic media screens only No Developers, one or two fields, no plugin bloat
Add Custom Fields to Media Free Yes, attachment details panel Depends on modal support A few text fields on a modest library
ACF (free) Free Yes Yes, per ACF documentation Sites already using ACF
ACF PRO $49–$249/yr Yes Yes Repeating or structured metadata
Meta Box $149–$229/yr, or $699 lifetime Yes Yes Sites that also need CPTs and settings pages

Method 3: Twenty lines of code, no plugin

If you can edit a theme’s functions.php — or better, a small site-specific plugin — the core filters are all you need. Both of the following are confirmed present in current WordPress core (attachment_fields_to_edit and attachment_fields_to_save in wp-admin/includes/media.php).

First, add the field to the attachment form:

add_filter( 'attachment_fields_to_edit', function ( $form_fields, $post ) {
    $form_fields['st_credit'] = array(
        'label' => __( 'Photo credit', 'your-textdomain' ),
        'input' => 'text',
        'value' => get_post_meta( $post->ID, '_st_credit', true ),
        'helps' => __( 'Shown under the image on the front end.', 'your-textdomain' ),
    );
    return $form_fields;
}, 10, 2 );

Then save it when the attachment is updated:

add_filter( 'attachment_fields_to_save', function ( $post, $attachment ) {
    if ( isset( $attachment['st_credit'] ) ) {
        update_post_meta( $post['ID'], '_st_credit', sanitize_text_field( $attachment['st_credit'] ) );
    }
    return $post;
}, 10, 2 );

Note the asymmetry that catches people out: the edit filter receives an object ($post->ID), the save filter receives an array ($post['ID']). Returning the wrong shape from the save filter silently drops your value.

Displaying the value

Read it back wherever the image is rendered. For a featured image that means resolving the thumbnail first:

$thumb_id = get_post_thumbnail_id();
$credit   = get_post_meta( $thumb_id, '_st_credit', true );

if ( $credit ) {
    printf( '<span class="photo-credit">%s</span>', esc_html( $credit ) );
}

Inside a media library loop, the attachment ID is already in scope, so the call is just get_post_meta( get_the_ID(), '_st_credit', true ). The _st_ prefix matters: the leading underscore hides the key from the default Custom Fields panel, so editors cannot accidentally overwrite it.

To make the field visible while browsing the library, add a column:

add_filter( 'manage_media_columns', function ( $cols ) {
    $cols['st_credit'] = 'Credit';
    return $cols;
} );

add_action( 'manage_media_custom_column', function ( $col, $id ) {
    if ( 'st_credit' === $col ) {
        echo esc_html( get_post_meta( $id, '_st_credit', true ) );
    }
}, 10, 2 );

Which method should you use?

Answer three questions and the choice makes itself:

  • Will someone who does not write code enter this data? Use ACF or Meta Box. Custom code with no UI means every new image needs a developer or WP-CLI.
  • Do you need the field inside the block editor’s media modal? Use ACF or Meta Box. The legacy filters will not render there.
  • Is this one text field on a small, fixed library? Use the free plugin or the snippet. Adding a field framework for a single credit line is overkill.

Troubleshooting

The field appears in the classic media modal but not in the block editor

Expected behaviour, not a bug. The block editor’s media modal does not call the classic attachment fields API. This is not a matter of a missing hook — the rendering path does not exist. Move to ACF, or edit the attachment from the Media Library screen, which still uses the classic form.

The value saves but comes back empty on the front end

You are almost certainly reading meta from the post ID instead of the attachment ID. On a post with a featured image, the two are different numbers. Log get_post_thumbnail_id() and compare it to the attachment ID you edited.

Fields disappear after switching themes

The values are still there — they are rows in wp_postmeta, tied to the attachment, not the theme. What broke is the template that printed them. Keep the display code in a site-specific plugin rather than functions.php, and it survives theme changes intact.

The field is not saving for images uploaded in bulk

Bulk upload flows and drag-and-drop uploaders can bypass the save filter, and no bulk-edit screen exists for attachment fields in core. Fill the values with WP-CLI instead: wp post meta update <attachment-id> _st_credit "Studio Name", or loop over a CSV with wp eval-file.

Frequently asked questions

Can I add custom fields to media without a plugin?

Yes, using the attachment_fields_to_edit and attachment_fields_to_save filters, which are still part of WordPress core in version 7.1. You get an editing UI on the classic media screens but not in the block editor’s media modal. If you need the field inside the modal, a plugin or a field framework is the practical route.

Where does WordPress store custom fields for media?

In the wp_postmeta table, with post_id set to the attachment’s ID. Each attachment is a row in wp_posts with post_type = 'attachment', so get_post_meta(), update_post_meta() and delete_post_meta() all work on media exactly as they do on posts.

Do these fields survive a theme change or a plugin removal?

The data does. Custom field values are database rows attached to the media item, not to the theme or plugin that created the editing screen. Removing ACF or the plugin deletes the interface, not the values — you can read them straight from wp_postmeta at any time. Only the code that displays them needs to be maintained.

Will custom fields on images help my SEO?

No, not directly — search engines do not read wp_postmeta. What does matter is alt text, file naming and the rendered HTML around the image. Use custom fields for business logic: credits, licences, CTA targets. For the SEO side, start with correct image dimensions and sensible file sizes, because those affect the page, which does affect ranking.

Can I search images by a custom field in the media library?

Not out of the box. The media library search covers title, caption, description and alt text only. To filter by custom field you either add an admin filter with pre_get_posts on the upload.php screen, or use a media management plugin that supports meta queries. Bulk-editing hundreds of images by hand is not practical in core WordPress.

Is there a way to add fields to the media modal without ACF?

Only with a plugin that explicitly supports the block editor’s modal — the legacy filter API does not reach it. ACF and Meta Box both document attachment support that renders in the media modal; the free Add Custom Fields to Media plugin targets the attachment details panel. Test on a staging copy before committing, because modal integration is the part that breaks across WordPress releases.

The short version

Media custom fields are ordinary post meta on an attachment, and the only real decision is how much interface you need around them. One field, small library, comfortable with PHP: use the snippet. Editors involved, or you need the field in the block editor: use ACF or Meta Box. Whichever you pick, keep the display code in a site plugin and read values with the attachment ID, and the metadata will outlive the theme you built it on.

If you are organising a large image library, pair this with proper image sizing — it is usually the bigger win for page speed than any metadata field.

Written by

Editor Team

Content Specialist at Spiracle Themes

We are a team of WordPress enthusiasts passionate about creating beautiful themes and helping users build better websites.

Leave a Reply

Your email address will not be published. Required fields are marked *