diff --git a/src/Hook/WebAccessibilityHooks.php b/src/Hook/WebAccessibilityHooks.php
new file mode 100644
index 0000000..3a6d8d2
--- /dev/null
+++ b/src/Hook/WebAccessibilityHooks.php
@@ -0,0 +1,97 @@
+<?php
+
+namespace Drupal\web_accessibility\Hook;
+
+use Drupal\web_accessibility\WebServiceInterface;
+use Drupal\Core\Form\FormStateInterface;
+use Drupal\Core\Routing\RouteMatchInterface;
+use Drupal\Core\Url;
+use Drupal\Core\Hook\Attribute\Hook;
+use Drupal\Core\StringTranslation\StringTranslationTrait;
+/**
+ * Hook implementations for web_accessibility.
+ */
+class WebAccessibilityHooks
+{
+    use StringTranslationTrait;
+    /**
+     * Implements hook_form_BASE_FORM_ID_alter() for \Drupal\node\NodeForm.
+     */
+    #[Hook('form_node_form_alter')]
+    public function formNodeFormAlter(&$form, \Drupal\Core\Form\FormStateInterface $form_state)
+    {
+        /** @var \Drupal\node\Entity\Node $node */
+        $node = $form_state->getFormObject()->getEntity();
+        if (!$node->isNew()) {
+            // Show web accessibility block only on published nodes.
+            $form['web_accessibility_settings'] = [
+                '#type' => 'details',
+                '#title' => $this->t('Web Accessibility Services'),
+                '#open' => FALSE,
+                '#group' => 'advanced',
+                '#access' => TRUE,
+                '#attributes' => [
+                    'class' => [
+                        'web-accessibility-form',
+                    ],
+                ],
+                '#weight' => 30,
+            ];
+            $form['web_accessibility_settings']['content'] = [
+                '#markup' => '<label>' . $this->t('Check with') . '</label>',
+            ];
+            $nodeUrl = $node->toUrl('canonical', [
+                'absolute' => TRUE,
+            ])->toString();
+            $services = \Drupal::service('web_accessibility.service_manager')->findAll();
+            if (!empty($services)) {
+                foreach ($services as $service) {
+                    $serviceUrl = str_replace(\Drupal\web_accessibility\WebServiceInterface::URL_TOKEN, $nodeUrl, $service->url);
+                    $form['web_accessibility_settings']['services_table_' . $service->id] = [
+                        '#prefix' => '<div class="web_accessibility_link form-item">',
+                        '#type' => 'link',
+                        '#url' => \Drupal\Core\Url::fromUri($serviceUrl, [
+                            'absolute' => TRUE,
+                            'attributes' => [
+                                'target' => '_blank',
+                            ],
+                        ]),
+                        '#title' => $service->name,
+                        '#suffix' => '</div>',
+                        '#attributes' => [
+                            'class' => [
+                                'button',
+                            ],
+                        ],
+                    ];
+                }
+            }
+        }
+    }
+    /**
+     * Implements hook_help().
+     *
+     * @inheritdoc
+     */
+    #[Hook('help')]
+    public function help($route_name, \Drupal\Core\Routing\RouteMatchInterface $route_match)
+    {
+        switch ($route_name) {
+            case 'help.page.web_accessibility':
+                $text = file_get_contents(__DIR__ . "/README.md");
+                if (!\Drupal::moduleHandler()->moduleExists('markdown')) {
+                    return '<pre>' . $text . '</pre>';
+                } else {
+                    // Use the Markdown filter to render the README.
+                    $filter_manager = \Drupal::service('plugin.manager.filter');
+                    $settings = \Drupal::configFactory()->get('markdown.settings')->getRawData();
+                    $config = [
+                        'settings' => $settings,
+                    ];
+                    $filter = $filter_manager->createInstance('markdown', $config);
+                    return $filter->process($text, 'en');
+                }
+        }
+        return NULL;
+    }
+}
diff --git a/web_accessibility.info.yml b/web_accessibility.info.yml
index 3e32dba..77bb856 100644
--- a/web_accessibility.info.yml
+++ b/web_accessibility.info.yml
@@ -3,4 +3,4 @@ type: module
 description: 'Validate content for WCAG2.0 accessibility'
 package: Web services
 configure: web_accessibility.settings
-core_version_requirement: ^8 || ^9 || ^10 || ^11
+core_version_requirement: ^10.1 || ^11 || ^12
diff --git a/web_accessibility.module b/web_accessibility.module
index cf79cdb..2f5f072 100644
--- a/web_accessibility.module
+++ b/web_accessibility.module
@@ -4,7 +4,9 @@
  * @file
  * Contains web_accessibility.module.
  */
-
+use Drupal\Core\Hook\Attribute\LegacyHook;
+use Drupal\web_accessibility\Hook\WebAccessibilityHooks;
+use Drupal\web_accessibility\WebServiceInterface;
 use Drupal\Core\Form\FormStateInterface;
 use Drupal\Core\Routing\RouteMatchInterface;
 use Drupal\Core\Url;
@@ -12,46 +14,10 @@ use Drupal\Core\Url;
 /**
  * Implements hook_form_BASE_FORM_ID_alter() for \Drupal\node\NodeForm.
  */
-function web_accessibility_form_node_form_alter(&$form, FormStateInterface $form_state) {
-  /** @var \Drupal\node\Entity\Node $node */
-  $node = $form_state->getFormObject()->getEntity();
-  if (!$node->isNew()) {
-    // Show web accessibility block only on published nodes.
-    $form['web_accessibility_settings'] = [
-      '#type' => 'details',
-      '#title' => t('Web Accessibility Services'),
-      '#open' => FALSE,
-      '#group' => 'advanced',
-      '#access' => TRUE,
-      '#attributes' => ['class' => ['web-accessibility-form']],
-      '#weight' => 30,
-    ];
-
-    $form['web_accessibility_settings']['content'] = [
-      '#markup' => '<label>' . t('Check with') . '</label>',
-    ];
-
-    $nodeUrl = $node->toUrl('canonical', ['absolute' => TRUE])->toString();
-
-    $services = \Drupal::service('web_accessibility.service_manager')
-      ->findAll();
-    if (!empty($services)) {
-      foreach ($services as $service) {
-        $serviceUrl = str_replace(\Drupal\web_accessibility\WebServiceInterface::URL_TOKEN, $nodeUrl, $service->url);
-        $form['web_accessibility_settings']['services_table_' . $service->id] = [
-          '#prefix' => '<div class="web_accessibility_link form-item">',
-          '#type' => 'link',
-          '#url' => Url::fromUri($serviceUrl, [
-            'absolute' => TRUE,
-            'attributes' => ['target' => '_blank']
-          ]),
-          '#title' => $service->name,
-          '#suffix' => '</div>',
-          '#attributes' => ['class' => ['button']],
-        ];
-      }
-    }
-  }
+#[LegacyHook]
+function web_accessibility_form_node_form_alter(&$form, FormStateInterface $form_state)
+{
+    \Drupal::service(WebAccessibilityHooks::class)->formNodeFormAlter($form, $form_state);
 }
 
 /**
@@ -59,21 +25,8 @@ function web_accessibility_form_node_form_alter(&$form, FormStateInterface $form
  *
  * @inheritdoc
  */
-function web_accessibility_help($route_name, RouteMatchInterface $route_match) {
-  switch ($route_name) {
-    case 'help.page.web_accessibility':
-      $text = file_get_contents(__DIR__ . "/README.md");
-      if (!\Drupal::moduleHandler()->moduleExists('markdown')) {
-        return '<pre>' . $text . '</pre>';
-      }
-      else {
-        // Use the Markdown filter to render the README.
-        $filter_manager = \Drupal::service('plugin.manager.filter');
-        $settings = \Drupal::configFactory()->get('markdown.settings')->getRawData();
-        $config = ['settings' => $settings];
-        $filter = $filter_manager->createInstance('markdown', $config);
-        return $filter->process($text, 'en');
-      }
-  }
-  return NULL;
+#[LegacyHook]
+function web_accessibility_help($route_name, RouteMatchInterface $route_match)
+{
+    return \Drupal::service(WebAccessibilityHooks::class)->help($route_name, $route_match);
 }
diff --git a/web_accessibility.services.yml b/web_accessibility.services.yml
index 6dd42c3..2d97a8d 100644
--- a/web_accessibility.services.yml
+++ b/web_accessibility.services.yml
@@ -4,3 +4,7 @@ services:
     arguments: ['@database']
     tags:
       - { name: backend_overridable }
+
+  Drupal\web_accessibility\Hook\WebAccessibilityHooks:
+    class: Drupal\web_accessibility\Hook\WebAccessibilityHooks
+    autowire: true
