diff --git a/image_fetchpriority.info.yml b/image_fetchpriority.info.yml
index 2961777..cee17d2 100644
--- a/image_fetchpriority.info.yml
+++ b/image_fetchpriority.info.yml
@@ -1,5 +1,5 @@
 name: Image Fetchpriority
 type: module
 description: 'Adds fetchpriority (high/low/auto) support to the built-in Image and Responsive Image field formatters, without replacing them.'
-core_version_requirement: ^10 || ^11
+core_version_requirement: ^10.1 || ^11 || ^12
 package: Custom
diff --git a/image_fetchpriority.module b/image_fetchpriority.module
index 9514345..b5f4f9e 100644
--- a/image_fetchpriority.module
+++ b/image_fetchpriority.module
@@ -24,7 +24,8 @@
  *   - hook_entity_display_build_alter()
  *       Injects fetchpriority="high|low|auto" into the rendered <img>.
  */
-
+use Drupal\Core\Hook\Attribute\LegacyHook;
+use Drupal\image_fetchpriority\Hook\ImageFetchpriorityHooks;
 use Drupal\Core\Form\FormStateInterface;
 use Drupal\Core\Render\Element;
 use Drupal\field_ui\Form\EntityViewDisplayEditForm;
@@ -49,74 +50,10 @@ const IMAGE_FETCHPRIORITY_SUPPORTED_FORMATTERS = ['image', 'responsive_image'];
  * The element is only injected when a field is actively being edited (i.e.
  * when settings_edit_form is present in the field's render subtree).
  */
-function image_fetchpriority_form_alter(array &$form, FormStateInterface $form_state, string $form_id): void {
-  // Only act on the "Manage display" form for entity view displays.
-  if (!($form_state->getFormObject() instanceof EntityViewDisplayEditForm)) {
-    return;
-  }
-
-  if (empty($form['fields'])) {
-    return;
-  }
-
-  /** @var \Drupal\Core\Entity\Display\EntityViewDisplayInterface $display */
-  $display = $form_state->getFormObject()->getEntity();
-
-  foreach (Element::children($form['fields']) as $field_name) {
-    // Only act on fields currently showing their settings edit form.
-    if (!isset($form['fields'][$field_name]['plugin']['settings_edit_form']['settings']['image_loading'])) {
-      continue;
-    }
-
-    // Only act on supported formatters.
-    $component = $display->getComponent($field_name);
-    if (
-      empty($component['type'])
-      || !in_array($component['type'], IMAGE_FETCHPRIORITY_SUPPORTED_FORMATTERS, TRUE)
-    ) {
-      continue;
-    }
-
-    // Read stored value; falls back to 'auto' on first use.
-    $image_loading = $component['settings']['image_loading'] ?? [];
-    $fetchpriority = $image_loading['fetchpriority'] ?? 'auto';
-
-    // Reference to the image_loading details for readability.
-    $image_loading_el = &$form['fields'][$field_name]['plugin']['settings_edit_form']['settings']['image_loading'];
-
-    // Inject fetchpriority as a direct child of the image_loading details.
-    // Order: ascending priority — low → auto → high (mirrors lazy → eager).
-    $image_loading_el['fetchpriority'] = [
-      '#type'          => 'radios',
-      '#title'         => t('Atributo de prioridad de carga'),
-      '#default_value' => $fetchpriority,
-      '#weight'        => 10,
-      '#options'       => [
-        'low'  => t('Baja (<em>fetchpriority="low"</em>)'),
-        'auto' => t('Automática (<em>fetchpriority="auto"</em>)'),
-        'high' => t('Alta (<em>fetchpriority="high"</em>)'),
-      ],
-    ];
-
-    $image_loading_el['fetchpriority']['low']['#description'] = t(
-      'Indica que esta imagen tiene menor impacto en el usuario y puede cargarse más tarde.'
-    );
-    $image_loading_el['fetchpriority']['auto']['#description'] = t(
-      'No establece preferencia. Es el valor por defecto si no se especifica.'
-    );
-    $image_loading_el['fetchpriority']['high']['#description'] = t(
-      'Indica que esta imagen es importante y debe cargarse lo antes posible. '
-      . 'Útil para imágenes "above-the-fold" como la imagen principal.'
-    );
-
-    $image_loading_el['fetchpriority_info'] = [
-      '#markup' => '<p>' . t(
-        '<a href="https://developer.mozilla.org/en-US/docs/Web/API/HTMLImageElement/fetchPriority" '
-        . 'target="_blank" rel="noopener noreferrer">Obtenga más información sobre fetchpriority.</a>'
-      ) . '</p>',
-      '#weight' => 20,
-    ];
-  }
+#[LegacyHook]
+function image_fetchpriority_form_alter(array &$form, FormStateInterface $form_state, string $form_id): void
+{
+    \Drupal::service(ImageFetchpriorityHooks::class)->formAlter($form, $form_state, $form_id);
 }
 
 // ---------------------------------------------------------------------------
@@ -128,24 +65,10 @@ function image_fetchpriority_form_alter(array &$form, FormStateInterface $form_s
  *
  * Appends the chosen fetchpriority value to the formatter summary row.
  */
-function image_fetchpriority_field_formatter_settings_summary_alter(array &$summary, array $context): void {
-  /** @var \Drupal\Core\Field\FormatterInterface $formatter */
-  $formatter = $context['formatter'];
-
-  if (!in_array($formatter->getPluginId(), IMAGE_FETCHPRIORITY_SUPPORTED_FORMATTERS, TRUE)) {
-    return;
-  }
-
-  $image_loading = $formatter->getSetting('image_loading') ?? [];
-  $fetchpriority = $image_loading['fetchpriority'] ?? 'auto';
-
-  $labels = [
-    'low'  => t('Fetchpriority: Baja'),
-    'auto' => t('Fetchpriority: Automática'),
-    'high' => t('Fetchpriority: Alta'),
-  ];
-
-  $summary[] = $labels[$fetchpriority] ?? $labels['auto'];
+#[LegacyHook]
+function image_fetchpriority_field_formatter_settings_summary_alter(array &$summary, array $context): void
+{
+    \Drupal::service(ImageFetchpriorityHooks::class)->fieldFormatterSettingsSummaryAlter($summary, $context);
 }
 
 // ---------------------------------------------------------------------------
@@ -158,28 +81,8 @@ function image_fetchpriority_field_formatter_settings_summary_alter(array &$summ
  * Injects fetchpriority="high|low|auto" into #item_attributes of every image
  * element produced by a supported formatter.
  */
-function image_fetchpriority_entity_display_build_alter(array &$build, array $context): void {
-  /** @var \Drupal\Core\Entity\Display\EntityViewDisplayInterface $display */
-  $display = $context['display'];
-
-  foreach ($display->getComponents() as $field_name => $component) {
-    if (
-      empty($component['type'])
-      || !in_array($component['type'], IMAGE_FETCHPRIORITY_SUPPORTED_FORMATTERS, TRUE)
-    ) {
-      continue;
-    }
-
-    if (!isset($build[$field_name])) {
-      continue;
-    }
-
-    $fetchpriority = $component['settings']['image_loading']['fetchpriority'] ?? 'auto';
-
-    foreach (Element::children($build[$field_name]) as $delta) {
-      if (isset($build[$field_name][$delta]['#item_attributes'])) {
-        $build[$field_name][$delta]['#item_attributes']['fetchpriority'] = $fetchpriority;
-      }
-    }
-  }
+#[LegacyHook]
+function image_fetchpriority_entity_display_build_alter(array &$build, array $context): void
+{
+    \Drupal::service(ImageFetchpriorityHooks::class)->entityDisplayBuildAlter($build, $context);
 }
diff --git a/image_fetchpriority.services.yml b/image_fetchpriority.services.yml
new file mode 100644
index 0000000..1a07bdd
--- /dev/null
+++ b/image_fetchpriority.services.yml
@@ -0,0 +1,5 @@
+
+services:
+  Drupal\image_fetchpriority\Hook\ImageFetchpriorityHooks:
+    class: Drupal\image_fetchpriority\Hook\ImageFetchpriorityHooks
+    autowire: true
diff --git a/src/Hook/ImageFetchpriorityHooks.php b/src/Hook/ImageFetchpriorityHooks.php
new file mode 100644
index 0000000..a5400df
--- /dev/null
+++ b/src/Hook/ImageFetchpriorityHooks.php
@@ -0,0 +1,135 @@
+<?php
+
+namespace Drupal\image_fetchpriority\Hook;
+
+use Drupal\Core\Form\FormStateInterface;
+use Drupal\Core\Render\Element;
+use Drupal\field_ui\Form\EntityViewDisplayEditForm;
+use Drupal\Core\Hook\Attribute\Hook;
+use Drupal\Core\StringTranslation\StringTranslationTrait;
+/**
+ * Hook implementations for image_fetchpriority.
+ */
+class ImageFetchpriorityHooks
+{
+    use StringTranslationTrait;
+    // ---------------------------------------------------------------------------
+    // Settings form
+    // ---------------------------------------------------------------------------
+    /**
+     * Implements hook_form_alter().
+     *
+     * Targets the "Manage display" form (EntityViewDisplayEditForm) on every
+     * build — including AJAX rebuilds — to inject the fetchpriority radio group
+     * directly inside the existing "Cargando imagen" (image_loading) details
+     * element.
+     *
+     * The element is only injected when a field is actively being edited (i.e.
+     * when settings_edit_form is present in the field's render subtree).
+     */
+    #[Hook('form_alter')]
+    public function formAlter(array &$form, \Drupal\Core\Form\FormStateInterface $form_state, string $form_id): void
+    {
+        // Only act on the "Manage display" form for entity view displays.
+        if (!$form_state->getFormObject() instanceof \Drupal\field_ui\Form\EntityViewDisplayEditForm) {
+            return;
+        }
+        if (empty($form['fields'])) {
+            return;
+        }
+        /** @var \Drupal\Core\Entity\Display\EntityViewDisplayInterface $display */
+        $display = $form_state->getFormObject()->getEntity();
+        foreach (\Drupal\Core\Render\Element::children($form['fields']) as $field_name) {
+            // Only act on fields currently showing their settings edit form.
+            if (!isset($form['fields'][$field_name]['plugin']['settings_edit_form']['settings']['image_loading'])) {
+                continue;
+            }
+            // Only act on supported formatters.
+            $component = $display->getComponent($field_name);
+            if (empty($component['type']) || !in_array($component['type'], IMAGE_FETCHPRIORITY_SUPPORTED_FORMATTERS, TRUE)) {
+                continue;
+            }
+            // Read stored value; falls back to 'auto' on first use.
+            $image_loading = $component['settings']['image_loading'] ?? [
+            ];
+            $fetchpriority = $image_loading['fetchpriority'] ?? 'auto';
+            // Reference to the image_loading details for readability.
+            $image_loading_el =& $form['fields'][$field_name]['plugin']['settings_edit_form']['settings']['image_loading'];
+            // Inject fetchpriority as a direct child of the image_loading details.
+            // Order: ascending priority — low → auto → high (mirrors lazy → eager).
+            $image_loading_el['fetchpriority'] = [
+                '#type' => 'radios',
+                '#title' => $this->t('Atributo de prioridad de carga'),
+                '#default_value' => $fetchpriority,
+                '#weight' => 10,
+                '#options' => [
+                    'low' => $this->t('Baja (<em>fetchpriority="low"</em>)'),
+                    'auto' => $this->t('Automática (<em>fetchpriority="auto"</em>)'),
+                    'high' => $this->t('Alta (<em>fetchpriority="high"</em>)'),
+                ],
+            ];
+            $image_loading_el['fetchpriority']['low']['#description'] = $this->t('Indica que esta imagen tiene menor impacto en el usuario y puede cargarse más tarde.');
+            $image_loading_el['fetchpriority']['auto']['#description'] = $this->t('No establece preferencia. Es el valor por defecto si no se especifica.');
+            $image_loading_el['fetchpriority']['high']['#description'] = $this->t('Indica que esta imagen es importante y debe cargarse lo antes posible. ' . 'Útil para imágenes "above-the-fold" como la imagen principal.');
+            $image_loading_el['fetchpriority_info'] = [
+                '#markup' => '<p>' . $this->t('<a href="https://developer.mozilla.org/en-US/docs/Web/API/HTMLImageElement/fetchPriority" ' . 'target="_blank" rel="noopener noreferrer">Obtenga más información sobre fetchpriority.</a>') . '</p>',
+                '#weight' => 20,
+            ];
+        }
+    }
+    // ---------------------------------------------------------------------------
+    // Settings summary
+    // ---------------------------------------------------------------------------
+    /**
+     * Implements hook_field_formatter_settings_summary_alter().
+     *
+     * Appends the chosen fetchpriority value to the formatter summary row.
+     */
+    #[Hook('field_formatter_settings_summary_alter')]
+    public function fieldFormatterSettingsSummaryAlter(array &$summary, array $context): void
+    {
+        /** @var \Drupal\Core\Field\FormatterInterface $formatter */
+        $formatter = $context['formatter'];
+        if (!in_array($formatter->getPluginId(), IMAGE_FETCHPRIORITY_SUPPORTED_FORMATTERS, TRUE)) {
+            return;
+        }
+        $image_loading = $formatter->getSetting('image_loading') ?? [
+        ];
+        $fetchpriority = $image_loading['fetchpriority'] ?? 'auto';
+        $labels = [
+            'low' => $this->t('Fetchpriority: Baja'),
+            'auto' => $this->t('Fetchpriority: Automática'),
+            'high' => $this->t('Fetchpriority: Alta'),
+        ];
+        $summary[] = $labels[$fetchpriority] ?? $labels['auto'];
+    }
+    // ---------------------------------------------------------------------------
+    // Render
+    // ---------------------------------------------------------------------------
+    /**
+     * Implements hook_entity_display_build_alter().
+     *
+     * Injects fetchpriority="high|low|auto" into #item_attributes of every image
+     * element produced by a supported formatter.
+     */
+    #[Hook('entity_display_build_alter')]
+    public static function entityDisplayBuildAlter(array &$build, array $context): void
+    {
+        /** @var \Drupal\Core\Entity\Display\EntityViewDisplayInterface $display */
+        $display = $context['display'];
+        foreach ($display->getComponents() as $field_name => $component) {
+            if (empty($component['type']) || !in_array($component['type'], IMAGE_FETCHPRIORITY_SUPPORTED_FORMATTERS, TRUE)) {
+                continue;
+            }
+            if (!isset($build[$field_name])) {
+                continue;
+            }
+            $fetchpriority = $component['settings']['image_loading']['fetchpriority'] ?? 'auto';
+            foreach (\Drupal\Core\Render\Element::children($build[$field_name]) as $delta) {
+                if (isset($build[$field_name][$delta]['#item_attributes'])) {
+                    $build[$field_name][$delta]['#item_attributes']['fetchpriority'] = $fetchpriority;
+                }
+            }
+        }
+    }
+}
