diff --git a/modules/ui_patterns_layouts/tests/src/Functional/LayoutBuilderRenderTest.php b/modules/ui_patterns_layouts/tests/src/Functional/LayoutBuilderRenderTest.php
index 8b23c5b2631f808a8bc2f25489f2bc04d34d1392..50ece86a78d026a11504ceca76470d7c7d9bd5e0 100644
--- a/modules/ui_patterns_layouts/tests/src/Functional/LayoutBuilderRenderTest.php
+++ b/modules/ui_patterns_layouts/tests/src/Functional/LayoutBuilderRenderTest.php
@@ -58,24 +58,30 @@ class LayoutBuilderRenderTest extends UiPatternsFunctionalTestBase {
 
     $test_data = $this->loadTestDataFixture();
     $tests = [
+      $test_data->getTestSet('attributes_empty'),
+      $test_data->getTestSet('attributes_default'),
       $test_data->getTestSet('textfield_default'),
       $test_data->getTestSet('token_default'),
       $test_data->getTestSet('context_exists_default'),
     ];
 
     foreach ($tests as $test_set) {
-      $node = $this->createTestContentNode('page', $test_set['entity'] ?? []);
       $ui_patterns_config = $this->buildUiPatternsConfig($test_set);
+      $config_import['third_party_settings']['layout_builder']['sections'][0]['layout_id'] = 'ui_patterns:' . str_replace('-', '_', $test_set['component']['component_id']);
       $this->importConfigFixture(
         'core.entity_view_display.node.page.full',
         $config_import
       );
-
+      $node = $this->createTestContentNode('page', $test_set['entity'] ?? []);
       $this->drupalGet('admin/structure/types/manage/page/display/full/layout');
-      $assert_session->elementExists('css', '.ui-patterns-test-component');
+      $assert_session->statusCodeEquals(200);
+      $component_id = str_replace('_', '-', explode(':', $test_set['component']['component_id'])[1]);
+      $assert_session->elementExists('css', '.ui-patterns-' . $component_id);
       $this->drupalGet('node/' . $node->id());
-      $assert_session->elementExists('css', '.ui-patterns-test-component');
+      $assert_session->statusCodeEquals(200);
+      $assert_session->elementExists('css', '.ui-patterns-' . $component_id);
       $this->validateRenderedComponent($test_set);
+      $node->delete();
     }
   }
 
diff --git a/src/Element/ComponentElementAlter.php b/src/Element/ComponentElementAlter.php
index 70f43f295ecfa9c3528d841159c5c709a0d0969a..5e9b62e75e30a5df9fa3905025fa635ba5988697 100644
--- a/src/Element/ComponentElementAlter.php
+++ b/src/Element/ComponentElementAlter.php
@@ -8,6 +8,7 @@ use Drupal\Core\Plugin\Component;
 use Drupal\Core\Security\TrustedCallbackInterface;
 use Drupal\Core\Theme\ComponentPluginManager;
 use Drupal\ui_patterns\Plugin\UiPatterns\PropType\SlotPropType;
+use Drupal\ui_patterns\PropTypeAdapterPluginManager;
 
 /**
  * Our additions to the SDC render element.
@@ -17,7 +18,7 @@ class ComponentElementAlter implements TrustedCallbackInterface {
   /**
    * Constructs a ComponentElementAlter.
    */
-  public function __construct(protected ComponentPluginManager $componentPluginManager) {
+  public function __construct(protected ComponentPluginManager $componentPluginManager, protected PropTypeAdapterPluginManager $adaptersManager) {
   }
 
   /**
@@ -68,8 +69,19 @@ class ComponentElementAlter implements TrustedCallbackInterface {
       if (!isset($props[$prop_id])) {
         continue;
       }
-      $prop_type = $props[$prop_id]['ui_patterns']['type_definition'];
-      $element["#props"][$prop_id] = $prop_type->normalize($prop);
+      $definition = $props[$prop_id];
+      $prop_type = $definition['ui_patterns']['type_definition'];
+      // Normalizing attributes to an array is not working
+      // if the prop type is defined by type=Drupal\Core\Template\Attribute
+      // This should actually be done by the normalize function.
+      $data = $prop_type->normalize($prop);
+      if (isset($definition['ui_patterns']['prop_type_adapter'])) {
+        $prop_type_adapter_id = $definition['ui_patterns']['prop_type_adapter'];
+        /** @var \Drupal\ui_patterns\PropTypeAdapterInterface $prop_type_adapter */
+        $prop_type_adapter = $this->adaptersManager->createInstance($prop_type_adapter_id);
+        $data = $prop_type_adapter->transform($data);
+      }
+      $element["#props"][$prop_id] = $data;
     }
     return $element;
   }
diff --git a/src/Element/ComponentElementBuilder.php b/src/Element/ComponentElementBuilder.php
index ec87c5904b9037d672265e737234e23c7907d238..544168bd0fd8ea418785bc105494e55666a897ba 100644
--- a/src/Element/ComponentElementBuilder.php
+++ b/src/Element/ComponentElementBuilder.php
@@ -32,7 +32,6 @@ class ComponentElementBuilder implements TrustedCallbackInterface {
   public function __construct(
     protected SourcePluginManager $sourcesManager,
     protected PropTypePluginManager $propTypeManager,
-    protected PropTypeAdapterPluginManager $adaptersManager,
     protected ComponentPluginManager $componentPluginManager,
   ) {
   }
@@ -86,12 +85,7 @@ class ComponentElementBuilder implements TrustedCallbackInterface {
     $prop_type = $definition['ui_patterns']['type_definition'];
     $build = $source->alterComponent($build);
     $data = $source->getValue($prop_type);
-    if (isset($definition['ui_patterns']['prop_type_adapter'])) {
-      $prop_type_adapter_id = $definition['ui_patterns']['prop_type_adapter'];
-      /** @var \Drupal\ui_patterns\PropTypeAdapterInterface $prop_type_adapter */
-      $prop_type_adapter = $this->adaptersManager->createInstance($prop_type_adapter_id);
-      $data = $prop_type_adapter->transform($data);
-    }
+
     if (empty($data) && $prop_type->getPluginId() !== 'attributes') {
       // For JSON Schema validator, empty value is not the same as missing
       // value, and we want to prevent some of the prop types rules to be
diff --git a/tests/fixtures/TestDataSet.yml b/tests/fixtures/TestDataSet.yml
index 154710146cee1aae1d56b1f48a9831c3dd8e771a..246d9d8bd4e8f39ed1134dffaef56e004d01f945 100644
--- a/tests/fixtures/TestDataSet.yml
+++ b/tests/fixtures/TestDataSet.yml
@@ -1,4 +1,52 @@
 ---
+attributes_empty:
+  component:
+    component_id: ui_patterns_test:test-component
+    props:
+      attributes_implicit:
+        source_id: attributes
+        source:
+          value: ''
+      attributes_ui_patterns:
+        source_id: attributes
+        source:
+          value: ''
+      attributes_class:
+        source_id: attributes
+        source:
+          value: ''
+  output:
+    props:
+      attributes_implicit:
+        value: ''
+  entity: {}
+
+attributes_default:
+  component:
+    component_id: ui_patterns_test:test-component
+    props:
+      attributes_implicit:
+        source_id: attributes
+        source:
+          value: 'ui_patterns="foo"'
+      attributes_ui_patterns:
+        source_id: attributes
+        source:
+          value: 'ui_patterns="foo"'
+      attributes_class:
+        source_id: attributes
+        source:
+          value: 'ui_patterns="foo"'
+  output:
+    props:
+      attributes_implicit:
+        value: 'ui_patterns="foo"'
+      attributes_ui_patterns:
+        value: 'ui_patterns="foo"'
+      attributes_class:
+        value: 'ui_patterns="foo"'
+  entity: {}
+
 field_property_default:
   component:
     component_id: ui_patterns_test:test-component
diff --git a/tests/modules/ui_patterns_test/components/test-component/test-component.component.yml b/tests/modules/ui_patterns_test/components/test-component/test-component.component.yml
index 97cbbc3fdd519feab3409853a26cce89727e791c..5dfd6f874847f8af825a616f892d9379204f8922 100644
--- a/tests/modules/ui_patterns_test/components/test-component/test-component.component.yml
+++ b/tests/modules/ui_patterns_test/components/test-component/test-component.component.yml
@@ -19,6 +19,27 @@ props:
       enum:
         - "2"
         - "3"
+    attributes_implicit:
+      title: "Attributes (implicit typing)"
+      type: object
+      patternProperties:
+        ".+":
+          anyOf:
+            - type:
+                - string
+                - number
+            - type: array
+              items:
+                anyOf:
+                  - type: number
+                  - type: string
+    attributes_ui_patterns:
+      title: "Attributes (explicit typing)"
+      "$ref": "ui-patterns://attributes"
+    attributes_class:
+      title: "Attributes when type is a PHP namespace"
+      type: 'Drupal\Core\Template\Attribute'
+
 slots:
   slot:
     title: "Slot"
diff --git a/tests/modules/ui_patterns_test/components/test-component/test-component.twig b/tests/modules/ui_patterns_test/components/test-component/test-component.twig
index 8c0d0364144d429ab2f387a014f26b82c45805ec..3e74de2a6dfa8a4fd71e9b8e7094cf93120ac062 100644
--- a/tests/modules/ui_patterns_test/components/test-component/test-component.twig
+++ b/tests/modules/ui_patterns_test/components/test-component/test-component.twig
@@ -8,6 +8,15 @@
   <div class="ui-patterns-props-enum_string">
     {{ enum_string }}
   </div>
+  <div class="ui-patterns-props-attributes_implicit">
+    {{ attributes_implicit }}
+  </div>
+  <div class="ui-patterns-props-attributes_ui_patterns">
+    {{ attributes_ui_patterns }}
+  </div>
+  <div class="ui-patterns-props-attributes_class">
+    {{ attributes_class }}
+  </div>
   <div class="ui-patterns-slots-slot">
     {{ slot }}
   </div>
diff --git a/tests/src/Functional/UiPatternsFunctionalTestBase.php b/tests/src/Functional/UiPatternsFunctionalTestBase.php
index af4af9e2b7173cb35d422317e4c6f9d805f59ce0..9c56261a806d7dfd84e9b2733b1030e4d3eb556d 100644
--- a/tests/src/Functional/UiPatternsFunctionalTestBase.php
+++ b/tests/src/Functional/UiPatternsFunctionalTestBase.php
@@ -8,6 +8,7 @@ use Drupal\Component\Serialization\Yaml;
 use Drupal\Tests\BrowserTestBase;
 use Drupal\Tests\ui_patterns\Traits\TestContentCreationTrait;
 use Drupal\Tests\ui_patterns\Traits\TestDataTrait;
+use Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException;
 
 /**
  * Base function testing.
@@ -57,6 +58,9 @@ abstract class UiPatternsFunctionalTestBase extends BrowserTestBase {
     if ($this->user) {
       $this->drupalLogin($this->user);
     }
+    else {
+      throw new AccessDeniedHttpException($this->getTextContent());
+    }
   }
 
   /**
@@ -95,6 +99,7 @@ abstract class UiPatternsFunctionalTestBase extends BrowserTestBase {
    *   The config fixture.
    */
   public function importConfigFixture(string $config_id, array $config) {
+    $this->configInitialize = FALSE;
     $this->initializeConfig();
     \Drupal::service('config.storage.sync')->write($config_id, $config);
     $config_importer = $this->configImporter();
@@ -128,6 +133,7 @@ abstract class UiPatternsFunctionalTestBase extends BrowserTestBase {
   protected function validateRenderedComponent($test_set) {
     $output = $test_set['output'] ?? [];
     $page = $this->getSession()->getPage();
+
     foreach ($output as $prop_or_slot => $prop_or_slot_item) {
       foreach ($prop_or_slot_item as $prop_name => $output) {
         $expected_outputs_here = ($prop_or_slot === "props") ? [$output] : $output;
diff --git a/ui_patterns.services.yml b/ui_patterns.services.yml
index 16062dcd2435304b78887093ccc9d99a3cfac923..abffbf352b4d9e402649948f7be24826407bb364 100644
--- a/ui_patterns.services.yml
+++ b/ui_patterns.services.yml
@@ -45,12 +45,12 @@ services:
     arguments:
       - "@plugin.manager.ui_patterns_source"
       - "@plugin.manager.ui_patterns_prop_type"
-      - "@plugin.manager.ui_patterns_prop_type_adapter"
       - "@plugin.manager.sdc"
   ui_patterns.component_element_alter:
     class: Drupal\ui_patterns\Element\ComponentElementAlter
     arguments:
       - "@plugin.manager.sdc"
+      - "@plugin.manager.ui_patterns_prop_type_adapter"
 
   # JSON schema management.
   ui_patterns.schema_stream_wrapper: