Use an ACF Options Page for values that belong to the whole site: contact details, footer text, social links or a default announcement. Read the default options storage with get_field('field_name', 'option'). Use a post field when each post needs its own value.
Options Pages are an ACF PRO feature. ACF PRO 6.2 and later can register them through the admin UI; PHP registration remains useful when configuration lives with the site's code. Secure Custom Fields is a separate plugin with its own Options Pages feature, so identify which product is installed before diagnosing availability.
Basic registration
Save this registration in a site plugin or a must-use plugin. I default site-wide settings to administrator access:
add_action( 'acf/init', function () {
if ( ! function_exists( 'acf_add_options_page' ) ) {
return;
}
acf_add_options_page( array(
'page_title' => 'Site Settings',
'menu_title' => 'Site Settings',
'menu_slug' => 'te-site-settings',
'capability' => 'manage_options',
'redirect' => false,
'autoload' => false,
) );
} );In the field-group editor, add a location rule targeting this Options Page. In the UI workflow, create the page under ACF → Options Pages and attach the field group there instead. Do not register the same slug twice through competing UI and code definitions.
acf/init is the appropriate time to use ACF's registration API. The function check prevents a fatal error if the product is disabled or lacks that feature; it does not install the feature for you.
Parent + sub-pages structure for many settings
Use a parent when separate groups deserve separate editing screens. Set the capability on the children too:
add_action( 'acf/init', function () {
if ( ! function_exists( 'acf_add_options_page' ) ) {
return;
}
acf_add_options_page( array(
'page_title' => 'Site Options',
'menu_slug' => 'te-site-options',
'capability' => 'manage_options',
'redirect' => true,
) );
foreach ( array( 'Header', 'Footer', 'Contact' ) as $section ) {
acf_add_options_sub_page( array(
'page_title' => $section,
'menu_slug' => 'te-options-' . strtolower( $section ),
'parent_slug' => 'te-site-options',
'capability' => 'manage_options',
) );
}
} );Attach each field group to the correct child page. Menu organization does not isolate stored values: default options pages share the same storage namespace. Use distinct names such as header_cta_url and footer_cta_url. If two screens intentionally use the same field, they can share its value. A custom storage prefix/context is a separate configuration choice, and reads must use the corresponding context.
Reading values from an Options Page
$text = (string) get_field( 'header_cta_text', 'option' );
$url = (string) get_field( 'header_cta_url', 'option' );
if ( '' !== $text && '' !== $url ) {
printf( '<a href="%s">%s</a>', esc_url( $url ), esc_html( $text ) );
}Escape at the point of output. A URL belongs in esc_url(), plain text in esc_html(), and an attribute value in esc_attr(). If a field intentionally permits limited HTML, define that contract and use an appropriate allowed-HTML policy instead of treating every field as raw markup.
Repeater values use the same options context:
if ( have_rows( 'social_profiles', 'option' ) ) {
while ( have_rows( 'social_profiles', 'option' ) ) {
the_row();
$url = (string) get_sub_field( 'url' );
$label = (string) get_sub_field( 'label' );
if ( $url && $label ) {
printf( '<a href="%s">%s</a>', esc_url( $url ), esc_html( $label ) );
}
}
}Updating Options Page values programmatically
Use the actual field key from your field-group export when initially creating a value, so ACF can establish its field reference:
// Replace these keys with the keys in your registered field group.
update_field( 'field_te_header_cta_text', 'Contact me', 'option' );
update_field( 'field_te_header_cta_url', 'https://example.com/contact/', 'option' );For a repeater, write a complete row array with the correct subfield keys:
$rows = array(
array(
'field_te_social_label' => 'GitHub',
'field_te_social_url' => 'https://github.com/example',
),
);
update_field( 'field_te_social_profiles', $rows, 'option' );This replaces the repeater value; it is not an append operation. Back up existing values before a bulk replacement. update_field() can return false when the value is unchanged, so distinguish a no-op from a failure using the intended before/after state. For a complete migration, use the programmatic field-update guide and safe batch-update procedure.
Cache strategy for high-traffic sites
Default options-page values live in wp_options, with reference metadata alongside them. Autoload is configurable; do not assume every ACF option is loaded on every request. Enable autoload only for a measured, bounded set of small values used throughout the site. A large repeater used on one route is a poor candidate for universal loading.
ACF and WordPress already cache values during normal reads. If profiling shows repeated work in your own adapter, a request-local wrapper can make that ownership explicit:
function te_site_setting( string $name, $default = null ) {
static $values = array();
if ( ! array_key_exists( $name, $values ) ) {
$value = get_field( $name, 'option' );
$values[ $name ] = ( false === $value || null === $value ) ? $default : $value;
}
return $values[ $name ];
}This wrapper treats false/null as missing; do not use that policy for a boolean setting where false is meaningful. It also assumes the value does not change later in the same request. Use normal ACF/WordPress update APIs for writes so their caches are invalidated. A persistent cache or a rendered-page cache you add needs its own invalidation policy; manually deleting arbitrary option-cache entries is not the normal update procedure.
Options page missing: ordered diagnostic checklist
- Confirm the installed plugin/product and feature availability. For ACF, verify ACF PRO is active; also check whether its UI features are disabled by configuration.
- Look for the page in the Options Pages UI and in PHP registration. Missing
acf_add_options_page()text alone does not mean the page is unregistered. - Verify registration runs on
acf/init, the slug is unique, and PHP logs contain no error that prevents registration. - Test with a user who has the configured capability.
edit_postsis also held by default Authors and Contributors, not just Editors. Usemanage_optionsor an intentionally provisioned custom capability for privileged site settings. - If the menu exists but the screen has no fields, inspect the group's location rules, active status and the selected child-page slug.
- For a missing child, confirm
parent_slugmatches the registered parent and that both capability settings allow the user to see it. - If fields appear but the frontend is blank, check the field name, options storage context, and whether a value has actually been saved. Do not use the menu slug as the default
'option'context.
An editor-specific capability should be provisioned during a controlled setup/migration, not added to a role on every frontend request. Test with that role rather than inferring behavior from an administrator session.
Multilingual considerations
Options fields do not become language-specific simply because the site has multiple languages. With WPML, use the ACFML integration and its documented Options Page translation workflow, including field translation preferences and saving values in the intended language. Other multilingual plugins have different integrations; verify their current support before designing storage around it.
Test each language's saved value and rendered output separately, including fallback behavior. Make language/context part of any custom cache key. Keep global values that really should be shared, such as a single corporate identifier, distinct from translated text.
For layout-specific values, use the Flexible Content component pattern. For slow options reads, measure the actual cache and query behavior before duplicating the settings into another store.
Sources
Authoritative references this article was fact-checked against.
- ACF Options Pages UI and storageadvancedcustomfields.com
- ACF options-page registrationadvancedcustomfields.com
- ACF field updates and referencesadvancedcustomfields.com
- WordPress roles and capabilitieswordpress.org
- SCF options-page supportdeveloper.wordpress.org
- WPML ACFML translation workflowwpml.org





