Skip to content

How-to Guides

Technical References

Plugins /

Advanced Custom Fields (ACF 5)

Advanced Custom Fields (ACF) is a popular plugin that many VIP clients choose to use on their sites. However, ACF is not available for clients on the WordPress VIP platform, and has not undergone a full, line-byline review for use on VIP Go. Clients wishing to use ACF on VIP Go accept the security and performance risks of using it. This page outlines some additional steps needed to make ACF more secure and performant, but should not be interpreted as the equivalent of a line-by-line review, or VIP’s approval of the plugin.

Please note that while ACF 5 can be used on most VIP Go sites, ACF 4 is unavailable. If in doubt about whether ACF is allowed for use on your VIP site, please contact us.

Steps to avoid performance issues

When using ACF 5 and ACF 5 Pro, several additional steps are needed in order to make ACF secure, and avoid performance issues:

  • Hide the Admin UI
  • Define fields in PHP
  • Use taxonomies for searchable fields
  • Avoid the_field and escape
  • Secure fields that allow arbitrary output

Hide the ACF Admin UI

The fields UI can be used to add arbitrary fields, including unsafe fields. For example it can allow an admin to display the passwords of users. You can disable the UI using this filter:

add_filter( 'acf/settings/show_admin', '__return_false' );

Define fields in PHP

In order to make sure that all ACF usage is secure, define the fields in PHP or local JSON, rather than at runtime. This way they remain versioned and safe. This can be done via the import export menu of a local developer environment to set up the fields available and export them to PHP.

Documentation on how to do this can be found on the ACF website.

Alternatively, fields can be defined via the local JSON feature as described here, but keep in mind that saving local JSON will not work in production as the filesystem is read only, nor is it desirable as it would bypass the security benefits.

Being mindful of taxonomy term storage

If an ACF field is going to be queried, filtered, or searched for in a post query, use the taxonomy data checkbox so that the field is stored as a term, not a post meta value. This ensures performance is not impacted by expensive meta queries on the front end.

the_field and escaping

the_field has no context as to when or where it is called, so it doesn’t know if it should be using esc_url, esc_attr or wp_kses_post, which makes it a security risk. Instead, use get_field in combination with an escaping function:

$url = get_field( 'custom_link' );
echo esc_url( $url );

Flexible content is the exception to this, and should be clearly marked on usage via comments.

Fields that use arbitrary output

If field types that allow arbitrary output are to be used, they must be accounted for in the acf/format_value and equivalent filters such as acf/format_value/type=textarea.

For example:

function vip_make_acf_text_areas_safe( $value, $post_id, $field ) {
	return wp_kses_post( $value );

add_filter( 'acf/format_value/type=textarea', 'vip_make_acf_text_areas_safe', 10, 3 );

This way, different escaping can be applied via different '$field' values. Alternatively, if all fields of that type use the same escaping, this can be done instead:

add_filter( 'acf/format_value/type=textarea', 'wp_kses_post', 10, 1 );

More information on format_value can be found here.

Working with image fields

Due to how VIP Go handles intermediate image sizes, when working with image fields that use ‘Image Array’ or ‘Image ID’ return format, the ‘sizes’ array will be empty in the field value. So instead of directly accessing your preferred file size URL with $field_value['sizes']['large'], themes will need to use the returned image ID to retrieve the correct URL:


$my_image_field = get_field('image');


<img src="<?php echo esc_url( wp_get_attachment_image_src( $my_image_field['ID'], 'large' )[0] );?>" alt="<?php echo esc_attr( $my_image_field['alt'] ); ?>" />

Last updated: December 10, 2020