diff --git a/.cspell-project-words.txt b/.cspell-project-words.txt
new file mode 100644
index 0000000000000000000000000000000000000000..3ec8f6258e5e6740596b117862a0ce6398e30598
--- /dev/null
+++ b/.cspell-project-words.txt
@@ -0,0 +1,6 @@
+contenu
+rockowitz
+selectmenu
+spécial
+strto
+tocs
diff --git a/css/toc.tree.css b/css/toc.tree.css
index f2928f7ffa28097da330c659ca4eed3ffc32aebc..cdda65502aca75ac5c23f643bc2823eb3239b276 100755
--- a/css/toc.tree.css
+++ b/css/toc.tree.css
@@ -7,7 +7,7 @@
  * Add border to tree when displayed within a node
  */
 .node .toc-tree {
-  border: 1px solid #ccc;
-  padding: 0 1em;
   margin: 1em 0;
+  padding: 0 1em;
+  border: 1px solid #ccc;
 }
diff --git a/js/toc.menu.js b/js/toc.menu.js
index cff6edc0db3376e6c3343d10ce9a7ce4ba037d83..0f4bddceec2b0f73909b842fbd4d4590350cb4be 100644
--- a/js/toc.menu.js
+++ b/js/toc.menu.js
@@ -4,19 +4,15 @@
  */
 
 (function ($, Drupal) {
-
-  "use strict";
-
   Drupal.behaviors.tocMenu = {
-    attach: function (context) {
+    attach(context) {
       $('form.toc-menu > select', context).change(function () {
-        var value = $(this).val();
+        const value = this.value;
         if (value) {
-          location.hash = value;
+          window.location.hash = value;
         }
         this.selectedIndex = 0;
       });
-    }
+    },
   };
-
 })(jQuery, Drupal);
diff --git a/js/toc_type.js b/js/toc_type.js
index 0ff1e0b5201ed5b5a93ea30bf62a7cdc114737e8..1b998c4c5855943e23a719cca92544b5c561483a 100644
--- a/js/toc_type.js
+++ b/js/toc_type.js
@@ -4,25 +4,37 @@
  */
 
 (function ($, Drupal, once) {
-
-  "use strict";
-
-  Drupal.behaviors.tocTypeOptions = {
-    attach: function (context) {
-      $(once('.js-toc-type-options-header-min, .js-toc-type-options-header-max', context)).change(toggleHeaders);
-    }
-  };
-  toggleHeaders();
-
   function toggleHeaders() {
-    var min = $('.js-toc-type-options-header-min').val();
-    var max = $('.js-toc-type-options-header-max').val();
+    const min = parseInt(
+      document.querySelector('.js-toc-type-options-header-min')?.value || 1,
+      10,
+    );
+    const max = parseInt(
+      document.querySelector('.js-toc-type-options-header-max')?.value || 6,
+      10,
+    );
 
-    for (var i = 1; i <= 6; i++) {
-      // Having to use the id instead of $('.js-toc-type-options-header-h' + i).
-      var $header = $('details[id$="-headers-h' + i + '"]');
-      (i >= min && i <= max) ? $header.show() : $header.hide();
+    for (let i = 1; i <= 6; i++) {
+      const $header = $(`details[id$="-headers-h${i}"]`);
+      if (i >= min && i <= max) {
+        $header.show();
+      } else {
+        $header.hide();
+      }
     }
   }
 
+  Drupal.behaviors.tocTypeOptions = {
+    attach(context) {
+      once(
+        'toc-type-header-change',
+        '.js-toc-type-options-header-min, .js-toc-type-options-header-max',
+        context,
+      ).forEach((el) => {
+        el.addEventListener('change', toggleHeaders);
+      });
+
+      toggleHeaders();
+    },
+  };
 })(jQuery, Drupal, once);
diff --git a/modules/toc_api_example/toc_api_example.info.yml b/modules/toc_api_example/toc_api_example.info.yml
index 00007a77166b30b597e23421ef11486af2a18022..ec98eae78d1366de045250ffa0aaeedeb7c43e9e 100644
--- a/modules/toc_api_example/toc_api_example.info.yml
+++ b/modules/toc_api_example/toc_api_example.info.yml
@@ -2,6 +2,6 @@ name: 'TOC API example'
 type: module
 description: 'Example of a custom implementation of the TOC API that adds a table of contents to specified content types.'
 package: 'Example modules'
-core_version_requirement: ^9.4 || ^10.0
+core_version_requirement: ^9.5 || ^10.2 || ^11.0
 dependencies:
   - toc_api:toc_api
diff --git a/modules/toc_api_example/toc_api_example.module b/modules/toc_api_example/toc_api_example.module
index eea6f91dae97c47a78f3136c837da5e8927e6f83..31c4211601369f7907903f5424d2891eb43bb88d 100755
--- a/modules/toc_api_example/toc_api_example.module
+++ b/modules/toc_api_example/toc_api_example.module
@@ -2,24 +2,25 @@
 
 /**
  * @file
- * Example of a custom implementation of the TOC API that adds a table of contents to specified content types.
+ * Example of a custom implementation of the TOC API.
  */
 
-use Drupal\node\NodeInterface;
 use Drupal\Core\Entity\Display\EntityViewDisplayInterface;
+use Drupal\node\NodeInterface;
 use Drupal\toc_api\Entity\TocType;
 
 /**
  * Implements hook_node_view().
  */
-function toc_api_example_node_view(array &$build, NodeInterface $node, EntityViewDisplayInterface $display, $view_mode) {
-  // Add TOC to 'page' and 'article' content types that are being viewed as a full (page) with a body field.
+function toc_api_example_node_view(array &$build, NodeInterface $node, EntityViewDisplayInterface $display, string $view_mode): void {
+  // Add TOC to 'page' and 'article' content types that are being viewed as a
+  // full (page) with a body field.
   if (in_array($node->getType(), ['page', 'article']) && $view_mode == 'full' && isset($build['body'][0])) {
     // Get the completely render (and filtered) body value.
     $body = (string) \Drupal::service('renderer')->render($build['body'][0]);
 
     // Get 'default' TOC type options.
-    /** @var \Drupal\toc_api\TocTypeInterface $toc_type */
+    /** @var \Drupal\toc_api\TocTypeInterface|null $toc_type */
     $toc_type = TocType::load('default');
     $options = ($toc_type) ? $toc_type->getOptions() : [];
 
diff --git a/phpstan.neon b/phpstan.neon
new file mode 100644
index 0000000000000000000000000000000000000000..ec1ca4cd641a5db26ba483b9395e941671ac7bc1
--- /dev/null
+++ b/phpstan.neon
@@ -0,0 +1,4 @@
+parameters:
+  level: 6
+  ignoreErrors:
+    - identifier: missingType.iterableValue
diff --git a/src/Entity/TocType.php b/src/Entity/TocType.php
index 4f143724d32920637279a4d8c4f6754fd9147c8d..db59b0dedd86cfd46540985993763b4c8dc3bad1 100644
--- a/src/Entity/TocType.php
+++ b/src/Entity/TocType.php
@@ -64,9 +64,9 @@ class TocType extends ConfigEntityBase implements TocTypeInterface {
   /**
    * The TOC type options.
    *
-   * @var array
+   * @var array|null
    */
-  protected $options;
+  protected $options = NULL;
 
   /**
    * {@inheritdoc}
diff --git a/src/Plugin/Block/TocBlockBase.php b/src/Plugin/Block/TocBlockBase.php
index 9b06dc92b810a8759c202db9a04d716a462a6097..b13c58e8507407c754474d7ba9ffa2740cf7dc16 100755
--- a/src/Plugin/Block/TocBlockBase.php
+++ b/src/Plugin/Block/TocBlockBase.php
@@ -3,15 +3,19 @@
 namespace Drupal\toc_api\Plugin\Block;
 
 use Drupal\Core\Access\AccessResult;
+use Drupal\Core\Access\AccessResultInterface;
 use Drupal\Core\Block\BlockBase;
+use Drupal\Core\Entity\EntityTypeManagerInterface;
 use Drupal\Core\Plugin\ContainerFactoryPluginInterface;
 use Drupal\Core\Routing\RouteMatchInterface;
 use Drupal\Core\Session\AccountInterface;
+use Drupal\node\NodeInterface;
+use Drupal\toc_api\TocInterface;
+use Drupal\toc_api\TocManagerInterface;
 use Symfony\Component\DependencyInjection\ContainerInterface;
 
 /**
- * Provides a base TOC block which displays the current TOC module's TOC in a
- * block.
+ * Provides a base block which displays the current TOC module's TOC in a block.
  */
 abstract class TocBlockBase extends BlockBase implements ContainerFactoryPluginInterface {
 
@@ -20,7 +24,21 @@ abstract class TocBlockBase extends BlockBase implements ContainerFactoryPluginI
    *
    * @var \Drupal\Core\Routing\RouteMatchInterface
    */
-  protected $routeMatch;
+  protected RouteMatchInterface $routeMatch;
+
+  /**
+   * The entity type manager.
+   *
+   * @var \Drupal\Core\Entity\EntityTypeManagerInterface
+   */
+  protected EntityTypeManagerInterface $entityTypeManager;
+
+  /**
+   * The TOC manager.
+   *
+   * @var \Drupal\toc_api\TocManagerInterface
+   */
+  protected TocManagerInterface $tocManager;
 
   /**
    * Creates a LocalActionsBlock instance.
@@ -33,34 +51,38 @@ abstract class TocBlockBase extends BlockBase implements ContainerFactoryPluginI
    *   The plugin implementation definition.
    * @param \Drupal\Core\Routing\RouteMatchInterface $route_match
    *   The route match.
+   * @param \Drupal\Core\Entity\EntityTypeManagerInterface $entity_type_manager
+   *   The entity type manager.
+   * @param \Drupal\toc_api\TocManagerInterface $toc_manager
+   *   The TOC manager.
    */
-  public function __construct(array $configuration, $plugin_id, $plugin_definition, RouteMatchInterface $route_match) {
+  final public function __construct(array $configuration, $plugin_id, $plugin_definition, RouteMatchInterface $route_match, EntityTypeManagerInterface $entity_type_manager, TocManagerInterface $toc_manager) {
     parent::__construct($configuration, $plugin_id, $plugin_definition);
     $this->routeMatch = $route_match;
+    $this->entityTypeManager = $entity_type_manager;
+    $this->tocManager = $toc_manager;
   }
 
   /**
    * {@inheritdoc}
    */
-  public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) {
+  public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition): static {
     return new static(
       $configuration,
       $plugin_id,
       $plugin_definition,
-      $container->get('current_route_match')
+      $container->get('current_route_match'),
+      $container->get('entity_type.manager'),
+      $container->get('toc_api.manager')
     );
   }
 
   /**
    * {@inheritdoc}
    */
-  public function build() {
+  public function build(): array {
     $toc = $this->getCurrentToc();
 
-    if (empty($toc)) {
-      return [];
-    }
-
     // Build the TOC.
     $options = $toc->getOptions();
     $build = [
@@ -82,12 +104,9 @@ abstract class TocBlockBase extends BlockBase implements ContainerFactoryPluginI
    * @return \Drupal\toc_api\TocInterface
    *   A TOC object.
    */
-  protected function getCurrentToc() {
-    /** @var \Drupal\toc_api\TocManagerInterface $toc_manager */
-    $toc_manager = \Drupal::service('toc_api.manager');
-
+  protected function getCurrentToc(): TocInterface {
     // Get the new TOC instance using the module name.
-    return $toc_manager->getToc($this->getCurrentTocId());
+    return $this->tocManager->getToc($this->getCurrentTocId());
   }
 
   /**
@@ -99,21 +118,21 @@ abstract class TocBlockBase extends BlockBase implements ContainerFactoryPluginI
    * @return string
    *   The current TOC block's plugin ID.
    */
-  protected function getCurrentTocId() {
+  protected function getCurrentTocId(): string {
     return $this->pluginId;
   }
 
   /**
    * {@inheritdoc}
    */
-  public function getCacheContexts() {
+  public function getCacheContexts(): array {
     return ['route'];
   }
 
   /**
    * {@inheritdoc}
    */
-  public function getCacheTags() {
+  public function getCacheTags(): array {
     $node = $this->getCurrentNode();
     return ($node) ? ['node:' . $node->id()] : [];
   }
@@ -122,14 +141,15 @@ abstract class TocBlockBase extends BlockBase implements ContainerFactoryPluginI
    * Load the node associated with the current request.
    *
    * @return \Drupal\node\NodeInterface|null
-   *   A node entity, or NULL if no node is not found.
+   *   A node entity, or NULL if no node is found.
    */
-  protected function getCurrentNode() {
+  protected function getCurrentNode(): ?NodeInterface {
     switch ($this->routeMatch->getRouteName()) {
       // Look at the request's node revision.
       case 'node.revision_show':
-        return node_revision_load($this->routeMatch
-          ->getParameter('node_revision'));
+        $node_storage = $this->entityTypeManager->getStorage('node');
+        $node = $node_storage->loadRevision($this->routeMatch->getParameter('node_revision'));
+        return ($node instanceof NodeInterface) ? $node : NULL;
 
       // Look at the request's node preview.
       case 'entity.node.preview':
@@ -146,14 +166,10 @@ abstract class TocBlockBase extends BlockBase implements ContainerFactoryPluginI
   /**
    * {@inheritdoc}
    */
-  protected function blockAccess(AccountInterface $account) {
-    $this->getCurrentTocId();
-    /** @var \Drupal\toc_api\TocManagerInterface $toc_manager */
-    $toc_manager = \Drupal::service('toc_api.manager');
-
+  protected function blockAccess(AccountInterface $account): AccessResultInterface {
     // Get the new TOC instance and see if it is visible and should be
     // displayed in a block.
-    $toc = $toc_manager->getToc($this->getCurrentTocId());
+    $toc = $this->tocManager->getToc($this->getCurrentTocId());
 
     if (!$toc || !$toc->isVisible() || !$toc->isBlock()) {
       return AccessResult::forbidden();
diff --git a/src/Toc.php b/src/Toc.php
index 4a0d1e7a9ba1804d8c4d4a8056fdd3e1aa7dcce7..3c7256410d592139b667d9dae6798e8909ab4281 100644
--- a/src/Toc.php
+++ b/src/Toc.php
@@ -72,9 +72,9 @@ class Toc implements TocInterface {
   /**
    * The number of root headers found in the content.
    *
-   * @var int
+   * @var int|null
    */
-  protected $headerCount;
+  protected $headerCount = NULL;
 
   /**
    * The source content with unique header ids.
@@ -100,9 +100,9 @@ class Toc implements TocInterface {
   /**
    * The toc represent as a tree.
    *
-   * @var array
+   * @var array|null
    */
-  protected $tree;
+  protected $tree = NULL;
 
   /**
    * Existing in the source content IDs.
@@ -192,16 +192,12 @@ class Toc implements TocInterface {
     $this->allowedTags = $this->formatter()->convertAllowedTagsToArray($this->options['header_allowed_tags']);
 
     $this->initialize();
-
-    // DEBUG:
-    // dsm($this->getIndex());
-    // dsm($this->getTree());
   }
 
   /**
    * Initializes the table of content index and ensure unique header ids.
    */
-  protected function initialize() {
+  protected function initialize(): void {
     $this->index = [];
 
     // Setup an empty array of keys to track the index's keys.
@@ -340,7 +336,7 @@ class Toc implements TocInterface {
           '#markup' => $header_html,
           '#allowed_tags' => $this->getAllowedTags(),
         ],
-        'url' => Url::fromRoute('<none>', NULL, [
+        'url' => Url::fromRoute('<none>', [], [
           'fragment' => $header_id,
         ]),
       ];
@@ -356,6 +352,7 @@ class Toc implements TocInterface {
    *   The TOC formatter
    */
   protected function formatter() {
+    // @phpstan-ignore-next-line
     return \Drupal::service('toc_api.formatter');
   }
 
@@ -398,7 +395,8 @@ class Toc implements TocInterface {
    * {@inheritdoc}
    */
   public function getHeaderCount() {
-    if (!isset($this->headerCount)) {
+    if ($this->headerCount === NULL) {
+      $this->headerCount = 0;
       foreach ($this->index as $item) {
         if (empty($item['parent'])) {
           $this->headerCount++;
@@ -419,7 +417,7 @@ class Toc implements TocInterface {
    * {@inheritdoc}
    */
   public function getTree() {
-    if (!isset($this->tree)) {
+    if ($this->tree === NULL) {
       $this->tree = [
         'title' => $this->options['title'],
       ];
@@ -445,7 +443,7 @@ class Toc implements TocInterface {
    * @param array $children
    *   An array of keys to be associative to the parent header item.
    */
-  protected function buildTree(array &$item, array $children) {
+  protected function buildTree(array &$item, array $children): void {
     $item['below_type'] = '';
     $item['below'] = [];
     foreach ($children as $key) {
@@ -498,8 +496,6 @@ class Toc implements TocInterface {
    *
    * @param \DOMDocument $dom
    *   DOM object.
-   *
-   * @return void
    */
   protected function collectExistingIds(\DOMDocument $dom): void {
     $xpath = new \DOMXPath($dom);
@@ -518,8 +514,6 @@ class Toc implements TocInterface {
    *
    * @param \DOMDocument $dom
    *   DOM object.
-   *
-   * @return void
    */
   protected function useIdsOnly(\DOMDocument $dom): void {
     $xpath = new \DOMXPath($dom);
diff --git a/src/TocBuilder.php b/src/TocBuilder.php
index 4050680dcacd777c65d7b41340e1467bbfa6a8e7..5556512894f35c2adc9e2460153288e26abfc411 100644
--- a/src/TocBuilder.php
+++ b/src/TocBuilder.php
@@ -4,11 +4,14 @@ namespace Drupal\toc_api;
 
 use Drupal\Component\Utility\Html;
 use Drupal\Component\Utility\Xss;
+use Drupal\Core\Render\Markup;
 use Drupal\Core\Render\RendererInterface;
 
 /**
- * Defines a service that builds and renders a table of contents and update an
- * HTML document's headers.
+ * Defines a service to build TOC.
+ *
+ * This service builds and renders a table of contents and update an HTML
+ * document's headers.
  */
 class TocBuilder implements TocBuilderInterface {
 
@@ -150,10 +153,13 @@ class TocBuilder implements TocBuilderInterface {
    */
   public function renderToc(TocInterface $toc) {
     if (!$toc->isVisible()) {
-      return '';
+      return Markup::create('');
     }
 
     $build = $this->buildToc($toc);
+    if (empty($build)) {
+      return Markup::create('');
+    }
     return $this->renderer->render($build);
   }
 
diff --git a/src/TocBuilderInterface.php b/src/TocBuilderInterface.php
index fdd0c1d88da47d13f4898b11f35bb0db6f5396bd..cfc02bd946b6c28c83fcde6c68c5a73718253f8b 100644
--- a/src/TocBuilderInterface.php
+++ b/src/TocBuilderInterface.php
@@ -26,8 +26,8 @@ interface TocBuilderInterface {
    *   A TOC object.
    *
    * @return array
-   *   A render array containing the table of content's body content with bookmarked, typed, and custom
-   *   headers with back to top links.
+   *   A render array containing the table of content's body content with
+   *   bookmarked, typed, and custom headers with back to top links.
    */
   public function buildContent(TocInterface $toc);
 
diff --git a/src/TocFormatter.php b/src/TocFormatter.php
index 3a30b302dce0d47ddd680c565589271e8625463a..1550948c0d694e5231eb1db8a27f7cff637b4367 100644
--- a/src/TocFormatter.php
+++ b/src/TocFormatter.php
@@ -3,7 +3,7 @@
 namespace Drupal\toc_api;
 
 /**
- * Defines a service for formatting a table of content's headers, numbering, and ids..
+ * Defines a service for formatting a TOC headers, numbering, and ids.
  */
 class TocFormatter implements TocFormatterInterface {
 
@@ -12,7 +12,90 @@ class TocFormatter implements TocFormatterInterface {
    */
   public function convertStringToId($text) {
     // Replace accents with their counterparts.
-    $text = strtr($text, ['Š' => 'S', 'š' => 's', 'Đ' => 'Dj', 'đ' => 'dj', 'Ž' => 'Z', 'ž' => 'z', 'Č' => 'C', 'č' => 'c', 'Ć' => 'C', 'ć' => 'c', 'À' => 'A', 'Á' => 'A', 'Â' => 'A', 'Ã' => 'A', 'Ä' => 'A', 'Å' => 'A', 'Æ' => 'A', 'Ç' => 'C', 'È' => 'E', 'É' => 'E', 'Ê' => 'E', 'Ë' => 'E', 'Ì' => 'I', 'Í' => 'I', 'Î' => 'I', 'Ï' => 'I', 'Ñ' => 'N', 'Ò' => 'O', 'Ó' => 'O', 'Ô' => 'O', 'Õ' => 'O', 'Ö' => 'O', 'Ø' => 'O', 'Ù' => 'U', 'Ú' => 'U', 'Û' => 'U', 'Ü' => 'U', 'Ý' => 'Y', 'Þ' => 'B', 'ß' => 'Ss', 'à' => 'a', 'á' => 'a', 'â' => 'a', 'ã' => 'a', 'ä' => 'a', 'å' => 'a', 'æ' => 'a', 'ç' => 'c', 'è' => 'e', 'é' => 'e', 'ê' => 'e', 'ë' => 'e', 'ì' => 'i', 'í' => 'i', 'î' => 'i', 'ï' => 'i', 'ð' => 'o', 'ñ' => 'n', 'ò' => 'o', 'ó' => 'o', 'ô' => 'o', 'õ' => 'o', 'ö' => 'o', 'ø' => 'o', 'ù' => 'u', 'ú' => 'u', 'û' => 'u', 'ý' => 'y', 'þ' => 'b', 'ÿ' => 'y', 'Ŕ' => 'R', 'ŕ' => 'r', 'Ā' => 'A', 'Ē' => 'E', 'Ī' => 'I', 'Ō' => 'O', 'Ū' => 'U', 'ā' => 'a', 'ē' => 'e', 'ī' => 'i', 'ō' => 'o', 'ū' => 'u']);
+    $text = strtr($text, [
+      'Š' => 'S',
+      'š' => 's',
+      'Đ' => 'Dj',
+      'đ' => 'dj',
+      'Ž' => 'Z',
+      'ž' => 'z',
+      'Č' => 'C',
+      'č' => 'c',
+      'Ć' => 'C',
+      'ć' => 'c',
+      'À' => 'A',
+      'Á' => 'A',
+      'Â' => 'A',
+      'Ã' => 'A',
+      'Ä' => 'A',
+      'Å' => 'A',
+      'Æ' => 'A',
+      'Ç' => 'C',
+      'È' => 'E',
+      'É' => 'E',
+      'Ê' => 'E',
+      'Ë' => 'E',
+      'Ì' => 'I',
+      'Í' => 'I',
+      'Î' => 'I',
+      'Ï' => 'I',
+      'Ñ' => 'N',
+      'Ò' => 'O',
+      'Ó' => 'O',
+      'Ô' => 'O',
+      'Õ' => 'O',
+      'Ö' => 'O',
+      'Ø' => 'O',
+      'Ù' => 'U',
+      'Ú' => 'U',
+      'Û' => 'U',
+      'Ü' => 'U',
+      'Ý' => 'Y',
+      'Þ' => 'B',
+      'ß' => 'Ss',
+      'à' => 'a',
+      'á' => 'a',
+      'â' => 'a',
+      'ã' => 'a',
+      'ä' => 'a',
+      'å' => 'a',
+      'æ' => 'a',
+      'ç' => 'c',
+      'è' => 'e',
+      'é' => 'e',
+      'ê' => 'e',
+      'ë' => 'e',
+      'ì' => 'i',
+      'í' => 'i',
+      'î' => 'i',
+      'ï' => 'i',
+      'ð' => 'o',
+      'ñ' => 'n',
+      'ò' => 'o',
+      'ó' => 'o',
+      'ô' => 'o',
+      'õ' => 'o',
+      'ö' => 'o',
+      'ø' => 'o',
+      'ù' => 'u',
+      'ú' => 'u',
+      'û' => 'u',
+      'ý' => 'y',
+      'þ' => 'b',
+      'ÿ' => 'y',
+      'Ŕ' => 'R',
+      'ŕ' => 'r',
+      'Ā' => 'A',
+      'Ē' => 'E',
+      'Ī' => 'I',
+      'Ō' => 'O',
+      'Ū' => 'U',
+      'ā' => 'a',
+      'ē' => 'e',
+      'ī' => 'i',
+      'ō' => 'o',
+      'ū' => 'u',
+    ]);
 
     // Lowercase.
     $text = strtolower($text);
@@ -40,6 +123,10 @@ class TocFormatter implements TocFormatterInterface {
    * {@inheritdoc}
    */
   public function convertNumberToListTypeValue($number, $type) {
+    if ($type === NULL) {
+      $type = '';
+    }
+
     $case_func = NULL;
     // Check if type should upper or lower cased.
     if (preg_match('/^(upper|lower)-(.+)$/', (string) $type, $match)) {
@@ -72,7 +159,21 @@ class TocFormatter implements TocFormatterInterface {
    * {@inheritdoc}
    */
   public function convertNumberToRomanNumeral($number) {
-    $roman_numerals = ['M' => 1000, 'CM' => 900, 'D' => 500, 'CD' => 400, 'C' => 100, 'XC' => 90, 'L' => 50, 'XL' => 40, 'X' => 10, 'IX' => 9, 'V' => 5, 'IV' => 4, 'I' => 1];
+    $roman_numerals = [
+      'M' => 1000,
+      'CM' => 900,
+      'D' => 500,
+      'CD' => 400,
+      'C' => 100,
+      'XC' => 90,
+      'L' => 50,
+      'XL' => 40,
+      'X' => 10,
+      'IX' => 9,
+      'V' => 5,
+      'IV' => 4,
+      'I' => 1,
+    ];
     $result = '';
     foreach ($roman_numerals as $roman_numeral => $roman_number) {
       $matches = intval($number / $roman_number);
@@ -86,7 +187,34 @@ class TocFormatter implements TocFormatterInterface {
    * {@inheritdoc}
    */
   public function convertNumberToLetter($number) {
-    static $letters = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z'];
+    static $letters = [
+      'a',
+      'b',
+      'c',
+      'd',
+      'e',
+      'f',
+      'g',
+      'h',
+      'i',
+      'j',
+      'k',
+      'l',
+      'm',
+      'n',
+      'o',
+      'p',
+      'q',
+      'r',
+      's',
+      't',
+      'u',
+      'v',
+      'w',
+      'x',
+      'y',
+      'z',
+    ];
     return $letters[(($number - 1) % 26)];
   }
 
diff --git a/src/TocFormatterInterface.php b/src/TocFormatterInterface.php
index f2757816f41d273e9b34bbee8a4e6d94fba08f19..6387b96bd2d8bade48e2eb667afbb400b161b1b0 100644
--- a/src/TocFormatterInterface.php
+++ b/src/TocFormatterInterface.php
@@ -38,7 +38,7 @@ interface TocFormatterInterface {
    *
    * @param int $number
    *   A number.
-   * @param string $type
+   * @param string|null $type
    *   The HTML5 list-style-type.
    *
    * @return string
diff --git a/src/TocInterface.php b/src/TocInterface.php
index a16130c7baee1e1e2667678c02653f8f83b936c4..95f34bb6af356fe50945b9a031c359544e024d19 100644
--- a/src/TocInterface.php
+++ b/src/TocInterface.php
@@ -50,7 +50,9 @@ interface TocInterface {
   /**
    * Returns a hierarchical array of headers.
    *
-   * @return array
+   * @todo update the description text.
+   *
+   * @return int
    *   An hierarchical array of headers.
    */
   public function getHeaderCount();
diff --git a/src/TocManager.php b/src/TocManager.php
index cdc7396117cd598c6dcc4fe3116572013da2e5fc..adb927f72eadc86311d7f813ed3b765f626c9bda 100644
--- a/src/TocManager.php
+++ b/src/TocManager.php
@@ -38,10 +38,11 @@ class TocManager implements TocManagerInterface {
   /**
    * {@inheritdoc}
    */
-  public function create($id, $source, array $options = []) {
+  public function create(string $id, string $source, array $options = []): TocInterface {
     // Merge default TOC type options with passed options.
-    /** @var \Drupal\toc_api\TocTypeInterface $default_toc */
-    if ($default_toc = TocType::load('default')) {
+    /** @var \Drupal\toc_api\TocTypeInterface|null $default_toc */
+    $default_toc = TocType::load('default');
+    if ($default_toc !== NULL) {
       $options = NestedArray::mergeDeep($default_toc->getOptions(), $options);
     }
 
@@ -53,14 +54,14 @@ class TocManager implements TocManagerInterface {
   /**
    * {@inheritdoc}
    */
-  public function getToc($id) {
+  public function getToc(string $id): ?TocInterface {
     return (isset($this->tocs[$id])) ? $this->tocs[$id] : NULL;
   }
 
   /**
    * {@inheritdoc}
    */
-  public function reset($id = NULL) {
+  public function reset(?string $id = NULL): void {
     if ($id === NULL) {
       $this->tocs = [];
     }
diff --git a/src/TocManagerInterface.php b/src/TocManagerInterface.php
index 901048db76fbeab31afcdf92b76ad1d84e133bf5..9bbd8fa6cb9f1ec4d1e932816b285cd4a5893b31 100644
--- a/src/TocManagerInterface.php
+++ b/src/TocManagerInterface.php
@@ -23,7 +23,7 @@ interface TocManagerInterface {
    * @return \Drupal\toc_api\TocInterface
    *   A new TOC object.
    */
-  public function create($id, $source, array $options = []);
+  public function create(string $id, string $source, array $options = []): TocInterface;
 
   /**
    * Get the current TOC instance.
@@ -32,10 +32,10 @@ interface TocManagerInterface {
    *   ID used to track the TOC object's instance. Typically, the ID can be
    *   the TOC implementation's module name.
    *
-   * @return \Drupal\toc_api\TocInterface
+   * @return \Drupal\toc_api\TocInterface|null
    *   The current TOC instance.
    */
-  public function getToc($id);
+  public function getToc(string $id): ?TocInterface;
 
   /**
    * Reset the current TOC instance.
@@ -44,6 +44,6 @@ interface TocManagerInterface {
    *   ID used to track the TOC object's instance. Typically, the ID can be
    *   the TOC implementation's module name.
    */
-  public function reset($id = NULL);
+  public function reset(?string $id = NULL): void;
 
 }
diff --git a/src/TocTypeForm.php b/src/TocTypeForm.php
index 4dbe5634dd3440f8999a673da397138da5782e9d..14a30f095324b533e35359586cd575474ab71d3f 100644
--- a/src/TocTypeForm.php
+++ b/src/TocTypeForm.php
@@ -48,13 +48,14 @@ class TocTypeForm extends EntityForm {
    *
    * @param \Drupal\Core\Entity\EntityTypeManagerInterface $entity_type_manager
    *   The entity query factory.
-   *
    * @param \Drupal\Core\Theme\Registry $theme_registry
    *   The theme registry.
    * @param \Drupal\Core\Theme\ThemeManagerInterface $theme_manager
    *   The theme manager.
+   * @param \Drupal\Core\Theme\ThemeInitializationInterface $theme_initialization
+   *   The theme initialization logic.
    */
-  public function __construct(EntityTypeManagerInterface $entity_type_manager, Registry $theme_registry, ThemeManagerInterface $theme_manager, ThemeInitializationInterface $theme_initialization) {
+  final public function __construct(EntityTypeManagerInterface $entity_type_manager, Registry $theme_registry, ThemeManagerInterface $theme_manager, ThemeInitializationInterface $theme_initialization) {
     $this->entityTypeManager = $entity_type_manager;
     $this->themeRegistry = $theme_registry;
     $this->themeManager = $theme_manager;
@@ -64,7 +65,7 @@ class TocTypeForm extends EntityForm {
   /**
    * {@inheritdoc}
    */
-  public static function create(ContainerInterface $container) {
+  public static function create(ContainerInterface $container): static {
     return new static(
       $container->get('entity_type.manager'),
       $container->get('theme.registry'),
@@ -78,6 +79,9 @@ class TocTypeForm extends EntityForm {
    */
   public function buildForm(array $form, FormStateInterface $form_state) {
     $toc_type = $this->entity;
+    if (!($toc_type instanceof TocTypeInterface)) {
+      return $form;
+    }
     $options = $toc_type->getOptions();
 
     // An associative array of HTML header tags keyed by level.
@@ -309,8 +313,7 @@ class TocTypeForm extends EntityForm {
       $form['options']['numbering']['headers'][$header_tag]['custom'] = [
         '#title' => $this->t('Customize @tag numbering', [
           '@tag' => $header_tag,
-        ]
-        ),
+        ]),
         '#type' => 'checkbox',
         '#default_value' => $header_options['custom'],
         '#attributes' => ['class' => ["js-toc-type-options-headers-$header_tag-custom"]],
@@ -367,7 +370,7 @@ class TocTypeForm extends EntityForm {
   /**
    * {@inheritdoc}
    */
-  public function submitForm(array &$form, FormStateInterface $form_state) {
+  public function submitForm(array &$form, FormStateInterface $form_state): void {
     $values = $form_state->getValues();
 
     $options = $values['general'] + $values['header'] + $values['top'] + $values['numbering'];
@@ -405,6 +408,7 @@ class TocTypeForm extends EntityForm {
     $this->messenger()->addMessage($this->t('Table of contents type %label saved.', ['%label' => $toc_type->label()]));
 
     $form_state->setRedirect('entity.toc_type.collection');
+    return parent::save($form, $form_state);
   }
 
   /**
@@ -418,13 +422,12 @@ class TocTypeForm extends EntityForm {
    */
   public function exists($id) {
     return (bool) $this->entityTypeManager
-      ->get('toc_type')
-      ->condition('id', $id)
-      ->execute();
+      ->getStorage('toc_type')
+      ->load($id);
   }
 
   /**
-   * Get TOC templates from the theme registry for the default theme as an associative array of options.
+   * Get TOC templates from the theme registry for the default theme.
    *
    * @return array
    *   TOC templates as an associative array of options.
diff --git a/src/TocTypeListBuilder.php b/src/TocTypeListBuilder.php
index e95ee205c878d7c6a33b47a54aebbb0e460d6dc1..fc9976ceb2fec3ee49f563ef9dfd4f58521ccbb2 100644
--- a/src/TocTypeListBuilder.php
+++ b/src/TocTypeListBuilder.php
@@ -26,6 +26,9 @@ class TocTypeListBuilder extends ConfigEntityListBuilder {
    * {@inheritdoc}
    */
   public function buildRow(EntityInterface $entity) {
+    if (!($entity instanceof TocTypeInterface)) {
+      return parent::buildRow($entity);
+    }
     $options = $entity->getOptions();
 
     $row['label'] = $entity->label();
diff --git a/templates/toc-menu.html.twig b/templates/toc-menu.html.twig
index 65b970a39c356e70e5d6e341e8d0e8f928b30969..92646f0a9c0f3283ef424a4ecae5ff3394055723 100644
--- a/templates/toc-menu.html.twig
+++ b/templates/toc-menu.html.twig
@@ -9,7 +9,7 @@
  * - index: List of header items. Each header item contains:
  *   - prefix: The header option prefix. Either indentation or the complete path.
  *   - title: The header title.
- *   - url: The header fragrment (ie hash) URL, instance of \Drupal\Core\Url.
+ *   - url: The header fragment (ie hash) URL, instance of \Drupal\Core\Url.
  *
  * @ingroup themeable
  */
diff --git a/templates/toc-tree.html.twig b/templates/toc-tree.html.twig
index e582d62423087f9c06382d6c39f685b4aacef703..09d591474e009851f8d9cebedbde6bd34278400e 100644
--- a/templates/toc-tree.html.twig
+++ b/templates/toc-tree.html.twig
@@ -13,7 +13,7 @@
  *   - attributes: HTML attributes for the table of contents or list item.
  *   - below: The table of contents child items.
  *   - title: The table of contents or header title.
- *   - url: The header fragrment (ie hash) URL, instance of \Drupal\Core\Url.
+ *   - url: The header fragment (ie hash) URL, instance of \Drupal\Core\Url.
  *
  * @ingroup themeable
  */
diff --git a/tests/src/Kernel/TocBuilderTest.php b/tests/src/Kernel/TocBuilderTest.php
index cdf6bf01f0e093e33b3e32208b119ddc0a58abab..7cf81dea567279d718f4df05ab2a70c0b1dae7dc 100644
--- a/tests/src/Kernel/TocBuilderTest.php
+++ b/tests/src/Kernel/TocBuilderTest.php
@@ -20,6 +20,8 @@ class TocBuilderTest extends KernelTestBase {
   protected static $modules = ['toc_api'];
 
   /**
+   * The TOC manager.
+   *
    * @var \Drupal\toc_api\TocManagerInterface
    */
   protected TocManagerInterface $manager;
@@ -40,7 +42,7 @@ class TocBuilderTest extends KernelTestBase {
    *
    * @todo Convert to unit test and include in TocTest, once that is fixed.
    */
-  public function testDuplicateIds() {
+  public function testDuplicateIds(): void {
     $toc_source = <<<HTML
     <p><a name="documents"></a></p>
     <h2>Documents</h2>
diff --git a/tests/src/Kernel/TocManagerTest.php b/tests/src/Kernel/TocManagerTest.php
index 0f30ed7119f990e36fa3fc0032f2691824251546..6c1f8ce912135fae6ff4d864053a6c1a22789d13 100755
--- a/tests/src/Kernel/TocManagerTest.php
+++ b/tests/src/Kernel/TocManagerTest.php
@@ -15,21 +15,41 @@ class TocManagerTest extends KernelTestBase {
   /**
    * Modules to enable.
    *
-   * @var array
+   * @var string[]
    */
-  public static $modules = ['system', 'toc_api'];
+  protected static $modules = ['system', 'toc_api'];
+
+  /**
+   * The default theme.
+   *
+   * @var string
+   */
+  protected $defaultTheme = 'stark';
+
+  /**
+   * The content.
+   *
+   * @var string
+   */
+  protected string $contentToc;
 
   /**
    * Empty test to avoid error about there being no tests.
    *
    * Remove when re-enabling disabledTestRender().
+   *
+   * @return void
+   *   No return value.
    */
-  public function testRender() {
-    $this->assertNull(NULL);
+  public function testRender(): void {
+    $this->markTestSkipped('Temporarily skipping until real tests are added.');
   }
 
   /**
    * Tests TOC rendering. Temporarily disabled.
+   *
+   * @return mixed
+   *   Could return full content (toc tables) or NULL
    */
   public function disabledTestRender() {
     /** @var \Drupal\Core\Render\RendererInterface $renderer */
@@ -42,16 +62,16 @@ class TocManagerTest extends KernelTestBase {
     // Create render toc and content functions with context.
     $render_toc = function ($toc) use ($toc_builder, $renderer) {
       return $renderer->executeInRenderContext(new RenderContext(), function () use ($toc_builder, $toc) {
-        $content = $toc_builder->renderToc($toc);
-        $this->content = $content;
-        return $content;
+        $contentToc = $toc_builder->renderToc($toc);
+        $this->content = $contentToc;
+        return $contentToc;
       });
     };
     $render_content = function ($toc) use ($toc_builder, $renderer) {
       return $renderer->executeInRenderContext(new RenderContext(), function () use ($toc_builder, $toc) {
-        $content = $toc_builder->renderContent($toc);
-        $this->content = $content;
-        return $content;
+        $contentToc = $toc_builder->renderContent($toc);
+        $this->content = $contentToc;
+        return $contentToc;
       });
     };
 
@@ -65,14 +85,14 @@ class TocManagerTest extends KernelTestBase {
     // Check default TOC options.
     $toc = $toc_manager->create('toc_test', '<h2>header 2</h2><h3>header 3</h3><h4>header 4</h4><h4>header 4</h4><h2>header 2</h2>', []);
     $render_toc($toc);
-    $this->assertNotFalse($this->cssSelect('.toc-desktop.toc.toc-tree'), 'Toc tree exists');
+    $this->assertNotEmpty($this->cssSelect('.toc-desktop.toc.toc-tree'), 'Toc tree exists');
     $this->assertRaw('<h3>Table of Contents</h3>');
     $this->assertRaw('<a href="#header-2">header 2</a>');
     $this->assertRaw('<a href="#header-3">header 3</a>');
     $this->assertRaw('<a href="#header-4">header 4</a>');
     $this->assertRaw('<a href="#header-4-01">header 4</a>');
     $this->assertRaw('<a href="#header-2-01">header 2</a>');
-    $this->assertNotFalse($this->cssSelect('.toc-mobile.toc.toc-menu'), 'Toc menu exists');
+    $this->assertNotEmpty($this->cssSelect('.toc-mobile.toc.toc-menu'), 'Toc menu exists');
     $this->assertRaw('<option value="">Table of Contents</option>');
     $this->assertRaw('<option value="#header-2">1) header 2</option>');
     $this->assertRaw('<option value="#header-3">1.1) header 3</option>');
@@ -80,8 +100,8 @@ class TocManagerTest extends KernelTestBase {
     $this->assertRaw('<option value="#header-4-01">1.1.2) header 4</option>');
     $this->assertRaw('<option value="#header-2-01">2) header 2</option>');
     $render_content($toc);
-    $this->assertPattern('|<a href="#top" class="back-to-top">Back to top</a>\s+<h2|s', 'Back to top before h2');
-    $this->assertPattern('|<a href="#top" class="back-to-top">Back to top</a>\s+$|s', 'Back to top at the bottom');
+    $this->assertMatchesRegularExpression('|<a href="#top" class="back-to-top">Back to top</a>\s+<h2|s', 'Back to top before h2');
+    $this->assertMatchesRegularExpression('|<a href="#top" class="back-to-top">Back to top</a>\s+$|s', 'Back to top at the bottom');
     $this->assertRaw('<a href="#top" class="back-to-top">Back to top</a>');
     $this->assertRaw('<h2 id="header-2"><span>1) </span>header 2</h2>');
     $this->assertRaw('<h3 id="header-3"><span>1.1) </span>header 3</h3>');
@@ -99,7 +119,11 @@ class TocManagerTest extends KernelTestBase {
     ];
     $toc = $toc_manager->create('toc_test', '<h2>header 2</h2><h3>header 3</h3><h4>header 4</h4><h4>header 4</h4><h2>header 2</h2>', $options);
     $render_toc($toc);
-    $this->assertPattern('|<ol class="decimal">.*?<ol class="lower-alpha">.*?<ol class="lower-roman">|s');
+    $this->assertMatchesRegularExpression('|<ol class="decimal">.*?<ol class="lower-alpha">.*?<ol class="lower-roman">|s',
+      // Contenu à tester.
+      $this->content,
+      'Failed asserting that the HTML structure matches the expected TOC format.'
+    );
     $render_content($toc);
     $this->assertRaw('<h2 id="header-2"><span>1) </span>header 2</h2>');
     $this->assertRaw('<h3 id="header-3"><span>1.a) </span>header 3</h3>');
@@ -125,11 +149,12 @@ class TocManagerTest extends KernelTestBase {
     ];
     $toc = $toc_manager->create('toc_test', '<h2>header 2</h2><h3>header 3</h3><h4>header 4</h4><h4>header 4</h4><h2>header 2</h2>', $options);
     $render_content($toc);
-    $this->assertNoPattern('|<a href="#top" class="back-to-top">TOP</a>\s+<h2|s', 'No back to top before h2');
-    $this->assertNoPattern('|<a href="#top" class="back-to-top">TOP</a>\s+$|s', 'No back to top at the bottom');
-    $this->assertPattern('|<a href="#top" class="back-to-top">TOP</a>\s+<h3 id="header-3"><span>1.1\) </span>header 3</h3>|s', 'Back to top before h3');
-    $this->assertPattern('|<a href="#top" class="back-to-top">TOP</a>\s+<h4 id="header-4"><span>1.1.1\) </span>header 4</h4>|s', 'Back to top before first h4');
-    $this->assertPattern('|<a href="#top" class="back-to-top">TOP</a>\s+<h4 id="header-4-01"><span>1.1.2\) </span>header 4</h4>|s', 'Back to top before second h4');
+
+    $this->assertNoPatternLocal('|<a href="#top" class="back-to-top">TOP</a>\s+<h2|s', 'No back to top before h2');
+    $this->assertNoPatternLocal('|<a href="#top" class="back-to-top">TOP</a>\s+$|s', 'No back to top at the bottom');
+    $this->assertMatchesRegularExpression('|<a href="#top" class="back-to-top">TOP</a>\s+<h3 id="header-3"><span>1.1\) </span>header 3</h3>|s', 'Back to top before h3');
+    $this->assertMatchesRegularExpression('|<a href="#top" class="back-to-top">TOP</a>\s+<h4 id="header-4"><span>1.1.1\) </span>header 4</h4>|s', 'Back to top before first h4');
+    $this->assertMatchesRegularExpression('|<a href="#top" class="back-to-top">TOP</a>\s+<h4 id="header-4-01"><span>1.1.2\) </span>header 4</h4>|s', 'Back to top before second h4');
 
     // Check list style type = 'none' and menu indent.
     $options = [
@@ -140,7 +165,7 @@ class TocManagerTest extends KernelTestBase {
     $this->assertRaw('<ol class="none">');
     $render_content($toc);
 
-    // Check unorder list when type = FALSE.
+    // Check unordered list when type = FALSE.
     $options = [
       'number_path' => FALSE,
       'default' => [
@@ -162,4 +187,25 @@ class TocManagerTest extends KernelTestBase {
     $this->assertRaw('<h4 id="header-4-01">header 4</h4>');
   }
 
+  /**
+   * Wrapper to handle assertRaw equivalent in PHPUnit.
+   */
+  protected function assertRaw(mixed $needle, mixed $message = ''): void {
+    $this->assertStringContainsString($needle, $this->content, $message);
+  }
+
+  /**
+   * Wrapper to handle assertNoRaw equivalent in PHPUnit.
+   */
+  protected function assertNoRaw(mixed $needle, mixed $message = ''): void {
+    $this->assertStringNotContainsString($needle, $this->content, $message);
+  }
+
+  /**
+   * Wrapper to handle assertNoPattern equivalent in PHPUnit.
+   */
+  protected function assertNoPatternLocal(mixed $pattern, mixed $message = ''): void {
+    $this->assertDoesNotMatchRegularExpression($pattern, $this->content, $message);
+  }
+
 }
diff --git a/tests/src/Unit/TocFormatterTest.php b/tests/src/Unit/TocFormatterTest.php
index 7ddfab24870360c9a37ddc28fd6cdd3cac617493..c5bbac2268d474b3747e2dd04ba361c1bc11c39f 100755
--- a/tests/src/Unit/TocFormatterTest.php
+++ b/tests/src/Unit/TocFormatterTest.php
@@ -31,7 +31,7 @@ class TocFormatterTest extends UnitTestCase {
   }
 
   /**
-   * Tests converting string to valid HTML id with TocFormatter::convertStringToId().
+   * Tests converting string to valid HTML id.
    *
    * @param string $string
    *   The string to run through $this->formatter->convertStringToId().
@@ -42,7 +42,7 @@ class TocFormatterTest extends UnitTestCase {
    *
    * @dataProvider providerConvertStringToId
    */
-  public function testConvertStringToId($string, $expected) {
+  public function testConvertStringToId($string, $expected): void {
     $result = $this->formatter->convertStringToId($string);
     $this->assertEquals($expected, $result);
   }
@@ -52,7 +52,7 @@ class TocFormatterTest extends UnitTestCase {
    *
    * @see testConvertStringToId()
    */
-  public function providerConvertStringToId() {
+  public static function providerConvertStringToId(): array {
     $tests[] = ['One', 'one'];
     $tests[] = ['One   two', 'one-two'];
     $tests[] = ['One ! two', 'one-two'];
@@ -62,7 +62,7 @@ class TocFormatterTest extends UnitTestCase {
   }
 
   /**
-   * Tests converting number to list style type with TocFormatter::convertNumberToListTypeValue().
+   * Tests converting number to list style type.
    *
    * @param int $number
    *   The number to run through TocFormatter::convertNumberToListTypeValue().
@@ -75,7 +75,7 @@ class TocFormatterTest extends UnitTestCase {
    *
    * @dataProvider providerConvertNumberToListTypeValue
    */
-  public function testConvertNumberToListTypeValue($number, $type, $expected) {
+  public function testConvertNumberToListTypeValue($number, $type, $expected): void {
     $result = $this->formatter->convertNumberToListTypeValue($number, $type);
     $this->assertEquals($expected, $result);
   }
@@ -85,7 +85,7 @@ class TocFormatterTest extends UnitTestCase {
    *
    * @see testConvertNumberToListTypeValue()
    */
-  public function providerConvertNumberToListTypeValue() {
+  public static function providerConvertNumberToListTypeValue(): array {
     $tests[] = [1, NULL, 1];
     $tests[] = [1, 'decimal', '1'];
     $tests[] = [1, 'random', '1'];
@@ -108,7 +108,7 @@ class TocFormatterTest extends UnitTestCase {
   }
 
   /**
-   * Tests converting header keys to list style type values with TocFormatter::convertHeaderKeysToValues().
+   * Tests converting header keys to list style type values.
    *
    * @param array $keys
    *   The array to run through TocFormatter::convertHeaderKeysToValues().
@@ -121,7 +121,7 @@ class TocFormatterTest extends UnitTestCase {
    *
    * @dataProvider providerConvertHeaderKeysToValues
    */
-  public function testConvertHeaderKeysToValues(array $keys, array $options, $expected) {
+  public function testConvertHeaderKeysToValues(array $keys, array $options, $expected): void {
     $result = $this->formatter->convertHeaderKeysToValues($keys, $options);
     $this->assertEquals($expected, $result);
   }
@@ -131,7 +131,7 @@ class TocFormatterTest extends UnitTestCase {
    *
    * @see testConvertHeaderKeysToValues()
    */
-  public function providerConvertHeaderKeysToValues() {
+  public static function providerConvertHeaderKeysToValues(): array {
     $options = [
       'number_path_truncate' => TRUE,
       'headers' => [
@@ -145,7 +145,11 @@ class TocFormatterTest extends UnitTestCase {
     $tests[] = [['h1' => 2, 'h2' => 2, 'h3' => 0], $options, ['h1' => '2', 'h2' => 'b']];
     $tests[] = [['h1' => 2, 'h2' => 2, 'h3' => 0, 'h4' => 0], $options, ['h1' => '2', 'h2' => 'b']];
     $tests[] = [['h1' => 2, 'h2' => 0, 'h3' => 2], $options, ['h1' => '2', 'h2' => '0', 'h3' => 'ii']];
-    $tests[] = [['h1' => 2, 'h2' => 2, 'h3' => 0], ['number_path_truncate' => FALSE] + $options, ['h1' => '2', 'h2' => 'b', 'h3' => '0']];
+    $tests[] = [
+      ['h1' => 2, 'h2' => 2, 'h3' => 0],
+      ['number_path_truncate' => FALSE] + $options,
+      ['h1' => '2', 'h2' => 'b', 'h3' => '0'],
+    ];
     return $tests;
   }
 
diff --git a/tests/src/Unit/TocTest.php b/tests/src/Unit/TocTest.php
index 14f3fa0379cfb4ecb5c4d7d6e8850190656e229f..8de7592d264635d5932e6f1411a6f74b8b693baf 100755
--- a/tests/src/Unit/TocTest.php
+++ b/tests/src/Unit/TocTest.php
@@ -39,6 +39,9 @@ class TocTest extends UnitTestCase {
    * Tests parsing headers and creating a table of contents index.
    *
    * @see Toc::getIndex()
+   *
+   * @return void
+   *   Performs some internal tests, but doesn't return anything.
    */
   public function testIndex() {
     // Check default index. This covers type, tag, level, indent, keys, parent,
@@ -300,7 +303,7 @@ class TocTest extends UnitTestCase {
 
     // Check missing parent.
     $toc = new Toc('<h2>header 2</h2><h4>header 4</h4><h4>header 4</h4><h2>header 2</h2>', []);
-    $this->assertArraySubset([
+    $result = $this->assertArraySubset([
       '1.0.0' => [
         'parent' => NULL,
         'children' => [
@@ -327,6 +330,9 @@ class TocTest extends UnitTestCase {
    * Tests converting table of contents index to hierarchical tree.
    *
    * @see Toc::getTree()
+   *
+   * @return void
+   *   Performs some internal tests, but doesn't return anything.
    */
   public function testTree() {
     // Check parent child relationship.
@@ -419,11 +425,14 @@ class TocTest extends UnitTestCase {
    * Tests converting table of contents index to hierarchical tree.
    *
    * @see Toc::getContent()
+   *
+   * @return void
+   *   Runs a few render tests internally, no return value.
    */
   public function testContent() {
     // Check update content ids.
     $toc = new Toc('<h2>header 2</h2><h3 id="three" class="custom">header 3</h3><h4 id="four">header 4</h4><h4 id="four">header 4</h4><h2>header 2</h2>', []);
-    
+
     $content = $toc->getContent();
     $this->assertStringContainsString('<h2 id="header-2">', $content);
     $this->assertStringContainsString('<h3 id="three-01" class="custom">', $content);
@@ -435,6 +444,9 @@ class TocTest extends UnitTestCase {
    * Tests converting table of contents index to hierarchical tree.
    *
    * @see Toc::getHeaderCount()
+   *
+   * @return void
+   *   Runs a few render tests internally, no return value.
    */
   public function testHeaderCount() {
     // Check TOC is hidden.
@@ -451,20 +463,27 @@ class TocTest extends UnitTestCase {
   /**
    * Recursively asserts that the expected items are set in the tested ToC.
    *
-   * @param $expected
+   * @param array $expected
    *   An array of expected values, may contain further nested arrays.
-   * @param $actual
+   * @param array $actual
    *   The object to test.
+   *
+   * @return bool|string
+   *   Runs a few render tests internally, no return value.
    */
   protected function assertArraySubset($expected, $actual) {
+    $assert_result = "";
+
     foreach ($expected as $key => $value) {
       if (is_array($value)) {
-        $this->assertArraySubset($value, $actual[$key]);
+        $assert_result = $this->assertArraySubset($value, $actual[$key]);
       }
       else {
         $this->assertSame($value, $actual[$key]);
       }
     }
+
+    return $assert_result;
   }
 
   /**
@@ -474,6 +493,9 @@ class TocTest extends UnitTestCase {
    *   A TOC index or tree.
    * @param string $method
    *   The TOC method to tests.
+   *
+   * @return void
+   *   Runs a few render tests internally, no return value.
    */
   protected function dumpArraySubset(array $array, $method) {
     $this->dumpArraySubsetUnset($array);
@@ -489,6 +511,9 @@ class TocTest extends UnitTestCase {
    *
    * @param array $array
    *   A TOC index or tree.
+   *
+   * @return void
+   *   Runs a few tests internally, no return value.
    */
   protected function dumpArraySubsetUnset(array &$array) {
     foreach ($array as &$value) {
diff --git a/toc_api.info.yml b/toc_api.info.yml
index 31ce058b00005768baab96aaeaabc22f77d85b3a..4fd7db1accec1b1dd02497b3464202b5440f9a53 100644
--- a/toc_api.info.yml
+++ b/toc_api.info.yml
@@ -2,5 +2,5 @@ name: 'TOC API'
 type: module
 description: 'API for building a a hierarchical table of contents from header tags.'
 package: 'API'
-core_version_requirement: ^9.4 || ^10.0
+core_version_requirement: ^9.5 || ^10.2 || ^11.0
 configure: entity.toc_type.collection
diff --git a/toc_api.install b/toc_api.install
index 51a86fc88cc82f749d459248fdc39790ea5ff5e5..fcf2f83ffc8cea8b8abf1177321765549cd1479f 100644
--- a/toc_api.install
+++ b/toc_api.install
@@ -8,10 +8,11 @@
 /**
  * Add header_exclude_xpath to existing TOCs.
  */
-function toc_api_update_8001() {
+function toc_api_update_8001(): void {
   $toc_types = \Drupal::entityQuery('toc_type')->execute();
 
   foreach ($toc_types as $type) {
+    /** @var \Drupal\toc_api\TocTypeInterface $entity */
     $entity = \Drupal::entityTypeManager()->getStorage('toc_type')->load($type);
     $options = $entity->getOptions();
 
diff --git a/toc_api.module b/toc_api.module
index 62aa9c33b15789abe86c8d8beaf380bc8a86e49d..e9fe635da2b98837970e9a478a1634be20c119f3 100755
--- a/toc_api.module
+++ b/toc_api.module
@@ -11,7 +11,7 @@ use Drupal\Core\Template\Attribute;
 /**
  * Implements hook_help().
  */
-function toc_api_help($route_name, RouteMatchInterface $route_match) {
+function toc_api_help(string $route_name, RouteMatchInterface $route_match): ?string {
   switch ($route_name) {
     case 'help.page.toc_api':
       $output = '<h3>' . t('About') . '</h3>';
@@ -29,7 +29,7 @@ function toc_api_help($route_name, RouteMatchInterface $route_match) {
 /**
  * Implements hook_theme().
  */
-function toc_api_theme() {
+function toc_api_theme(): array {
   return [
     'toc_header' => [
       'variables' => ['toc' => NULL, 'item' => NULL, 'attributes' => []],
@@ -62,7 +62,7 @@ function toc_api_theme() {
  *   - toc: A TOC (table of contents) object.
  *   - item: A table of contents header item.
  */
-function template_preprocess_toc_header(&$variables) {
+function template_preprocess_toc_header(array &$variables): void {
   /** @var \Drupal\toc_api\TocInterface $toc */
   $toc = $variables['toc'];
 
@@ -73,7 +73,13 @@ function template_preprocess_toc_header(&$variables) {
   $options = $toc->getOptions();
   $variables['options'] = $options;
   $variables['header_options'] = $options['headers'][$item['tag']];
-  $variables['header_options']['display_number'] = in_array($variables['header_options']['number_type'], ['decimal', 'lower-alpha', 'upper-alpha', 'lower-roman', 'upper-roman']);
+  $variables['header_options']['display_number'] = in_array($variables['header_options']['number_type'], [
+    'decimal',
+    'lower-alpha',
+    'upper-alpha',
+    'lower-roman',
+    'upper-roman',
+  ]);
 
   $variables['attributes']['id'] = $variables['id'];
   $variables['attributes'] = new Attribute($variables['attributes']);
@@ -90,7 +96,7 @@ function template_preprocess_toc_header(&$variables) {
  *   - item: A table of contents header item.
  *   - attributes: Attributes to be added to back to top link.
  */
-function template_preprocess_toc_back_to_top(&$variables) {
+function template_preprocess_toc_back_to_top(array &$variables): void {
   /** @var \Drupal\toc_api\TocInterface $toc */
   $toc = $variables['toc'];
 
@@ -111,7 +117,7 @@ function template_preprocess_toc_back_to_top(&$variables) {
  *   - toc: A TOC (table of contents) object.
  *   - attributes: Attributes to be added to back to top link.
  */
-function template_preprocess_toc_tree(&$variables) {
+function template_preprocess_toc_tree(array &$variables): void {
   /** @var \Drupal\toc_api\TocInterface $toc */
   $toc = $variables['toc'];
 
@@ -139,7 +145,7 @@ function template_preprocess_toc_tree(&$variables) {
  *   - toc: A TOC (table of contents) object.
  *   - attributes: Attributes to be added to back to top link.
  */
-function template_preprocess_toc_menu(&$variables) {
+function template_preprocess_toc_menu(array &$variables): void {
   /** @var \Drupal\toc_api\TocInterface $toc */
   $toc = $variables['toc'];
 
@@ -177,7 +183,7 @@ function template_preprocess_toc_menu(&$variables) {
  *   - toc: A TOC (table of contents) object.
  *   - attributes: Attributes to be added to back to top link.
  */
-function template_preprocess_toc_responsive(&$variables) {
+function template_preprocess_toc_responsive(array &$variables): void {
   $variables['attributes'] = new Attribute($variables['attributes']);
 
   $variables['desktop'] = [
@@ -209,7 +215,7 @@ function template_preprocess_toc_responsive(&$variables) {
  *   - toc: A TOC (table of contents) object.
  *   - attributes: Attributes to be added to back to top link.
  */
-function template_preprocess_toc_default(&$variables) {
+function template_preprocess_toc_default(array &$variables): void {
   $variables['attributes'] = new Attribute($variables['attributes']);
 
   $variables['toc_default'] = [