Agent Skill
2/7/2026

fullstory-element-properties

Core concepts for Fullstory's Element Properties API. Platform-agnostic guide covering API Defined Elements, property inheritance, schema types, and best practices. See SKILL-WEB.md and SKILL-MOBILE.md for implementation examples.

F
fullstorydev
6GitHub Stars
1Views
npx skills add fullstorydev/fs-skills

SKILL.md

Namefullstory-element-properties
DescriptionCore concepts for Fullstory's Element Properties API. Platform-agnostic guide covering API Defined Elements, property inheritance, schema types, and best practices. See SKILL-WEB.md and SKILL-MOBILE.md for implementation examples.

name: fullstory-element-properties version: v3 description: Core concepts for Fullstory's Element Properties API. Platform-agnostic guide covering API Defined Elements, property inheritance, schema types, and best practices. See SKILL-WEB.md and SKILL-MOBILE.md for implementation examples. platforms:

  • web
  • ios
  • android
  • flutter
  • react-native related_skills:
  • fullstory-page-properties
  • fullstory-user-properties
  • fullstory-analytics-events
  • universal-data-scoping-and-decoration
  • fullstory-privacy-controls
  • fullstory-ecommerce
  • fullstory-saas implementation_files:
  • SKILL-WEB.md
  • SKILL-IOS.md
  • SKILL-ANDROID.md
  • SKILL-REACT-NATIVE.md
  • SKILL-FLUTTER.md

Fullstory Element Properties API

Implementation Files: This document covers core concepts. For code examples, see:

Overview

Fullstory's Element Properties API allows developers to capture custom properties on UI elements that can be used for search, filtering, grouping, and analytics. Unlike standard attributes which are only used for CSS selectors, element properties become first-class data points for analysis, similar to user properties, page properties, and event properties.

Key capabilities:

  • Attach semantic business data to interactive elements
  • Enable filtering and segmentation by element context
  • Capture data on clicks, taps, and other interactions
  • Inherit properties through element hierarchy

Core Concepts

API Defined Elements

  • API Defined Elements provide a programmatic approach to defining Elements in Fullstory
  • Once created, these elements can be used across Fullstory features for search and analysis
  • Elements are defined using the data-fs-element attribute (web) or FS.setAttribute (mobile)
  • Element names are permanently attached to their associated Element (though display name can change)

Element Properties vs Attributes

TypePurposeSearchableExample
AttributesCSS selectors, element matching❌ Noclass="btn-primary"
Element PropertiesFiltering, grouping, analytics✅ YesproductId: "SKU-123"

When to Use Element Properties

Good use cases:

  • E-commerce product data (SKUs, prices, categories)
  • Form analytics (field names, validation states)
  • Content tracking (article IDs, categories)
  • A/B testing (variant names, experiment IDs)
  • User segments (tier levels, feature flags)
  • Navigation context (section names, page types)

Avoid for:

  • Technical/debug data (component versions, render timestamps)
  • Styling information (CSS classes, style properties)
  • Implementation details (framework internals, React keys)
  • High cardinality data (unique timestamps, random IDs)
  • Data already captured as user/page properties
  • PII without proper consent handling

⭐ Critical: Property Inheritance (Parent ↔ Child)

This is one of the most powerful features of Element Properties:

Two-way inheritance:

  • Parent → Child: Properties defined on a parent element are inherited by all child elements
  • Child → Parent: When an action occurs on a parent element, it captures properties from all defined child elements
┌─────────────────────────────────────────────────────────────────────┐
│  FORM (element="checkout-form")                                      │
│                                                                     │
│  ┌─────────────────────────────────────────────────────────────┐   │
│  │  SHIPPING SELECT (selectedShipping="express")                │   │
│  └─────────────────────────────────────────────────────────────┘   │
│                                                                     │
│  ┌─────────────────────────────────────────────────────────────┐   │
│  │  PAYMENT SELECT (selectedPayment="credit_card")              │   │
│  └─────────────────────────────────────────────────────────────┘   │
│                                                                     │
│  ┌─────────────────────────────────────────────────────────────┐   │
│  │  GIFT WRAP CHECKBOX (giftWrap="true")                        │   │
│  └─────────────────────────────────────────────────────────────┘   │
│                                                                     │
│  ┌─────────────────────────────────────────────────────────────┐   │
│  │  SUBMIT BUTTON (element="submit-order")                      │   │
│  │  ───────────────────────────────────────────────────────     │   │
│  │  When clicked, captures ALL properties from siblings:        │   │
│  │  • selectedShipping: "express"                               │   │
│  │  • selectedPayment: "credit_card"                            │   │
│  │  • giftWrap: true                                            │   │
│  └─────────────────────────────────────────────────────────────┘   │
│                                                                     │
└─────────────────────────────────────────────────────────────────────┘

Why this matters for analytics:

  • The submit button (or any parent action element) automatically captures the state of all child properties at the moment of interaction
  • You can create metrics like:
    • "Submit clicks WHERE selectedPayment = 'paypal'"
    • "Group submit clicks BY selectedShipping"
    • "Funnel: visits → checkout-form viewed → submit-order clicked WHERE giftWrap = true"

Key Insight: Define element properties on individual form fields, and the submit button will automatically capture the full form state. This eliminates the need to manually aggregate form data.


Supported Property Types

TypeDescriptionExamples
strString value"foo", "bar", "foo@bar"
strsArray of strings["foo", "bar"]
intInteger0, -123, 45
intsArray of integers[0, 1, 2]
realFloat/decimal12.345, -0.5
realsArray of reals[12.345, 1]
boolBooleantrue, false, 1, 0, t, f
boolsArray of booleans[true, false]
dateISO8601 date/datetime"2006-01-02T15:04:05Z"
datesArray of dates["2006-01-02", "2006-01-02T15:04:05Z"]

Type Formatting Requirements

TypeCorrectIncorrect
real199.99"$199.99" (no currency symbols)
int5"5 items" (no units/text)
booltrue or "true""yes", "Yes", "Y"
date"2024-01-15T00:00:00Z""today", "Jan 15"

Limits and Constraints

Global Limits

LimitValue
Active API Defined ElementsMax 1,000 (archived don't count)
Properties per single interactionMax 50 unique
Properties across all interactionsMax 500 unique

Property Requirements

  • Property Names: Use meaningful, readable names (no type suffix needed)
  • Property Values: Must match the specified type
  • Cardinality: High cardinality properties may be limited

Best Practices for Limits

  1. ✅ Focus on business-relevant properties only
  2. ✅ Avoid debug/technical properties
  3. ✅ Use property hierarchy to reduce duplication
  4. ✅ Archive unused elements to free up quota
  5. ✅ Monitor your property count

Common Implementation Patterns

Pattern 1: Container + Interactive Element

Container (e.g., product card)
  ├── Properties: productId, productName, price, category
  └── Button (e.g., "Add to Cart")
      └── Inherits all container properties
      └── Button interaction captures full product context

Pattern 2: Form + Fields

Form Container
  ├── Properties: formType, formStep, userTier
  ├── Field 1
  │   ├── Inherits form properties
  │   └── Own properties: fieldName, isRequired, fieldType
  ├── Field 2
  │   └── Same pattern
  └── Submit Button
      └── Inherits form properties + captures all field properties

Pattern 3: List Items

List Container
  ├── Properties: listType, totalItems, filterApplied
  └── List Item (repeated)
      ├── Inherits list properties
      └── Own properties: itemId, itemName, position

Implementation Order (Critical)

For all platforms, follow this order:

  1. Set attribute values FIRST
  2. Set the properties schema SECOND
  3. Name the element LAST (with data-fs-element or equivalent)

Setting the schema before values may cause timing issues with property capture.


Best Practices

Property Design

DoDon't
Use clean numeric valuesInclude currency symbols ($, €)
Use boolean true/falseUse "yes"/"no" strings
Use ISO8601 for datesUse human-readable dates
Use name override for readabilityUse raw attribute names
Focus on business-relevant dataCapture debug/technical data

Mobile-Specific Considerations

  • Handle view/cell reuse: Clear old attributes before setting new ones
  • Track applied attributes: Maintain a list for cleanup
  • Use lifecycle methods: prepareForReuse() (iOS), onBindViewHolder (Android)
  • Convert types to strings: Mobile SDKs expect string values for all attributes

Troubleshooting

Properties Not Appearing

SymptomCommon CausesSolutions
No properties capturedSchema set before valuesAlways set values before schema
No properties capturedInvalid JSON in schemaUse proper JSON builders, not manual strings
No properties capturedAttribute doesn't existVerify all schema attributes exist
No properties capturedHit property limitsCheck 50/500 limits

Wrong Values Captured (Mobile)

SymptomCommon CausesSolutions
Stale dataView/cell reuse not handledImplement prepareForReuse or clear in bind
Old attributes remainAttributes not clearedTrack and clear previous attributes
Wrong timingAttributes set at wrong lifecycle pointSet in appropriate lifecycle methods

Type Conversion Errors

SymptomCommon CausesSolutions
Numbers show as stringsValues contain non-numeric charsStrip formatting before setting
Booleans show as stringsUsing "yes"/"no"Use "true"/"false" strings
Dates not queryableWrong formatUse ISO8601 format

Pre-Deployment Checklist

  • All attribute values are set before the schema
  • All referenced attributes in schema actually exist
  • Numeric values are clean (no symbols, units, text)
  • Boolean values use "true"/"false" or "1"/"0"
  • Date values are in ISO8601 format
  • JSON schema is valid (no syntax errors)
  • Property names are meaningful and use name override
  • Types match the actual data (real for decimals, int for whole numbers)
  • Cell/view reuse is handled (mobile only)
  • Elements are named with data-fs-element (web) or equivalent (mobile)

Key Takeaways for Agent

When helping developers implement Element Properties:

  1. Always emphasize:

    • Set attribute values BEFORE schema
    • Use clean, unformatted values (no "$", "items", "Yes/No")
    • Match types correctly (real for decimals, int for integers, bool for booleans)
    • Provide meaningful property names via name override
  2. Common mistakes to watch for:

    • Schema set before values
    • Formatted numbers ("$10.99", "5 items")
    • "Yes"/"No" for booleans
    • Manual JSON string construction (mobile)
    • No cell/view reuse handling (mobile)
    • Over-capturing technical/debug data
  3. Questions to ask developers:

    • What data is business-relevant?
    • Is this element in a recycling container? (mobile)
    • Are there parent elements that should have properties?
    • What analytics questions need to be answered?
  4. Platform routing:

    • Web (JavaScript/HTML) → See SKILL-WEB.md
    • iOS (Swift/SwiftUI) → See SKILL-IOS.md
    • Android (Kotlin/Java) → See SKILL-ANDROID.md
    • Flutter (Dart) → See SKILL-FLUTTER.md
    • React Native → See SKILL-REACT-NATIVE.md

Reference Links

Skills Info
Original Name:fullstory-element-propertiesAuthor:fullstorydev