diff --git a/animatecss.install b/animatecss.install
index 05b5bae..e28c91f 100644
--- a/animatecss.install
+++ b/animatecss.install
@@ -1,5 +1,8 @@
 <?php
 
+use Drupal\Component\Utility\DeprecationHelper;
+use Drupal\Core\Extension\Requirement\RequirementSeverity;
+
 /**
  * @file
  * Install, update, uninstall Requirements functions for the AnimateCSS module.
@@ -18,7 +21,7 @@ function animatecss_requirements($phase) {
   $requirements = [];
 
   // Check Animate.css library is existing.
-  /** @var Drupal\Core\Asset\LibraryDiscovery $library_discovery */
+  /** @var \Drupal\Core\Asset\LibraryDiscoveryInterface $library_discovery */
   $library_discovery = \Drupal::service('library.discovery');
   $library_animate = $library_discovery->getLibraryByName('animatecss', 'animate.css');
   $library_exists = FALSE;
@@ -50,7 +53,7 @@ function animatecss_requirements($phase) {
   $requirements['animatecss'] = [
     'title'       => t('Animate.css library'),
     'value'       => $library_exists ? t('Installed') : t('Not installed'),
-    'severity'    => $library_exists ? REQUIREMENT_OK : REQUIREMENT_ERROR,
+    'severity'    => $library_exists ? DeprecationHelper::backwardsCompatibleCall(\Drupal::VERSION, '11.2.0', fn() => RequirementSeverity::OK, fn() => REQUIREMENT_OK) : DeprecationHelper::backwardsCompatibleCall(\Drupal::VERSION, '11.2.0', fn() => RequirementSeverity::Error, fn() => REQUIREMENT_ERROR),
     'description' => $description,
   ];
 
diff --git a/animatecss.module b/animatecss.module
index 885408b..6287051 100644
--- a/animatecss.module
+++ b/animatecss.module
@@ -14,34 +14,17 @@
  *
  * Copyright (C) 2021-2023 Daniel Eden
  */
-
+use Drupal\Core\Hook\Attribute\LegacyHook;
+use Drupal\animatecss\Hook\AnimatecssHooks;
 use Drupal\Core\Installer\InstallerKernel;
 use Drupal\Core\Routing\RouteMatchInterface;
 
 /**
  * Implements hook_help().
  */
+#[LegacyHook]
 function animatecss_help($route_name, RouteMatchInterface $route_match) {
-  switch ($route_name) {
-    case 'help.page.animatecss':
-      $output  = '<h3 class="animate__animated animate__bounce">' . t('About') . '</h3>';
-      $output .= '<p class="animate__animated animate__fadeInUp animate__delay-1s">' . t('The AnimateCSS is a module that aims to integrate <a href=":animate_library">Animate.css</a> library with Drupal. Animate.css is a library of ready-to-use, cross-browser animations for use in your web projects. Great for emphasis, home pages, sliders, and attention-guiding hints. AnimateCSS module allows you to quickly attach Animate.css library in your page.', [':animate_library' => 'https://animate.style/']) . '</p>';
-      $output .= '<h3 class="animate__animated animate__zoomIn animate__delay-2s">' . t('Uses') . '</h3>';
-      $output .= '<dl>';
-      $output .= '<dt class="animate__animated animate__flipInX animate__delay-3s">' . t('Basic usage') . '</dt>';
-      $output .= '<dd class="animate__animated animate__slideInLeft animate__delay-4s"><p>' . t('Add the class animate__animated to an element, along with any of the animation names (do not forget the animate__ prefix!)') . '</p>';
-      $output .= '<pre><code>';
-      $output .= '&lt;h1 class="animate__animated animate__bounce"&gt;An animated element&lt;/h1&gt;' . "\n";
-      $output .= '</code></pre></dd>';
-      $output .= '<dt class="animate__animated animate__flipInX animate__delay-3s">' . t('Usage with Javascript') . '</dt>';
-      $output .= '<dd class="animate__animated animate__slideInRight animate__delay-4s"><p>' . t('You can do a whole bunch of other stuff with animate.css when you combine it with Javascript.') . '</p>';
-      $output .= '<pre>';
-      $output .= "const element = document.querySelector('.my-element');" . "\n";
-      $output .= "element.classList.add('animate__animated', 'animate__bounceOutLeft');";
-      $output .= '</pre></dd>';
-      $output .= '</dl>';
-      return $output;
-  }
+  return \Drupal::service(AnimatecssHooks::class)->help($route_name, $route_match);
 }
 
 /**
@@ -52,7 +35,7 @@ function animatecss_help($route_name, RouteMatchInterface $route_match) {
  */
 function animatecss_check_installed() {
   // Throw error if Animate.css library file not found.
-  /** @var Drupal\Core\Asset\LibraryDiscovery $library_discovery */
+  /** @var \Drupal\Core\Asset\LibraryDiscoveryInterface $library_discovery */
   $library_discovery = \Drupal::service('library.discovery');
   $library_exists = FALSE;
   $definition = $library_discovery->getLibraryByName('animatecss', 'animate.css');
@@ -68,24 +51,10 @@ function animatecss_check_installed() {
 /**
  * Implements hook_page_attachments().
  */
-function animatecss_page_attachments(array &$attachments) {
-  // Don't add the Library during installation.
-  if (InstallerKernel::installationAttempted()) {
-    return;
-  }
-
-  // Check first AnimateCSS UI module is not installed and library not exists.
-  $moduleHandler = \Drupal::service('module_handler');
-  if (!$moduleHandler->moduleExists('animatecss_ui')) {
-    // Check if Animate.css library not exist in local library then
-    // attach the latest version of Animate.css automatically from CDN.
-    if (animatecss_check_installed()) {
-      $attachments['#attached']['library'][] = 'animatecss/animate.css';
-    }
-    else {
-      $attachments['#attached']['library'][] = 'animatecss/animate.cdn';
-    }
-  }
+#[LegacyHook]
+function animatecss_page_attachments(array &$attachments)
+{
+    \Drupal::service(AnimatecssHooks::class)->pageAttachments($attachments);
 }
 
 /**
diff --git a/animatecss.services.yml b/animatecss.services.yml
new file mode 100644
index 0000000..5308423
--- /dev/null
+++ b/animatecss.services.yml
@@ -0,0 +1,5 @@
+
+services:
+  Drupal\animatecss\Hook\AnimatecssHooks:
+    class: Drupal\animatecss\Hook\AnimatecssHooks
+    autowire: true
diff --git a/animatecss_ui/animatecss_ui.install b/animatecss_ui/animatecss_ui.install
index fbae9c4..52fd2e3 100644
--- a/animatecss_ui/animatecss_ui.install
+++ b/animatecss_ui/animatecss_ui.install
@@ -4,7 +4,7 @@
  * @file
  * Install, update and uninstall functions for the AnimateCSS module.
  */
-
+use Drupal\Component\Utility\DeprecationHelper;
 use Drupal\Core\Url;
 
 /**
@@ -147,7 +147,7 @@ function animatecss_ui_update_8003() {
   $config = $config_factory->getEditable('animatecss.settings');
   // Add new silent configuration field.
   $config->set('silent', FALSE);
-  $config->save(TRUE);
+  DeprecationHelper::backwardsCompatibleCall(\Drupal::VERSION, '11.4.0', fn() => $config->save(), fn() => $config->save(TRUE));
 }
 
 /**
@@ -171,7 +171,7 @@ function animatecss_ui_update_8005() {
   if ($config->get('options.clean') === NULL) {
     // Set the default value for the 'clean' option.
     $config->set('options.clean', FALSE);
-    $config->save(TRUE);
+    DeprecationHelper::backwardsCompatibleCall(\Drupal::VERSION, '11.4.0', fn() => $config->save(), fn() => $config->save(TRUE));
   }
 }
 
@@ -187,20 +187,20 @@ function animatecss_ui_update_8006() {
   if ($config->get('options.event') === NULL) {
     // Set the default value for the 'event' option.
     $config->set('options.event', 'onload');
-    $config->save(TRUE);
+    DeprecationHelper::backwardsCompatibleCall(\Drupal::VERSION, '11.4.0', fn() => $config->save(), fn() => $config->save(TRUE));
   }
 
   // Check if the 'once' option already exists to avoid overwriting it.
   if ($config->get('options.once') === NULL) {
     // Set the default value for the 'once' option.
     $config->set('options.once', FALSE);
-    $config->save(TRUE);
+    DeprecationHelper::backwardsCompatibleCall(\Drupal::VERSION, '11.4.0', fn() => $config->save(), fn() => $config->save(TRUE));
   }
 
   // Check if the 'display' option already exists to avoid overwriting it.
   if ($config->get('options.display') === NULL) {
     // Set the default value for the 'display' option.
     $config->set('options.display', FALSE);
-    $config->save(TRUE);
+    DeprecationHelper::backwardsCompatibleCall(\Drupal::VERSION, '11.4.0', fn() => $config->save(), fn() => $config->save(TRUE));
   }
 }
diff --git a/animatecss_ui/animatecss_ui.module b/animatecss_ui/animatecss_ui.module
index def68e4..a5295b2 100644
--- a/animatecss_ui/animatecss_ui.module
+++ b/animatecss_ui/animatecss_ui.module
@@ -14,7 +14,8 @@
  *
  * Copyright (C) 2021-2023 Daniel Eden
  */
-
+use Drupal\Core\Hook\Attribute\LegacyHook;
+use Drupal\animatecss_ui\Hook\AnimatecssUiHooks;
 use Drupal\Core\Installer\InstallerKernel;
 use Drupal\Core\Link;
 use Drupal\Core\Routing\RouteMatchInterface;
@@ -25,165 +26,18 @@ use Symfony\Component\HttpFoundation\RequestStack;
 /**
  * Implements hook_help().
  */
+#[LegacyHook]
 function animatecss_ui_help($route_name, RouteMatchInterface $route_match) {
-  switch ($route_name) {
-    case 'help.page.animatecss_ui':
-      return '<p>' . t('<a href=":animate_url">Animate.css</a> is a library of ready-to-use, cross-browser animations for use in your web projects. Great for emphasis, home pages, sliders, and attention-guiding hints., see the <a href=":animate_github">Animate.css Github</a> for usage and Configure on <a href=":animate_config">AnimateCSS module settings</a> to put CSS selectors you want animated element.', [
-        ':animate_url'    => 'https://animate.style/',
-        ':animate_github' => 'https://github.com/animate-css/animate.css',
-        ':animate_config' => Link::createFromRoute(t('admin page'), 'animatecss.settings')->toString(),
-      ]) . '</p>';
-  }
+  return \Drupal::service(AnimatecssUiHooks::class)->help($route_name, $route_match);
 }
 
 /**
  * Implements hook_page_attachments().
  */
-function animatecss_ui_page_attachments(array &$attachments) {
-  // Don't add the library during installation.
-  if (InstallerKernel::installationAttempted()) {
-    return;
-  }
-
-  // Load the Animate.css configuration settings.
-  $config = \Drupal::config('animatecss.settings');
-
-  // Attach Animate.css to pages with chosen method.
-  $method = animatecss_check_installed() ? $config->get('method') : 'cdn';
-  $compat = $config->get('compat');
-
-  // Checking the path to load Animate.css for demo examples,
-  // It's just in Animatecss configuration.
-  $currentPath = Url::fromRoute('<current>')->toString();
-  $settingPath = Url::fromRoute('animatecss.admin')->toString() . '/*';
-
-  if (\Drupal::service('path.matcher')->matchPath($currentPath, $settingPath)) {
-    $options = $config->get('options');
-    $options['selector'] = '.animate__sample';
-
-    // Attach Animate.css for examples.
-    $attachments['#attached']['drupalSettings']['animatecss']['sample'] = $options;
-    $attachments['#attached']['drupalSettings']['animatecss']['compat'] = $compat;
-
-    if ($method == 'cdn') {
-      $attachments['#attached']['library'][] = 'animatecss_ui/animate-cdn-dev';
-    }
-    else {
-      $attachments['#attached']['library'][] = 'animatecss_ui/animate-dev';
-    }
-    return;
-  }
-
-  // Don't include Animate.css library if the user has opted out of loading it.
-  if (!$config->get('load')) {
-    return TRUE;
-  }
-
-  // Don't add the Animate.css on specified paths.
-  if (!_animatecss_ui_check_url()) {
-    return TRUE;
-  }
-
-  // Check for load development and production version.
-  $variant_options = ['source', 'minified'];
-  $variant = $variant_options[$config->get('minimized.options')];
-  if ($method == 'cdn') {
-    // The Animate.css library is attached with the CDN method.
-    // However, if the compatible version was enabled,
-    // the compatible version of the CDN should be added.
-    if ($compat) {
-      $attachments['#attached']['library'][] = 'animatecss_ui/animate-cdn-compat';
-    }
-    else {
-      // Check variant to load Animate.css from CDN.
-      switch ($variant) {
-        case 'minified':
-          $attachments['#attached']['library'][] = 'animatecss_ui/animate-cdn';
-          break;
-
-        case 'source':
-          $attachments['#attached']['library'][] = 'animatecss_ui/animate-cdn-dev';
-          break;
-      }
-    }
-  }
-  else {
-    // If the compatible version is enabled in the settings,
-    // it will include the compatible version of the Animate.css library.
-    // Because the compatible version is only available in compressed form.
-    if ($compat) {
-      $attachments['#attached']['library'][] = 'animatecss_ui/animate-compat';
-    }
-    else {
-      // Check variant to load Animate.css from local.
-      switch ($variant) {
-        case 'minified':
-          $attachments['#attached']['library'][] = 'animatecss_ui/animate-css';
-          break;
-
-        case 'source':
-          $attachments['#attached']['library'][] = 'animatecss_ui/animate-dev';
-          break;
-      }
-    }
-  }
-
-  // Get selectors from config.
-  $options = $config->get('options');
-  $animated = [];
-
-  // Load enabled animate selectors from database.
-  $results = \Drupal::service('animatecss.animate_manager')->loadAnimate()->fetchAll();
-  if (count($results)) {
-    $selectors = [];
-    foreach ($results as $animate) {
-      $animate_options = unserialize($animate->options, ['allowed_classes' => FALSE]);
-
-      // Support WOW JS Module.
-      if (isset($animate_options['wow']) && $animate_options['wow']['enable']) {
-        continue;
-      }
-
-      // Support AOS JS Module.
-      if (isset($animate_options['aos']) && $animate_options['aos']['enable']) {
-        continue;
-      }
-
-      $selectors[] = $animate->selector;
-      $animated[$animate->aid] = ['selector' => $animate->selector] + $animate_options;
-    }
-
-    // Merge global selectors from config with database selectors.
-    if (count(array_filter($config->get('options.selector'))) && count($selectors)) {
-      $options['selector'] = array_diff($options['selector'], $selectors);
-
-      // Attach config selectors after merge if there were any left.
-      if (count($options['selector'])) {
-        array_unshift($animated, $options);
-      }
-    }
-  }
-  else {
-    // If global selectors are set, get the selectors from the configuration.
-    if (count($config->get('options.selector'))) {
-      $animated = [$options];
-    }
-  }
-
-  // If there is animate selectors, then the init file
-  // with options will be added to the page.
-  if (count($animated)) {
-    // Export settings.
-    $attachments['#attached']['drupalSettings']['animatecss']['elements'] = $animated;
-
-    // If set compatible mode, pass to settings for change class in javascript.
-    if ($compat) {
-      $attachments['#attached']['drupalSettings']['animatecss']['compat'] = $compat;
-    }
-
-    // Init animate.
-    $attachments['#attached']['library'][] = 'animatecss_ui/animate-init';
-  }
+#[LegacyHook]
+function animatecss_ui_page_attachments(array &$attachments)
+{
+    return \Drupal::service(AnimatecssUiHooks::class)->pageAttachments($attachments);
 }
 
 /**
diff --git a/animatecss_ui/animatecss_ui.services.yml b/animatecss_ui/animatecss_ui.services.yml
index fc34db9..d89a4b3 100644
--- a/animatecss_ui/animatecss_ui.services.yml
+++ b/animatecss_ui/animatecss_ui.services.yml
@@ -4,3 +4,7 @@ services:
     arguments: [ '@database' ]
     tags:
       - { name: backend_overridable }
+
+  Drupal\animatecss_ui\Hook\AnimatecssUiHooks:
+    class: Drupal\animatecss_ui\Hook\AnimatecssUiHooks
+    autowire: true
diff --git a/animatecss_ui/src/Hook/AnimatecssUiHooks.php b/animatecss_ui/src/Hook/AnimatecssUiHooks.php
new file mode 100644
index 0000000..325720e
--- /dev/null
+++ b/animatecss_ui/src/Hook/AnimatecssUiHooks.php
@@ -0,0 +1,162 @@
+<?php
+
+namespace Drupal\animatecss_ui\Hook;
+
+use Drupal\Core\Installer\InstallerKernel;
+use Drupal\Core\Link;
+use Drupal\Core\Routing\RouteMatchInterface;
+use Drupal\Core\Url;
+use Symfony\Component\HttpFoundation\Request;
+use Symfony\Component\HttpFoundation\RequestStack;
+use Drupal\Core\Hook\Attribute\Hook;
+use Drupal\Core\StringTranslation\StringTranslationTrait;
+/**
+ * Hook implementations for animatecss_ui.
+ */
+class AnimatecssUiHooks
+{
+    use StringTranslationTrait;
+    /**
+     * Implements hook_help().
+     */
+    #[Hook('help')]
+    public function help($route_name, \Drupal\Core\Routing\RouteMatchInterface $route_match)
+    {
+        switch ($route_name) {
+            case 'help.page.animatecss_ui':
+                return '<p>' . $this->t('<a href=":animate_url">Animate.css</a> is a library of ready-to-use, cross-browser animations for use in your web projects. Great for emphasis, home pages, sliders, and attention-guiding hints., see the <a href=":animate_github">Animate.css Github</a> for usage and Configure on <a href=":animate_config">AnimateCSS module settings</a> to put CSS selectors you want animated element.', [
+                    ':animate_url' => 'https://animate.style/',
+                    ':animate_github' => 'https://github.com/animate-css/animate.css',
+                    ':animate_config' => \Drupal\Core\Link::createFromRoute($this->t('admin page'), 'animatecss.settings')->toString(),
+                ]) . '</p>';
+        }
+    }
+    /**
+     * Implements hook_page_attachments().
+     */
+    #[Hook('page_attachments')]
+    public static function pageAttachments(array &$attachments)
+    {
+        // Don't add the library during installation.
+        if (\Drupal\Core\Installer\InstallerKernel::installationAttempted()) {
+            return;
+        }
+        // Load the Animate.css configuration settings.
+        $config = \Drupal::config('animatecss.settings');
+        // Attach Animate.css to pages with chosen method.
+        $method = animatecss_check_installed() ? $config->get('method') : 'cdn';
+        $compat = $config->get('compat');
+        // Checking the path to load Animate.css for demo examples,
+        // It's just in Animatecss configuration.
+        $currentPath = \Drupal\Core\Url::fromRoute('<current>')->toString();
+        $settingPath = \Drupal\Core\Url::fromRoute('animatecss.admin')->toString() . '/*';
+        if (\Drupal::service('path.matcher')->matchPath($currentPath, $settingPath)) {
+            $options = $config->get('options');
+            $options['selector'] = '.animate__sample';
+            // Attach Animate.css for examples.
+            $attachments['#attached']['drupalSettings']['animatecss']['sample'] = $options;
+            $attachments['#attached']['drupalSettings']['animatecss']['compat'] = $compat;
+            if ($method == 'cdn') {
+                $attachments['#attached']['library'][] = 'animatecss_ui/animate-cdn-dev';
+            } else {
+                $attachments['#attached']['library'][] = 'animatecss_ui/animate-dev';
+            }
+            return;
+        }
+        // Don't include Animate.css library if the user has opted out of loading it.
+        if (!$config->get('load')) {
+            return TRUE;
+        }
+        // Don't add the Animate.css on specified paths.
+        if (!_animatecss_ui_check_url()) {
+            return TRUE;
+        }
+        // Check for load development and production version.
+        $variant_options = [
+            'source',
+            'minified',
+        ];
+        $variant = $variant_options[$config->get('minimized.options')];
+        if ($method == 'cdn') {
+            // The Animate.css library is attached with the CDN method.
+            // However, if the compatible version was enabled,
+            // the compatible version of the CDN should be added.
+            if ($compat) {
+                $attachments['#attached']['library'][] = 'animatecss_ui/animate-cdn-compat';
+            } else {
+                // Check variant to load Animate.css from CDN.
+                switch ($variant) {
+                    case 'minified':
+                        $attachments['#attached']['library'][] = 'animatecss_ui/animate-cdn';
+                        break;
+                    case 'source':
+                        $attachments['#attached']['library'][] = 'animatecss_ui/animate-cdn-dev';
+                        break;
+                }
+            }
+        } else if ($compat) {
+            $attachments['#attached']['library'][] = 'animatecss_ui/animate-compat';
+        } else {
+            // Check variant to load Animate.css from local.
+            switch ($variant) {
+                case 'minified':
+                    $attachments['#attached']['library'][] = 'animatecss_ui/animate-css';
+                    break;
+                case 'source':
+                    $attachments['#attached']['library'][] = 'animatecss_ui/animate-dev';
+                    break;
+            }
+        }
+        // Get selectors from config.
+        $options = $config->get('options');
+        $animated = [
+        ];
+        // Load enabled animate selectors from database.
+        $results = \Drupal::service('animatecss.animate_manager')->loadAnimate()->fetchAll();
+        if (count($results)) {
+            $selectors = [
+            ];
+            foreach ($results as $animate) {
+                $animate_options = unserialize($animate->options, [
+                    'allowed_classes' => FALSE,
+                ]);
+                // Support WOW JS Module.
+                if (isset($animate_options['wow']) && $animate_options['wow']['enable']) {
+                    continue;
+                }
+                // Support AOS JS Module.
+                if (isset($animate_options['aos']) && $animate_options['aos']['enable']) {
+                    continue;
+                }
+                $selectors[] = $animate->selector;
+                $animated[$animate->aid] = [
+                    'selector' => $animate->selector,
+                ] + $animate_options;
+            }
+            // Merge global selectors from config with database selectors.
+            if (count(array_filter($config->get('options.selector'))) && count($selectors)) {
+                $options['selector'] = array_diff($options['selector'], $selectors);
+                // Attach config selectors after merge if there were any left.
+                if (count($options['selector'])) {
+                    array_unshift($animated, $options);
+                }
+            }
+        } else if (count($config->get('options.selector'))) {
+            $animated = [
+                $options,
+            ];
+        }
+        // If there is animate selectors, then the init file
+        // with options will be added to the page.
+        if (count($animated)) {
+            // Export settings.
+            $attachments['#attached']['drupalSettings']['animatecss']['elements'] = $animated;
+            // If set compatible mode, pass to settings for change class in javascript.
+            if ($compat) {
+                $attachments['#attached']['drupalSettings']['animatecss']['compat'] = $compat;
+            }
+            // Init animate.
+            $attachments['#attached']['library'][] = 'animatecss_ui/animate-init';
+        }
+    }
+}
diff --git a/src/Hook/AnimatecssHooks.php b/src/Hook/AnimatecssHooks.php
new file mode 100644
index 0000000..e4fa26e
--- /dev/null
+++ b/src/Hook/AnimatecssHooks.php
@@ -0,0 +1,66 @@
+<?php
+
+namespace Drupal\animatecss\Hook;
+
+use Drupal\Core\Installer\InstallerKernel;
+use Drupal\Core\Routing\RouteMatchInterface;
+use Drupal\Core\Hook\Attribute\Hook;
+use Drupal\Core\StringTranslation\StringTranslationTrait;
+/**
+ * Hook implementations for animatecss.
+ */
+class AnimatecssHooks
+{
+    use StringTranslationTrait;
+    /**
+     * Implements hook_help().
+     */
+    #[Hook('help')]
+    public function help($route_name, \Drupal\Core\Routing\RouteMatchInterface $route_match)
+    {
+        switch ($route_name) {
+            case 'help.page.animatecss':
+                $output = '<h3 class="animate__animated animate__bounce">' . $this->t('About') . '</h3>';
+                $output .= '<p class="animate__animated animate__fadeInUp animate__delay-1s">' . $this->t('The AnimateCSS is a module that aims to integrate <a href=":animate_library">Animate.css</a> library with Drupal. Animate.css is a library of ready-to-use, cross-browser animations for use in your web projects. Great for emphasis, home pages, sliders, and attention-guiding hints. AnimateCSS module allows you to quickly attach Animate.css library in your page.', [
+                    ':animate_library' => 'https://animate.style/',
+                ]) . '</p>';
+                $output .= '<h3 class="animate__animated animate__zoomIn animate__delay-2s">' . $this->t('Uses') . '</h3>';
+                $output .= '<dl>';
+                $output .= '<dt class="animate__animated animate__flipInX animate__delay-3s">' . $this->t('Basic usage') . '</dt>';
+                $output .= '<dd class="animate__animated animate__slideInLeft animate__delay-4s"><p>' . $this->t('Add the class animate__animated to an element, along with any of the animation names (do not forget the animate__ prefix!)') . '</p>';
+                $output .= '<pre><code>';
+                $output .= '&lt;h1 class="animate__animated animate__bounce"&gt;An animated element&lt;/h1&gt;' . "\n";
+                $output .= '</code></pre></dd>';
+                $output .= '<dt class="animate__animated animate__flipInX animate__delay-3s">' . $this->t('Usage with Javascript') . '</dt>';
+                $output .= '<dd class="animate__animated animate__slideInRight animate__delay-4s"><p>' . $this->t('You can do a whole bunch of other stuff with animate.css when you combine it with Javascript.') . '</p>';
+                $output .= '<pre>';
+                $output .= "const element = document.querySelector('.my-element');" . "\n";
+                $output .= "element.classList.add('animate__animated', 'animate__bounceOutLeft');";
+                $output .= '</pre></dd>';
+                $output .= '</dl>';
+                return $output;
+        }
+    }
+    /**
+     * Implements hook_page_attachments().
+     */
+    #[Hook('page_attachments')]
+    public static function pageAttachments(array &$attachments)
+    {
+        // Don't add the Library during installation.
+        if (\Drupal\Core\Installer\InstallerKernel::installationAttempted()) {
+            return;
+        }
+        // Check first AnimateCSS UI module is not installed and library not exists.
+        $moduleHandler = \Drupal::service('module_handler');
+        if (!$moduleHandler->moduleExists('animatecss_ui')) {
+            // Check if Animate.css library not exist in local library then
+            // attach the latest version of Animate.css automatically from CDN.
+            if (animatecss_check_installed()) {
+                $attachments['#attached']['library'][] = 'animatecss/animate.css';
+            } else {
+                $attachments['#attached']['library'][] = 'animatecss/animate.cdn';
+            }
+        }
+    }
+}
