Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Some links on this page are affiliate links: if you buy through them we may earn a commission, at no extra cost to you.

WordPress custom fields store extra information as key/value metadata attached to content. You can enter a simple value in WordPress’s built-in panel, then retrieve and display it with a template, block, plugin, or custom code. For editor-friendly field groups, repeaters, validation, or relationships, a field-management plugin is usually a better fit.

What are WordPress custom fields?

A custom field has a key (the machine-readable name) and a value (the stored information). For example, an event might have the key event_date and the value 2026-09-12. WordPress commonly calls this post metadata or post meta in developer documentation; “Custom Fields” is the familiar administration label. Metadata is separate from a post’s title and main content. The default post-meta system uses WordPress’s post-meta table, although the database table prefix varies and some plugins or applications use other storage models. WordPress explains the built-in Custom Fields feature.

Content Example key Example value
Event event_date 2026-09-12
Product product_price 49.00
Recipe prep_time 30 minutes
Book review rating 4.5
Staff profile job_title Senior Editor

Custom fields can be attached to posts and pages; code or plugins can also support custom post types and other WordPress objects. A field does not appear on the front end just because it exists. Something must retrieve and render it, such as a theme template, dynamic block, page builder, or plugin.

Free tools Windows power users keep installed

One-click scans. No signup required.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Choose where the data belongs

Before adding fields, decide what the information describes. A value that applies to a whole post is a natural fit for post meta. A value that belongs to one block instance may belong in that block’s attributes. Reusable entities such as authors, venues, or products may need their own post type and relationships. Highly relational application data may warrant custom tables or a separate architecture; custom fields are not automatically the right model for every dataset.

  • One or two simple values: start with WordPress’s native fields.
  • Structured fields for editors: use a field plugin or custom metabox with labels, instructions, validation, and suitable controls.
  • Repeated rows or flexible layouts: choose a plugin or custom implementation designed for that structure rather than storing a blob of text.
  • Block-specific content: consider block attributes; use post meta when the value should be reusable at the post level.

Enable the native Custom Fields panel

The panel is hidden by default until enabled. In the Block Editor, use this documented path; labels can vary slightly by WordPress version or editing context. WordPress’s instructions describe the same workflow.

  1. Save the post first.
  2. Click Options, the three-dot menu in the top toolbar, then choose Preferences.
  3. Open General and find Advanced.
  4. Turn on Custom fields.
  5. Click Select & Reload Page. The panel appears at the bottom of the editor.

Add and name a field

  1. In the Custom Fields panel, click Enter new.
  2. Enter a key in Name, for example event_date.
  3. Enter the value, for example 2026-09-12.
  4. Click Add Custom Field, then save or update the post.

WordPress can offer a previously used key in the dropdown on later posts. It also permits more than one value for a key, but repeated values are often awkward to validate and edit in the basic panel; use a deliberate field structure for repeatable content.

  • Use lowercase, machine-friendly keys with underscores, such as event_start_date, rather than labels with spaces.
  • Prefix project keys, such as acme_event_date, to reduce collisions. The WordPress Block Bindings tutorial likewise recommends a theme or plugin prefix for metadata keys.
  • Use separate fields for separate concepts: event_start_date, event_end_date, and event_venue are easier to validate and query than one combined text value.
  • Prefer an unambiguous date such as 2026-09-12. If a date includes a time, define whether it is site-local, UTC, visitor-local, or an all-day date.
  • Do not rename a key casually after launch. Existing data remains under the old key until you migrate it.

Keys beginning with an underscore, such as _acme_import_source_id, are hidden from the basic Custom Fields list. This is useful for implementation metadata, but it is not a security control. The WordPress reference for adding post meta documents this behavior.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Retrieve and display a value in PHP

get_post_meta() returns metadata for a post. Its third argument controls whether WordPress returns one value or an array of values; see the function reference.

$value = get_post_meta( get_the_ID(), 'event_date', true );
$values = get_post_meta( get_the_ID(), 'event_date', false );
$all_meta = get_post_meta( get_the_ID() );

Escape values for the context where they are output. Retrieving a value and making it safe to print are separate tasks.

<?php
$subtitle = get_post_meta( get_the_ID(), 'subtitle', true );

if ( $subtitle ) {
    echo '<p class="post-subtitle">' . esc_html( $subtitle ) . '</p>';
}
?>

For a URL, use esc_url() in the link attribute and escape the link text as HTML:

<?php
$url = get_post_meta( get_the_ID(), 'external_url', true );

if ( $url ) {
    printf(
        '<a href="%1$s" rel="noopener">%2$s</a>',
        esc_url( $url ),
        esc_html__( 'Visit website', 'mytheme' )
    );
}
?>

For a numeric value, validate it before formatting:

What’s actually slowing this PC down?

Pick the symptom - the matching free tool is one click away.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
<?php
$price = get_post_meta( get_the_ID(), 'product_price', true );

if ( is_numeric( $price ) ) {
    echo esc_html( number_format_i18n( (float) $price, 2 ) );
}
?>

Use esc_html() for text, esc_attr() for an HTML attribute, and esc_url() for an output URL. Never assume metadata is safe because it came from an editor: imports and other code can write it too.

Save values safely in code

For direct updates, choose validation and sanitization appropriate to the data type rather than treating every value as plain text. WordPress documents update_post_meta() and delete_post_meta() alongside the other post-meta functions.

update_post_meta(
    $post_id,
    'event_date',
    sanitize_text_field( $event_date )
);

update_post_meta(
    $post_id,
    'product_price',
    (float) $product_price
);

update_post_meta(
    $post_id,
    'external_url',
    esc_url_raw( $external_url )
);

sanitize_* functions clean or normalize input before storage. esc_* functions prepare data for a particular output context; esc_url_raw() is appropriate when storing a URL, while esc_url() is for output. For example, a rating constrained to five stars might be clamped to the expected range, and a quantity can be normalized with absint(). Do not use sanitize_text_field() as a universal solution.

A custom metabox save handler needs more than sanitization. It should verify a nonce, check the user’s capability, ignore autosaves and revisions where appropriate, confirm the expected post type, and validate the expected input. This illustrative pattern assumes that a form also outputs the matching nonce field; it is not a universal drop-in handler:

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
function myplugin_save_event_meta( $post_id ) {
    if ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE ) {
        return;
    }

    if ( wp_is_post_revision( $post_id ) ) {
        return;
    }

    if (
        ! isset( $_POST['myplugin_event_nonce'] ) ||
        ! wp_verify_nonce(
            sanitize_text_field( wp_unslash( $_POST['myplugin_event_nonce'] ) ),
            'myplugin_save_event'
        )
    ) {
        return;
    }

    if ( ! current_user_can( 'edit_post', $post_id ) ) {
        return;
    }

    if ( isset( $_POST['event_date'] ) ) {
        update_post_meta(
            $post_id,
            'event_date',
            sanitize_text_field( wp_unslash( $_POST['event_date'] ) )
        );
    }
}
add_action( 'save_post_event', 'myplugin_save_event_meta' );

Register metadata for the Block Editor and REST API

When code defines a field, register its schema rather than relying only on an arbitrary key. show_in_rest exposes registered metadata through the REST API and is needed for relevant Block Editor integrations. For registered post meta, the post type must also support custom-fields. See the metadata registration reference and Block Editor metabox guidance.

function myplugin_register_meta() {
    register_post_meta(
        'post',
        'myplugin_subtitle',
        array(
            'single'            => true,
            'type'              => 'string',
            'show_in_rest'      => true,
            'sanitize_callback' => 'sanitize_text_field',
            'auth_callback'     => function () {
                return current_user_can( 'edit_posts' );
            },
        )
    );
}
add_action( 'init', 'myplugin_register_meta' );

For a custom post type, register the metadata for that type and make sure the type supports custom fields:

function myplugin_register_book_meta() {
    register_post_meta(
        'book',
        'myplugin_isbn',
        array(
            'single'            => true,
            'type'              => 'string',
            'show_in_rest'      => true,
            'sanitize_callback' => 'sanitize_text_field',
        )
    );
}
add_action( 'init', 'myplugin_register_book_meta' );

register_post_type(
    'book',
    array(
        'label'    => 'Books',
        'supports' => array( 'title', 'editor', 'thumbnail', 'custom-fields' ),
    )
);
  • single determines whether the key represents one value or multiple values.
  • type describes the expected data, such as string, boolean, integer, number, array, or object.
  • sanitize_callback normalizes incoming values; auth_callback controls whether the current user may edit the metadata.
  • default can provide a default value where appropriate. revisions_enabled is relevant when supported metadata should participate in revisions.

Registration should live where the data model belongs. If a field’s behavior should survive a theme change, avoid putting its only registration and save logic in that theme’s functions.php; a site-specific or custom plugin is often a better home.

Use metadata with REST, blocks, and templates

When registered with REST exposure, metadata can appear in a post response under meta, for example at /wp-json/wp/v2/posts/123. A typical response includes a structure such as "meta": { "myplugin_subtitle": "A structured subtitle" }. To update protected metadata, send an authenticated request, for example with a WordPress Application Password:

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
curl -X POST 
  -H "Content-Type: application/json" 
  -u "username:application-password" 
  -d '{"meta":{"myplugin_subtitle":"Updated subtitle"}}' 
  https://example.com/wp-json/wp/v2/posts/123

The registration schema and the type of the submitted value must agree, and authentication is needed for protected updates. The REST API documentation covers extending responses. Plugin-managed fields may have their own API behavior: consult the ACF REST API integration documentation for ACF.

There are three distinct editing and display needs. The native panel is the simplest way to enter plain metadata. A plugin or custom block can provide a purpose-built control such as a date picker or image selector; WordPress’s Block Editor guide shows metadata interaction with useEntityProp. For consistent front-end output, render the value through a theme or block template, dynamic block, or page-builder dynamic-data feature. A block template can include a metadata block automatically so editors do not have to remember to add it.

Block Bindings can connect registered post meta to supported block attributes. The WordPress Developer Blog’s Block Bindings tutorial gives an example using a registered key:

<!-- wp:paragraph {
    "metadata": {
        "bindings": {
            "content": {
                "source": "core/post-meta",
                "args": {
                    "key": "projectslug_mood"
                }
            }
        }
    }
} -->
<p></p>
<!-- /wp:paragraph -->

The metadata needs show_in_rest. In the tutorial’s WordPress 6.5 workflow, the binding was entered through the Code Editor rather than a dedicated visual binding control, so do not assume every installation has a visual “bind field” button.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Support on Ko-Fi

Pick an implementation that fits the workflow

Approach Best suited to Trade-offs
Native Custom Fields panel One-off or simple values Built into WordPress and dependency-free, but offers a basic interface and limited validation.
Custom PHP metabox Developer-controlled editing workflows Can be tailored closely, but requires ongoing code, security, and compatibility maintenance.
ACF free Visual field groups and a broad selection of field types Friendly editor workflow, with a plugin dependency; advanced features are in PRO. See ACF.
ACF PRO Projects needing repeaters, flexible content, galleries, options pages, clone fields, or ACF Blocks Paid annual product with ACF-specific conventions; see ACF PRO for current details.
Meta Box Developers wanting a modular field and extension approach Evaluate which extensions and workflow fit the project; its REST API documentation covers exposing fields through WordPress endpoints.
Pods Content types, fields, and relationships in a broader content model May offer more modeling workflow than a simple metadata need requires; see its documentation and Block Bindings guidance.
Custom block attributes Values belonging to an individual block instance Natural for block-specific content, but reuse and querying differ from post-level metadata.
Custom tables Specialized, highly relational application data Provide control over a distinct data model but require more work for queries, migrations, permissions, and editor integration.

ACF has a free version and a paid PRO tier; features and terms can change, so check the vendor’s current pages rather than relying on remembered prices. In general, start with core for a genuinely simple requirement, use a field plugin when editors need structured controls, and reserve custom architecture for a data model that calls for it. Do not choose solely by counting field types: consider the editing experience, REST needs, dependencies, and who will maintain the implementation.

Tips for maintenance and debugging

  • Keep one concept per field and document its format, especially date and time conventions.
  • Use a prefix to avoid collisions; use underscore-prefixed keys only when hiding implementation metadata from the basic panel is intentional.
  • Validate before saving and escape for the output context. A correct sanitizer depends on the value’s type and purpose.
  • Inspect the exact post ID and key when a value is missing. During development, a temporary log can help: error_log( print_r( get_post_meta( $post_id, 'myplugin_key', true ), true ) );
  • Check whether the code requests one value or all values, whether a later callback overwrites it, whether conditional template logic suppresses it, and whether a cache is stale.
  • Keep data registration and rendering logic in an appropriate plugin or theme layer so a theme change does not silently remove functionality the site depends on.

Fix common custom-field problems

Symptom What to check Next step
Custom Fields panel is missing It may be disabled in Preferences, or the editor context may differ. Use Options → Preferences → General → Advanced → Custom fields, enable it, then select Select & Reload Page.
Field appears but does not save in the Block Editor For registered metadata, check show_in_rest, post-type custom-fields support, registration on init, schema type, authentication, and callbacks that may overwrite the value. Correct the registration and post-type support; see the Block Editor metadata guidance.
Field saves but front-end output is blank Wrong post ID or key, a single-versus-multiple mismatch, the wrong template, conditional suppression, or a plugin value returned as an array or object. Inspect the stored value and adapt the template to the actual type.
REST response omits the field REST exposure may be off, or a custom post type may lack custom-fields support. Register metadata with show_in_rest => true and verify post-type supports.
Stored value is displayed unsafely The template may print metadata directly. Use context-appropriate escaping such as esc_html(), esc_attr(), or esc_url().
A field plugin is deactivated or replaced Stored data may remain while plugin functions, editing screens, or rendering logic stop working. Inventory keys and plugin-specific calls, back up files and database, plan a migration, and test on staging. ACF’s FAQ notes that code calling ACF functions such as the_field() or get_field() depends on those functions being available.

Before publishing, check the field lifecycle

  • Does the information belong to the post, a block, a reusable entity, or a specialized data model?
  • Is the key consistent and the value format unambiguous?
  • Are values validated and sanitized on input, and escaped at output?
  • If code manages the field, are schema, permissions, REST exposure, and post-type support configured intentionally?
  • Is there a template, block, or plugin that actually renders the value?
  • Can the site’s data and rendering continue through a theme or plugin change, and is there a tested migration plan?

Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.