Image Hotspot
An interactive image field where editors upload an image and click to place named hotspot pins at any position. Each pin stores a label, description, optional link, and — depending on pin style — a Font Awesome icon. Coordinates are stored as percentages so hotspots remain responsive at any image size.
Pro field
Image Hotspot requires the Extra Fields for ACF Pro license.
Settings
| Setting | Default | Options | Description |
|---|---|---|---|
| Pin Style | dot | dot · pin · numbered · icon | Visual appearance of placed pins. icon requires a Font Awesome class per pin. |
| Max Hotspots | 0 | Integer | Maximum pins allowed. 0 = unlimited. |
| Description Type | plain | plain · rich | rich enables a TinyMCE editor for formatted pin descriptions. |
Return values
Returns an associative array with an image_id and a hotspots array.
$hotspot = get_field('product_diagram');
// [
// 'image_id' => 456,
// 'hotspots' => [
// [
// 'x' => 45.5, // % from left
// 'y' => 32.1, // % from top
// 'label' => 'Power button',
// 'description' => 'Hold for 3 seconds to power on.',
// 'link' => 'https://example.com/docs/power',
// 'icon' => 'fas fa-power-off',
// ],
// ...
// ],
// ]
Usage
Rendering a responsive hotspot image
$data = get_field('diagram');
if ($data && !empty($data['image_id'])) {
$img_url = wp_get_attachment_image_url($data['image_id'], 'large');
echo '<div class="hotspot-wrap" style="position: relative; display: inline-block;">';
echo '<img src="' . esc_url($img_url) . '" style="width: 100%; display: block;">';
foreach ($data['hotspots'] as $pin) {
printf(
'<button class="hotspot-pin" style="position: absolute; left: %s%%; top: %s%%;" aria-label="%s" data-description="%s">',
esc_attr(round($pin['x'], 2)),
esc_attr(round($pin['y'], 2)),
esc_attr($pin['label']),
esc_attr($pin['description'])
);
echo '<span class="pin-dot"></span>';
echo '</button>';
}
echo '</div>';
}
Building a hotspot list alongside the image
$data = get_field('feature_diagram');
if ($data) {
echo '<div class="diagram-layout">';
// Image
echo '<div class="diagram-image">';
echo wp_get_attachment_image($data['image_id'], 'full');
echo '</div>';
// Numbered list
echo '<ol class="diagram-pins">';
foreach ($data['hotspots'] as $i => $pin) {
echo '<li>';
echo '<strong>' . esc_html($pin['label']) . '</strong>';
if ($pin['description']) {
echo '<p>' . wp_kses_post($pin['description']) . '</p>';
}
if ($pin['link']) {
echo '<a href="' . esc_url($pin['link']) . '">Learn more</a>';
}
echo '</li>';
}
echo '</ol>';
echo '</div>';
}