diff --git a/doccheck_basic.info.yml b/doccheck_basic.info.yml
index 40266c0..c63d75b 100755
--- a/doccheck_basic.info.yml
+++ b/doccheck_basic.info.yml
@@ -1,6 +1,6 @@
 name: "DocCheck Basic"
 description: "DocCheck Basic Login page and block"
-core_version_requirement: ^10.2 || ^11
+core_version_requirement: ^10.2 || ^11 || ^12
 package: Web services
 type: module
 dependencies:
diff --git a/doccheck_basic.module b/doccheck_basic.module
index 20e7b30..3b71511 100755
--- a/doccheck_basic.module
+++ b/doccheck_basic.module
@@ -5,6 +5,8 @@
  * Module code for doccheck_basic module.
  */
 
+use Drupal\Core\Hook\Attribute\LegacyHook;
+use Drupal\doccheck_basic\Hook\DoccheckBasicHooks;
 use Drupal\Core\Routing\RouteMatchInterface;
 
 /**
@@ -30,21 +32,7 @@ function doccheck_basic_theme($existing, $type, $theme, $path) {
 /**
  * Implements hook_help().
  */
+#[LegacyHook]
 function doccheck_basic_help($route_name, RouteMatchInterface $route_match) {
-  switch ($route_name) {
-    case 'help.page.doccheck_basic':
-      $text = file_get_contents(dirname(__FILE__) . '/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;
+  return \Drupal::service(DoccheckBasicHooks::class)->help($route_name, $route_match);
 }
diff --git a/doccheck_basic.services.yml b/doccheck_basic.services.yml
index 8cf1030..978e1bf 100644
--- a/doccheck_basic.services.yml
+++ b/doccheck_basic.services.yml
@@ -44,3 +44,7 @@ services:
       - '@entity_type.manager'
     tags:
       - { name: authentication_provider, provider_id: 'doccheck_basic_ip_auth', priority: 100, global: TRUE }
+
+  Drupal\doccheck_basic\Hook\DoccheckBasicHooks:
+    class: Drupal\doccheck_basic\Hook\DoccheckBasicHooks
+    autowire: true
diff --git a/src/Hook/DoccheckBasicHooks.php b/src/Hook/DoccheckBasicHooks.php
new file mode 100644
index 0000000..8e3f41f
--- /dev/null
+++ b/src/Hook/DoccheckBasicHooks.php
@@ -0,0 +1,38 @@
+<?php
+
+namespace Drupal\doccheck_basic\Hook;
+
+use Drupal\Core\Routing\RouteMatchInterface;
+use Drupal\Core\Hook\Attribute\Hook;
+
+/**
+ * Hook implementations for doccheck_basic.
+ */
+class DoccheckBasicHooks {
+
+  /**
+   * Implements hook_help().
+   */
+  #[Hook('help')]
+  public static function help($route_name, RouteMatchInterface $route_match) {
+    switch ($route_name) {
+      case 'help.page.doccheck_basic':
+        $text = file_get_contents(dirname(__FILE__) . '/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;
+  }
+
+}
