diff --git a/config/install/htmlpurifier.settings.yml b/config/install/htmlpurifier.settings.yml
new file mode 100644
index 0000000000000000000000000000000000000000..c3fdba8c94a894b845467952e49bdaa963223d74
--- /dev/null
+++ b/config/install/htmlpurifier.settings.yml
@@ -0,0 +1 @@
+cache.serializer_path: ''
diff --git a/config/schema/htmlpurifier.schema.yml b/config/schema/htmlpurifier.schema.yml
index 8b5b4dd7169982160b901bd3558bee1e0c211460..a2c7a57a9e0132e99bc64795911f11d7377560a2 100644
--- a/config/schema/htmlpurifier.schema.yml
+++ b/config/schema/htmlpurifier.schema.yml
@@ -5,3 +5,10 @@ filter_settings.htmlpurifier:
     htmlpurifier_configuration:
       type: string
       label: 'Configuration of HTMLPurifier'
+htmlpurifier.settings:
+  type: config_object
+  label: 'HTML Purifier settings'
+  mapping:
+    cache.serializer_path:
+      type: string
+      label: 'Absolute path with no trailing slash to store serialized definitions.'
diff --git a/htmlpurifier.info.yml b/htmlpurifier.info.yml
index 7b5391b0bb749d4119ec4fbbc9d1bd38e0c37489..7eff3e24ab0522b6ada767d0bfe68a818e991aed 100644
--- a/htmlpurifier.info.yml
+++ b/htmlpurifier.info.yml
@@ -2,6 +2,4 @@ name: 'HTML Purifier'
 type: module
 description: 'Filter that removes malicious HTML and ensures standards compliant output.'
 package: Filter
-core: 8.x
-core_version_requirement: ^8 || ^9 || ^10
-php: 7.1
+core_version_requirement: ^10.2
diff --git a/src/Plugin/Filter/HtmlPurifierFilter.php b/src/Plugin/Filter/HtmlPurifierFilter.php
index deb0247d55bde7af7cb15cd2c3eea749c842b758..15768eba69572baafc6dbc60f27ff5f49b9f731e 100644
--- a/src/Plugin/Filter/HtmlPurifierFilter.php
+++ b/src/Plugin/Filter/HtmlPurifierFilter.php
@@ -3,9 +3,13 @@
 namespace Drupal\htmlpurifier\Plugin\Filter;
 
 use Drupal\Component\Serialization\Yaml;
+use Drupal\Core\Config\ConfigFactoryInterface;
+use Drupal\Core\File\FileSystemInterface;
 use Drupal\Core\Form\FormStateInterface;
+use Drupal\Core\Plugin\ContainerFactoryPluginInterface;
 use Drupal\filter\FilterProcessResult;
 use Drupal\filter\Plugin\FilterBase;
+use Symfony\Component\DependencyInjection\ContainerInterface;
 
 /**
  * The implementation of HTML Purifier filter.
@@ -17,7 +21,7 @@ use Drupal\filter\Plugin\FilterBase;
  *   type = Drupal\filter\Plugin\FilterInterface::TYPE_TRANSFORM_IRREVERSIBLE
  * )
  */
-class HtmlPurifierFilter extends FilterBase {
+class HtmlPurifierFilter extends FilterBase implements ContainerFactoryPluginInterface {
 
   /**
    * Array of error messages from HTMLPurifier configuration assignments.
@@ -26,16 +30,48 @@ class HtmlPurifierFilter extends FilterBase {
    */
   protected $configErrors = [];
 
+  public function __construct(
+    array $configuration,
+    $plugin_id,
+    $plugin_definition,
+    protected FileSystemInterface $fileSystem,
+    protected ConfigFactoryInterface $configFactory,
+  ) {
+    parent::__construct($configuration, $plugin_id, $plugin_definition);
+  }
+
   /**
    * {@inheritdoc}
    */
-  public function process($text, $langcode) {
+  public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition): static {
+    return new static(
+      $configuration,
+      $plugin_id,
+      $plugin_definition,
+      $container->get('file_system'),
+      $container->get('config.factory'),
+    );
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function process($text, $langcode): FilterProcessResult {
     if (!empty($this->settings['htmlpurifier_configuration'])) {
       $purifier_config = $this->applyPurifierConfig($this->settings['htmlpurifier_configuration']);
     }
     else {
       $purifier_config = \HTMLPurifier_Config::createDefault();
     }
+
+    // Set Serializer path to the temporary directory, so it can be written.
+    $cache_serializer_path = $this->configFactory->get('htmlpurifier.settings')->get('cache.serializer_path');
+    if (empty($cache_serializer_path)) {
+      $cache_serializer_path = $this->fileSystem->getTempDirectory() . '/htmlpurifier';
+    }
+    $this->fileSystem->prepareDirectory($cache_serializer_path, FileSystemInterface::MODIFY_PERMISSIONS | FileSystemInterface::CREATE_DIRECTORY);
+    $purifier_config->set('Cache.SerializerPath', $cache_serializer_path);
+
     $purifier = new \HTMLPurifier($purifier_config);
     $purified_text = $purifier->purify($text);
     return new FilterProcessResult($purified_text);
@@ -50,13 +86,18 @@ class HtmlPurifierFilter extends FilterBase {
 
     $settings = Yaml::decode($configuration);
     foreach ($settings as $namespace => $directives) {
-      if (is_array($directives)) {
-        foreach ($directives as $key => $value) {
-          $purifier_config->set("$namespace.$key", $value);
+
+      // Keep Cache managing out of the text formats scope.
+      if ($namespace !== 'Cache') {
+
+        if (is_array($directives)) {
+          foreach ($directives as $key => $value) {
+            $purifier_config->set("$namespace.$key", $value);
+          }
+        }
+        else {
+          $this->configErrors[] = 'Invalid value for namespace $namespace, must be an array of directives.';
         }
-      }
-      else {
-        $this->configErrors[] = 'Invalid value for namespace $namespace, must be an array of directives.';
       }
     }
 
@@ -66,11 +107,16 @@ class HtmlPurifierFilter extends FilterBase {
   /**
    * {@inheritdoc}
    */
-  public function settingsForm(array $form, FormStateInterface $form_state) {
+  public function settingsForm(array $form, FormStateInterface $form_state): array {
     if (empty($this->settings['htmlpurifier_configuration'])) {
       /** @var \HTMLPurifier_Config $purifier_config */
       $purifier_config = \HTMLPurifier_Config::createDefault();
-      $default_value = Yaml::encode($purifier_config->getAll());
+      $config_array = $purifier_config->getAll();
+
+      // Keep Cache managing out of the text formats scope.
+      unset($config_array['Cache']);
+
+      $default_value = Yaml::encode($config_array);
     }
     else {
       $default_value = $this->settings['htmlpurifier_configuration'];
@@ -121,7 +167,7 @@ class HtmlPurifierFilter extends FilterBase {
   /**
    * Custom error handler to manage invalid purifier configuration assignments.
    */
-  public function configErrorHandler(int $errno, string $errstr) {
+  public function configErrorHandler(int $errno, string $errstr): void {
     // Do not set a validation error if the error is about a deprecated use.
     if ($errno < E_DEPRECATED) {
       // \HTMLPurifier_Config::triggerError() adds ' invoked on line ...' to the