How to Add a Custom Field in WordPress
To add a custom field in WordPress, open the editor's Preferences, enable the Custom fields panel, click Enter new and save a name and value on the post. WordPress stores it as post meta. It appears on the page only when the theme, a plugin or a block bound to that key prints it.
For WordPress site owners and developers storing extra data on posts, from a single source link to typed ACF field groups.
knowledge
- Read time
- 4 min
- Sections
- 7
- Updated
- 14 Nov 2026
- Written by
- WebJi® team
Last editorial update: 14 November 2026.
How to add a custom field in WordPress with the built-in panel
To add a custom field with the built-in panel, enable Custom fields in the editor's Preferences, then save a name and a value on the post. WordPress stores the pair as post meta; the panel is hidden in the block editor until you switch it on.
- Edit the post. Open the options menu in the top bar and choose Preferences.
- Open the Panels section and enable Custom fields. The editor reloads.
- Under the content, choose Enter new. Type a key such as source_url and a value. Click Add Custom Field.
- Update the post. The pair is saved even though the public page does not show it yet.
What a custom field stores in the WordPress database
Each custom field becomes one row in the postmeta table: the post id, the meta key and the meta value, plus a unique meta_id. A key that starts with an underscore is hidden from the editor panel, which is how plugins keep internal settings out of sight.
The same idea powers user meta and term meta, so a field on a user profile lands in usermeta rather than postmeta. If a value looks empty after saving, check which table the code is actually querying.
How to show a custom field on the front end
To show a custom field, fetch it with get_post_meta for the current post id, then escape it before printing. Escape as text with esc_html, as a link with esc_url, and as markup with wp_kses_post, so a stored value can never inject script into the page.
$source = get_post_meta( get_the_ID(), 'source_url', true );
if ( $source ) {
echo '<p>Source: <a href="' . esc_url( $source ) . '">link</a></p>';
}Put that in a child-theme template or a small site-specific plugin, and test on a copy: a syntax error in a template file returns a white screen, which WP_DEBUG will explain.
In a block theme you can skip PHP entirely with the Block Bindings API (WordPress 6.5 and later). Register the key with show_in_rest, then bind a Paragraph, Heading, Image or Button block to it in the code editor (see the Gutenberg blocks guide). Keys that start with an underscore are protected and cannot be bound.
register_meta( 'post', 'source_url', array(
'show_in_rest' => true,
'single' => true,
'type' => 'string',
) );
<!-- wp:paragraph {"metadata":{"bindings":{"content":{"source":"core/post-meta","args":{"key":"source_url"}}}}} -->
<p>Fallback text</p>
<!-- /wp:paragraph -->How to save a custom field safely in PHP
Save a custom field inside a handler that checks a nonce, confirms the user can edit that post, sanitises the value, and only then calls update_post_meta. A save routine that skips the nonce lets any visitor with a crafted request overwrite your field. The nonce itself comes from wp_nonce_field( 'save_source', 'source_nonce' ) printed inside your meta box, and the autosave check stops a half-typed value being stored.
add_action( 'save_post', function ( $post_id ) {
if ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE ) {
return;
}
if ( ! isset( $_POST['source_nonce'] ) ||
! wp_verify_nonce( sanitize_text_field( wp_unslash( $_POST['source_nonce'] ) ), 'save_source' ) ) {
return;
}
if ( ! current_user_can( 'edit_post', $post_id ) ) {
return;
}
if ( isset( $_POST['source_url'] ) ) {
update_post_meta( $post_id, 'source_url',
esc_url_raw( wp_unslash( $_POST['source_url'] ) ) );
}
} );Register the key with register_post_meta when the value should also be available through the REST API, and set show_in_rest to true for block editor access. The WordPress database guide explains how postmeta sits beside the posts table if you want the storage model in more detail.
Native custom fields vs ACF vs Meta Box
Choose the built-in panel for one or two text notes, Advanced Custom Fields for typed field groups with location rules, and Meta Box when the project needs many field types without a page-builder dependency. All three save to the same postmeta table.
| Option | Best for | Interface | Watch out for |
|---|---|---|---|
| Native Custom fields | One text note, a source URL, a quick key | Hidden panel in the editor, text value only | No field types, no validation, easy to misspell a key |
| Advanced Custom Fields | Typed groups on posts, pages or options pages | Field Groups screen with location rules | Another plugin to update; some field types sit in the pro version |
| Meta Box | Many field types on a custom project | Field group builder with code-first config | More setup than the native panel for a single value |
Do not drive the same key from the built-in panel and a plugin at once. Pick one writer, or the value is saved twice under two names and the template reads whichever one it was told to read.
How to add custom fields with the ACF plugin
To add custom fields with ACF, install Advanced Custom Fields, open Field Groups and add a group, then add each field and set a location rule such as Post Type is equal to Post. The group appears under the editor for matching posts, and each field gets a key that get_field() can read.
- Go to Plugins → Add New, search for Advanced Custom Fields (ACF®), install and activate. A separate fork, Secure Custom Fields, also sits in the directory and deactivates ACF if both are active, so install only one.
- Open ACF → Field Groups → Add New and give the group a name that describes its content.
- Click Add Field, set the label, the field name and the type (text, image, date picker), then close the field.
- Add a location rule so the group only shows where it belongs, for example Post Type is equal to Post.
- Publish the group, edit a post, fill the fields and update. Read the values later with get_field( 'field_name' ).
How to check that a custom field saved and displays
To check a custom field saved, reopen the post and confirm the value is still in the panel; if it vanished, the save handler returned early or the key was misspelled. Then load the public page in a private window, because a cached copy hides fresh output.
When the panel holds a value but the page prints nothing, check the template runs for that post type and that the key in the code matches the key in the database exactly. A quick var_dump of get_post_meta for the post id shows what WordPress actually stored.
None of this depends on the hosting account: the field and the code travel with the site. On WebJi® WordPress hosting you can inspect postmeta directly in phpMyAdmin from the hosting panel.
Frequently asked questions
How do I add a custom field in WordPress?
In the post editor open Preferences, enable the Custom fields panel, click Enter new, save a name and a value, and update the post. The pair is stored in postmeta.
Why is the custom field box missing?
The block editor hides it. Enable Custom fields under Preferences, Panels. A full-site editor template may also omit the panel. The classic editor shows the box from Screen Options.
Do custom fields show on the website automatically?
No. Something in the theme or a block has to print that key. Until then the value sits in the database only.
How do I display a custom field in PHP?
Call get_post_meta( get_the_ID(), 'your_key', true ) and escape the result before printing it, with esc_html for text or esc_url for a link.
What is the difference between native custom fields and ACF?
Native fields hold plain text and need the key typed by hand. Advanced Custom Fields adds typed field groups, location rules and its own get_field() function, and all of them save to the same postmeta table.
Can I add a custom field programmatically?
Yes. Call update_post_meta( $post_id, 'key', $value ) after checking a nonce and the user's edit capability, or use register_post_meta to declare the key first.
Last editorial update: 14 November 2026.
Ready to get started with WebJi®?
Join 12,000+ businesses across India and overseas. INR pricing, 18% GST shown before payment and 24/7 email support in Hindi and English — average first reply under 60 minutes.