diff --git a/animation_animall.py b/animation_animall.py
index 309141a95101fb30d31f19aa8ab3d0b5a7ed21b2..fe99019c886069f62c4eeb10cc2bf993ffa66e9f 100644
--- a/animation_animall.py
+++ b/animation_animall.py
@@ -3,8 +3,8 @@
 bl_info = {
     "name": "AnimAll",
     "author": "Daniel Salazar <zanqdo@gmail.com>",
-    "version": (0, 8, 3),
-    "blender": (2, 80, 0),
+    "version": (0, 9, 0),
+    "blender": (3, 3, 0),
     "location": "3D View > Toolbox > Animation tab > AnimAll",
     "description": "Allows animation of mesh, lattice, curve and surface data",
     "warning": "",
@@ -72,6 +72,11 @@ class AnimallProperties(bpy.types.PropertyGroup):
         description="Insert keyframes on active Vertex group values",
         default=False
     )
+    key_attribute: BoolProperty(
+        name="Active Attribute",
+        description="Insert keyframes on active attribute values",
+        default=False
+    )
     key_points: BoolProperty(
         name="Points",
         description="Insert keyframes on point locations",
@@ -122,6 +127,12 @@ def delete_key(data, key):
         pass
 
 
+def is_selected_vert_loop(data, loop_i):
+    """Get selection status of vertex corresponding to a loop"""
+    vertex_index = data.loops[loop_i].vertex_index
+    return data.vertices[vertex_index].select
+
+
 # GUI (Panel)
 
 class VIEW3D_PT_animall(Panel):
@@ -163,6 +174,8 @@ class VIEW3D_PT_animall(Panel):
             row = col.row()
             row.prop(animall_properties, "key_vcols")
             row.prop(animall_properties, "key_vgroups")
+            row = col.row()
+            row.prop(animall_properties, "key_attribute")
 
         elif obj.type == 'CURVE':
             row.prop(animall_properties, "key_points")
@@ -328,8 +341,38 @@ class ANIM_OT_insert_keyframe_animall(Operator):
                 if animall_properties.key_vcols:
                     for v_col_layer in data.vertex_colors:
                         if v_col_layer.active:  # only insert in active VCol layer
-                            for v_i, data in enumerate(v_col_layer.data):
-                                insert_key(data, 'color', group="Loop %s" % v_i)
+                            for v_i, vcol_data in enumerate(v_col_layer.data):
+                                insert_key(vcol_data, 'color', group="Loop %s" % v_i)
+
+                if animall_properties.key_attribute:
+                    if data.attributes.active is not None:
+                        attribute = data.attributes.active
+                        if attribute.data_type != 'STRING':
+                            # Cannot animate string attributes?
+                            if attribute.data_type in {'FLOAT', 'INT', 'BOOLEAN', 'INT8'}:
+                                attribute_key = "value"
+                            elif attribute.data_type in {'FLOAT_COLOR', 'BYTE_COLOR'}:
+                                attribute_key = "color"
+                            elif attribute.data_type in {'FLOAT_VECTOR', 'FLOAT2'}:
+                                attribute_key = "vector"
+
+                            if attribute.domain == 'POINT':
+                                group = "Vertex %s"
+                            elif attribute.domain == 'EDGE':
+                                group = "Edge %s"
+                            elif attribute.domain == 'FACE':
+                                group = "Face %s"
+                            elif attribute.domain == 'CORNER':
+                                group = "Loop %s"
+
+                            for e_i, _attribute_data in enumerate(attribute.data):
+                                if (not animall_properties.key_selected
+                                        or attribute.domain == 'POINT' and data.vertices[e_i].select
+                                        or attribute.domain == 'EDGE' and data.edges[e_i].select
+                                        or attribute.domain == 'FACE' and data.polygons[e_i].select
+                                        or attribute.domain == 'CORNER' and is_selected_vert_loop(data, e_i)):
+                                    insert_key(data, f'attributes["{attribute.name}"].data[{e_i}].{attribute_key}',
+                                            group=group % e_i)
 
             elif obj.type in {'CURVE', 'SURFACE'}:
                 # Shape key keys have to be inserted in object mode for curves...
@@ -429,8 +472,47 @@ class ANIM_OT_delete_keyframe_animall(Operator):
                 if animall_properties.key_vcols:
                     for v_col_layer in data.vertex_colors:
                         if v_col_layer.active:  # only delete in active VCol layer
-                            for data in v_col_layer.data:
-                                delete_key(data, 'color')
+                            for vcol_data in v_col_layer.data:
+                                delete_key(vcol_data, 'color')
+
+                if animall_properties.key_attribute:
+                    if data.attributes.active is not None:
+                        attribute = data.attributes.active
+                        if attribute.data_type != 'STRING':
+                            # Cannot animate string attributes?
+                            if attribute.data_type in {'FLOAT', 'INT', 'BOOLEAN', 'INT8'}:
+                                attribute_key = "value"
+                            elif attribute.data_type in {'FLOAT_COLOR', 'BYTE_COLOR'}:
+                                attribute_key = "color"
+                            elif attribute.data_type in {'FLOAT_VECTOR', 'FLOAT2'}:
+                                attribute_key = "vector"
+
+                            for e_i, _attribute_data in enumerate(attribute.data):
+                                if (not animall_properties.key_selected
+                                        or attribute.domain == 'POINT' and data.vertices[e_i].select
+                                        or attribute.domain == 'EDGE' and data.edges[e_i].select
+                                        or attribute.domain == 'FACE' and data.polygons[e_i].select
+                                        or attribute.domain == 'CORNER' and is_selected_vert_loop(data, e_i)):
+                                    delete_key(data, f'attributes["{attribute.name}"].data[{e_i}].{attribute_key}')
+
+                if animall_properties.key_attribute:
+                    if data.attributes.active is not None:
+                        attribute = data.attributes.active
+                        if attribute.data_type != 'STRING':
+                            # Cannot animate string attributes?
+                            if attribute.data_type in {'FLOAT', 'INT', 'BOOLEAN', 'INT8'}:
+                                attribute_key = "value"
+                            elif attribute.data_type in {'FLOAT_COLOR', 'BYTE_COLOR'}:
+                                attribute_key = "color"
+                            elif attribute.data_type in {'FLOAT_VECTOR', 'FLOAT2'}:
+                                attribute_key = "vector"
+
+                            for e_i, _attribute_data in enumerate(attribute.data):
+                                if (not animall_properties.key_selected
+                                        or attribute.domain == 'POINT' and data.vertices[e_i].select
+                                        or attribute.domain == 'EDGE' and data.edges[e_i].select
+                                        or attribute.domain == 'FACE' and data.polygons[e_i].select):
+                                    delete_key(data, f'attributes["{attribute.name}"].data[{e_i}].{attribute_key}')
 
             elif obj.type == 'LATTICE':
                 if animall_properties.key_shape: