Skip to content
Back to skills

246 Custom Lightning Types 1f81a5de

ASecurity

> Build custom UI components for agent action inputs and outputs using LightningTypeBundle

  • 9 stars
  • 0 votes
  • 0 copies
  • 0 views
  • Added October 11, 2026
code-qualitygobashapidocumentation

Works with

  • api

Security analysis

A100/100

Scanned October 11, 2026

npx -y skills add tools-only/X-Skills --skill 246-custom-lightning-types_1f81a5de --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of 246 Custom Lightning Types 1f81a5de?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for 246 Custom Lightning Types 1f81a5de
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/tools-only-246-custom-lightning-types-1f81a5de/badge)](https://www.skillsdirectory.com/skills/tools-only-246-custom-lightning-types-1f81a5de)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

SKILL.md
<!-- TIER: 3 | DETAILED REFERENCE -->
<!-- Read after: SKILL.md, agent-script-reference.md, actions-guide.md -->
<!-- Purpose: LightningTypeBundle for custom agent action UIs (API 64.0+) -->

# Custom Lightning Types for Agentforce

> Build custom UI components for agent action inputs and outputs using LightningTypeBundle

## Overview

**Custom Lightning Types** enable you to define custom data structures with dedicated UI components for Agentforce service agents. When an agent action requires structured input or displays complex output, you can create a custom type with:

- **Schema**: Define the data structure and validation
- **Editor**: Custom UI for input collection
- **Renderer**: Custom UI for displaying output

```
┌─────────────────────────────────────────────────────────────────────────────┐
│                    CUSTOM LIGHTNING TYPE ARCHITECTURE                        │
├─────────────────────────────────────────────────────────────────────────────┤
│                                                                             │
│  LightningTypeBundle/                                                       │
│  └── MyCustomType/                                                          │
│      ├── schema.json        ← Data structure definition                     │
│      ├── editor.json        ← Input UI configuration                        │
│      ├── renderer.json      ← Output UI configuration                       │
│      └── MyCustomType.lightningTypeBundle-meta.xml                          │
│                                                                             │
│                           ▼                                                 │
│                                                                             │
│  ┌─────────────────────────────────────────────────────────────────┐       │
│  │                     AGENT CONVERSATION                          │       │
│  ├─────────────────────────────────────────────────────────────────┤       │
│  │  Agent: I need some details to proceed.                         │       │
│  │                                                                  │       │
│  │  ┌──────────────────────────────────────────┐                   │       │
│  │  │ [Custom Input UI - Editor Component]      │                   │       │
│  │  │ ┌───────────────┐ ┌────────────────────┐ │                   │       │
│  │  │ │ Name: [_____] │ │ Type: [Dropdown ▼] │ │                   │       │
│  │  │ └───────────────┘ └────────────────────┘ │                   │       │
│  │  │ [Submit]                                  │                   │       │
│  │  └──────────────────────────────────────────┘                   │       │
│  │                                                                  │       │
│  │  Agent: Here's the result:                                      │       │
│  │                                                                  │       │
│  │  ┌──────────────────────────────────────────┐                   │       │
│  │  │ [Custom Output UI - Renderer Component]   │                   │       │
│  │  │ ┌─────────────────────────────────────┐  │                   │       │
│  │  │ │ Order #12345                         │  │                   │       │
│  │  │ │ Status: ✅ Confirmed                 │  │                   │       │
│  │  │ │ [View Details] [Track Shipment]      │  │                   │       │
│  │  │ └─────────────────────────────────────┘  │                   │       │
│  │  └──────────────────────────────────────────┘                   │       │
│  └─────────────────────────────────────────────────────────────────┘       │
│                                                                             │
└─────────────────────────────────────────────────────────────────────────────┘
```

---

## Prerequisites

### API Version Requirement

**Minimum API v64.0+ (Fall '25)** for LightningTypeBundle support.

```bash
# Verify org API version
sf org display --target-org [alias] --json | jq '.result.apiVersion'
```

### Enhanced Chat V2 Requirement

Custom Lightning Types require **Enhanced Chat V2** in Service Cloud:

1. Go to **Setup → Chat → Chat Settings**
2. Enable **Enhanced Chat Experience**
3. Select **Version 2 (Enhanced)**

> ⚠️ Without Enhanced Chat V2, custom type UI components will not render.

---

## File Structure

```
force-app/main/default/
└── lightningTypeBundles/
    └── OrderDetails/
        ├── schema.json
        ├── editor.json
        ├── renderer.json
        └── OrderDetails.lightningTypeBundle-meta.xml
```

### Bundle Metadata XML

```xml
<?xml version="1.0" encoding="UTF-8"?>
<LightningTypeBundle xmlns="http://soap.sforce.com/2006/04/metadata">
    <masterLabel>Order Details</masterLabel>
    <description>Custom type for order information display</description>
</LightningTypeBundle>
```

---

## Schema Definition (schema.json)

The schema defines your data structure using JSON Schema format:

### Basic Schema

```json
{
    "$schema": "http://json-schema.org/draft-07/schema#",
    "type": "object",
    "title": "OrderDetails",
    "description": "Order information for display in agent conversations",
    "properties": {
        "orderId": {
            "type": "string",
            "title": "Order ID",
            "description": "Unique order identifier"
        },
        "orderStatus": {
            "type": "string",
            "title": "Order Status",
            "enum": ["Pending", "Processing", "Shipped", "Delivered", "Cancelled"],
            "description": "Current order status"
        },
        "orderDate": {
            "type": "string",
            "format": "date",
            "title": "Order Date"
        },
        "totalAmount": {
            "type": "number",
            "title": "Total Amount",
            "minimum": 0
        },
        "items": {
            "type": "array",
            "title": "Order Items",
            "items": {
                "type": "object",
                "properties": {
                    "productName": {
                        "type": "string"
                    },
                    "quantity": {
                        "type": "integer",
                        "minimum": 1
                    },
                    "price": {
                        "type": "number",
                        "minimum": 0
                    }
                },
                "required": ["productName", "quantity", "price"]
            }
        }
    },
    "required": ["orderId", "orderStatus"]
}
```

### Supported JSON Schema Types

| Type | JSON Schema | Notes |
|------|-------------|-------|
| Text | `"type": "string"` | Standard text input |
| Number | `"type": "number"` | Decimal values |
| Integer | `"type": "integer"` | Whole numbers only |
| Boolean | `"type": "boolean"` | True/false checkbox |
| Enum | `"enum": [...]` | Dropdown selection |
| Date | `"format": "date"` | Date picker |
| DateTime | `"format": "date-time"` | Date and time picker |
| Array | `"type": "array"` | List of items |
| Object | `"type": "object"` | Nested structure |

### Validation Keywords

```json
{
    "properties": {
        "email": {
            "type": "string",
            "format": "email",
            "maxLength": 255
        },
        "quantity": {
            "type": "integer",
            "minimum": 1,
            "maximum": 100
        },
        "productCode": {
            "type": "string",
            "pattern": "^PRD-[0-9]{6}$"
        }
    }
}
```

---

## Editor Configuration (editor.json)

The editor defines how input fields are collected from users:

### Basic Editor

```json
{
    "component": "lightning-record-edit-form",
    "attributes": {
        "objectApiName": "Custom_Lightning_Type"
    },
    "fields": [
        {
            "name": "orderId",
            "component": "lightning-input",
            "attributes": {
                "label": "Order ID",
                "placeholder": "Enter order number",
                "required": true
            }
        },
        {
            "name": "orderStatus",
            "component": "lightning-combobox",
            "attributes": {
                "label": "Order Status",
                "options": [
                    { "label": "Pending", "value": "Pending" },
                    { "label": "Processing", "value": "Processing" },
                    { "label": "Shipped", "value": "Shipped" },
                    { "label": "Delivered", "value": "Delivered" },
                    { "label": "Cancelled", "value": "Cancelled" }
                ]
            }
        },
        {
            "name": "orderDate",
            "component": "lightning-input",
            "attributes": {
                "type": "date",
                "label": "Order Date"
            }
        },
        {
            "name": "totalAmount",
            "component": "lightning-input",
            "attributes": {
                "type": "number",
                "label": "Total Amount",
                "formatter": "currency",
                "step": "0.01"
            }
        }
    ],
    "submitButton": {
        "label": "Submit Order Details",
        "variant": "brand"
    }
}
```

### Supported Editor Components

| Component | Use Case | Example |
|-----------|----------|---------|
| `lightning-input` | Text, number, date, email, etc. | `"type": "text"` |
| `lightning-combobox` | Dropdown selection | With `options` array |
| `lightning-checkbox` | Boolean toggle | Single checkbox |
| `lightning-checkbox-group` | Multiple selections | Array of checkboxes |
| `lightning-radio-group` | Single selection from options | Radio buttons |
| `lightning-textarea` | Multi-line text | Long descriptions |
| `lightning-file-upload` | File attachment | Document upload |

### Conditional Fields

```json
{
    "fields": [
        {
            "name": "hasDiscount",
            "component": "lightning-checkbox",
            "attributes": {
                "label": "Apply Discount?"
            }
        },
        {
            "name": "discountCode",
            "component": "lightning-input",
            "attributes": {
                "label": "Discount Code"
            },
            "conditions": {
                "hasDiscount": true
            }
        }
    ]
}
```

---

## Renderer Configuration (renderer.json)

The renderer defines how output is displayed to users:

### Basic Renderer

```json
{
    "component": "lightning-card",
    "attributes": {
        "title": "Order Details",
        "iconName": "standard:orders"
    },
    "body": [
        {
            "component": "lightning-layout",
            "attributes": {
                "multipleRows": true
            },
            "body": [
                {
                    "component": "lightning-layout-item",
                    "attributes": {
                        "size": "6"
                    },
                    "body": [
                        {
                            "component": "lightning-formatted-text",
                            "attributes": {
                                "value": "Order #${orderId}"
                            }
                        }
                    ]
                },
                {
                    "component": "lightning-layout-item",
                    "attributes": {
                        "size": "6"
                    },
                    "body": [
                        {
                            "component": "lightning-badge",
                            "attributes": {
                                "label": "${orderStatus}"
                            }
                        }
                    ]
                }
            ]
        },
        {
            "component": "lightning-formatted-number",
            "attributes": {
                "value": "${totalAmount}",
                "style": "currency",
                "currencyCode": "USD"
            }
        }
    ]
}
```

### Supported Renderer Components

| Component | Use Case |
|-----------|----------|
| `lightning-card` | Container with header |
| `lightning-layout` | Grid layout |
| `lightning-formatted-text` | Display text |
| `lightning-formatted-number` | Currency, percent |
| `lightning-formatted-date-time` | Date display |
| `lightning-badge` | Status indicators |
| `lightning-icon` | Icons |
| `lightning-button` | Actions |
| `lightning-datatable` | Tabular data |
| `lightning-progress-bar` | Progress display |

### List Rendering

For array data:

```json
{
    "component": "lightning-datatable",
    "attributes": {
        "keyField": "productName",
        "data": "${items}",
        "columns": [
            { "label": "Product", "fieldName": "productName" },
            { "label": "Quantity", "fieldName": "quantity", "type": "number" },
            { "label": "Price", "fieldName": "price", "type": "currency" }
        ]
    }
}
```

---

## Complete Example: Customer Address

### 1. schema.json

```json
{
    "$schema": "http://json-schema.org/draft-07/schema#",
    "type": "object",
    "title": "CustomerAddress",
    "properties": {
        "street": {
            "type": "string",
            "title": "Street Address",
            "maxLength": 255
        },
        "city": {
            "type": "string",
            "title": "City"
        },
        "state": {
            "type": "string",
            "title": "State/Province"
        },
        "postalCode": {
            "type": "string",
            "title": "Postal Code",
            "pattern": "^[0-9]{5}(-[0-9]{4})?$"
        },
        "country": {
            "type": "string",
            "title": "Country",
            "enum": ["United States", "Canada", "Mexico", "United Kingdom"]
        },
        "isDefault": {
            "type": "boolean",
            "title": "Default Address",
            "default": false
        }
    },
    "required": ["street", "city", "postalCode", "country"]
}
```

### 2. editor.json

```json
{
    "layout": "vertical",
    "fields": [
        {
            "name": "street",
            "component": "lightning-textarea",
            "attributes": {
                "label": "Street Address",
                "placeholder": "Enter your street address",
                "required": true,
                "maxLength": 255
            }
        },
        {
            "name": "city",
            "component": "lightning-input",
            "attributes": {
                "type": "text",
                "label": "City",
                "required": true
            }
        },
        {
            "name": "state",
            "component": "lightning-input",
            "attributes": {
                "type": "text",
                "label": "State/Province"
            }
        },
        {
            "name": "postalCode",
            "component": "lightning-input",
            "attributes": {
                "type": "text",
                "label": "Postal Code",
                "required": true,
                "pattern": "[0-9]{5}(-[0-9]{4})?"
            }
        },
        {
            "name": "country",
            "component": "lightning-combobox",
            "attributes": {
                "label": "Country",
                "required": true,
                "options": [
                    { "label": "United States", "value": "United States" },
                    { "label": "Canada", "value": "Canada" },
                    { "label": "Mexico", "value": "Mexico" },
                    { "label": "United Kingdom", "value": "United Kingdom" }
                ]
            }
        },
        {
            "name": "isDefault",
            "component": "lightning-checkbox",
            "attributes": {
                "label": "Set as default address"
            }
        }
    ],
    "submitButton": {
        "label": "Save Address",
        "variant": "brand"
    }
}
```

### 3. renderer.json

```json
{
    "component": "lightning-card",
    "attributes": {
        "title": "Shipping Address",
        "iconName": "standard:address"
    },
    "body": [
        {
            "component": "lightning-formatted-address",
            "attributes": {
                "street": "${street}",
                "city": "${city}",
                "province": "${state}",
                "postalCode": "${postalCode}",
                "country": "${country}"
            }
        },
        {
            "component": "lightning-badge",
            "conditions": {
                "isDefault": true
            },
            "attributes": {
                "label": "Default",
                "class": "slds-m-top_small"
            }
        }
    ]
}
```

### 4. CustomerAddress.lightningTypeBundle-meta.xml

```xml
<?xml version="1.0" encoding="UTF-8"?>
<LightningTypeBundle xmlns="http://soap.sforce.com/2006/04/metadata">
    <masterLabel>Customer Address</masterLabel>
    <description>Structured address for customer shipping information</description>
</LightningTypeBundle>
```

---

## Using Custom Types in Agent Actions

### In GenAiFunction Metadata

```xml
<GenAiFunction xmlns="http://soap.sforce.com/2006/04/metadata">
    <masterLabel>Collect Shipping Address</masterLabel>
    <developerName>Collect_Shipping_Address</developerName>
    <description>Collects customer shipping address</description>

    <invocationTarget>Collect_Address_Flow</invocationTarget>
    <invocationTargetType>flow</invocationTargetType>

    <capability>
        Collect the customer's shipping address when they want to update
        their delivery information or place an order.
    </capability>

    <!-- Output uses custom Lightning Type -->
    <genAiFunctionOutputs>
        <developerName>shippingAddress</developerName>
        <description>The customer's shipping address</description>
        <dataType>CustomerAddress</dataType>
        <isRequired>true</isRequired>
    </genAiFunctionOutputs>
</GenAiFunction>
```

### In Agent Script

```agentscript
topic address_management:
    label: "Address Management"
    description: "Manages customer addresses"

    actions:
        Collect_Shipping_Address:
            description: "Collect the customer's shipping address"
            outputs:
                # Reference custom Lightning Type as output
                shippingAddress: CustomerAddress
                    description: "Customer shipping address"
                    is_used_by_planner: True
                    is_displayable: True
            target: "flow://Collect_Address_Flow"

    reasoning:
        instructions: ->
            | When the user wants to update their shipping address,
            | use the Collect_Shipping_Address action.
            | The custom UI will collect the address details.
        actions:
            collect: @actions.Collect_Shipping_Address
```

---

## Best Practices

```
┌─────────────────────────────────────────────────────────────────────────────┐
│                    CUSTOM LIGHTNING TYPES BEST PRACTICES                     │
├─────────────────────────────────────────────────────────────────────────────┤
│                                                                             │
│  SCHEMA DESIGN                                                              │
│  ─────────────────────────────────────────────────────────────────────────  │
│  ✅ Keep schemas focused on a single concept                                │
│  ✅ Use meaningful property names                                           │
│  ✅ Add validation constraints (min, max, pattern)                          │
│  ✅ Mark required fields explicitly                                         │
│  ❌ Don't nest objects more than 2 levels deep                              │
│  ❌ Don't create overly complex schemas                                     │
│                                                                             │
│  EDITOR UX                                                                  │
│  ─────────────────────────────────────────────────────────────────────────  │
│  ✅ Group related fields together                                           │
│  ✅ Use appropriate input types (date picker for dates)                     │
│  ✅ Provide clear labels and placeholders                                   │
│  ✅ Use conditional fields to reduce complexity                             │
│  ❌ Don't require too many fields at once                                   │
│  ❌ Don't hide critical fields behind conditions                            │
│                                                                             │
│  RENDERER UX                                                                │
│  ─────────────────────────────────────────────────────────────────────────  │
│  ✅ Highlight the most important information                                │
│  ✅ Use visual hierarchy (cards, badges, icons)                             │
│  ✅ Format data appropriately (currency, dates)                             │
│  ✅ Keep displays scannable and concise                                     │
│  ❌ Don't display raw data without formatting                               │
│  ❌ Don't crowd too much information                                        │
│                                                                             │
│  DEPLOYMENT                                                                 │
│  ─────────────────────────────────────────────────────────────────────────  │
│  ✅ Deploy LightningTypeBundle before GenAiFunction                         │
│  ✅ Test with Enhanced Chat V2 enabled                                      │
│  ✅ Validate JSON files before deployment                                   │
│  ❌ Don't reference undefined custom types                                  │
│                                                                             │
└─────────────────────────────────────────────────────────────────────────────┘
```

---

## Deployment

### package.xml Entry

```xml
<?xml version="1.0" encoding="UTF-8"?>
<Package xmlns="http://soap.sforce.com/2006/04/metadata">
    <types>
        <members>*</members>
        <name>LightningTypeBundle</name>
    </types>
    <version>64.0</version>
</Package>
```

### Deploy Command

```bash
# Deploy specific type
sf project deploy start -m "LightningTypeBundle:CustomerAddress"

# Deploy all types
sf project deploy start -d force-app/main/default/lightningTypeBundles/

# Deploy with dependencies (type + action)
sf project deploy start -m "LightningTypeBundle:CustomerAddress,GenAiFunction:Collect_Shipping_Address"
```

### Deployment Order

1. **LightningTypeBundle** - Deploy custom types first
2. **GenAiFunction** - Deploy actions that reference the types
3. **AiAuthoringBundle** - Deploy agent that uses the actions

---

## Troubleshooting

| Issue | Cause | Solution |
|-------|-------|----------|
| UI not rendering | Enhanced Chat V2 not enabled | Enable Enhanced Chat V2 in Setup |
| "Type not found" | Custom type not deployed | Deploy LightningTypeBundle first |
| Schema validation error | Invalid JSON Schema | Validate against JSON Schema draft-07 |
| Editor fields missing | Incorrect field names | Match `name` in editor.json to schema properties |
| Renderer empty | Variable syntax error | Use `${propertyName}` for value interpolation |

---

## Related Documentation

- [Actions Reference](actions-reference.md) - GenAiFunction metadata
- [Agent Script Reference](agent-script-reference.md) - Action syntax
- [Patterns & Practices](patterns-and-practices.md) - Agent design patterns

---

## Source

> **Reference**: [How to Use Custom Lightning Types in Agentforce Service Agents](https://salesforcediaries.com/2025/11/23/how-to-use-custom-lightning-types-in-agentforce-service-agents-1/) - Salesforce Diaries

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…

Newsletter

Get the weekly list of safe new skills, and the ones we pulled.