How to add a dynamic fallback to an ACF field value in Elementor

A new challenge came my way recently with regard to Elementor and Advanced Custom Fields. When using an ACF dynamic value in an Elementor widget control, you do have access to a fallback value, however, it's a fixed value only. For my scenario, I needed a unique fallback value based on the post. Follow along as I share the solution.

The scenario

My task involved modifying an existing hero image widget displayed on a product page. It needed support for adding a mobile-specific hero image for further page speed optimization. Since I was dealing with an existing product catalog, there’s a lot of posts that will not have an image uploaded when the feature goes live. While the Elementor Image control does include a fallback option, it’s only a fixed value. Obviously, I don’t want the same fallback image for all products, so what are my options?

Luckily, Elementor uses some core functions from Advanced Custom Fields to accomplish their integration, so I was able to find a filter hook that solved this task perfectly.

The ACF load_value filter hook

After much debugging into source code I found the right filter that would allow me to intercept the loading of an ACF field value. According to the PHPDOC this hook Filters the $value after it has been loaded. For reference it can be found within the plugin directory inside ./includes/acf-value-functions.php within the acf_get_value function.

To implement, paste this code into your functions.php or relevant class file:

add_filter( 'acf/load_value', 'maybe_fallback_hero_image', 99, 3 );

As you can see it has 3 potential arguments that you can use in your method signature. Here’s an example function that you can model your implementation after:

public function maybe_fallback_hero_image( $value, $post_id, $field ) {
  // Check for mobile hero image setting
   if ( empty( $value ) && 'product_hero_mobile' === $field['name'] ) {
      // Retrieve desktop hero setting (As attachment ID)
      $fallback = get_post_meta( $post_id,'product_hero', true );
      // Substitute the fallback for the missing mobile attachment
      if ( ! empty( $fallback ) )
         $value = $fallback;
   return $value;

Make sure to return $value here, regardless of whether you change it.

As long as you’ve included both the function and filter hook in your code, you’ve now learned how to programmatically add a fallback value for Advanced Custom Fields when used in 3rd-party page builders like Elementor.