Skip to main content

Slot Component

The slot component enables modules to extend existing component layouts with additional UI elements without modifying the original component definition. A slot acts as an extension point: it queries for extension components stored in the database that target a specific slot name, then renders them in order.

How It Works

  1. A parent component defines a slot in its YAML layout
  2. Other modules register extension components in the database with a targetSlot property matching the slot name
  3. At runtime, the slot fetches all matching appComponents, sorts by order, and renders each extension's layout

Props

PropTypeRequiredDefaultDescription
namestringYesThe slot name to match against. Supports template expressions (e.g., TMS/{{entityType}}/Tabs)
itemTagstringNoReact.FragmentHTML element type to wrap each extension (e.g., li, div)

Extension Component Definition

Extension components stored in the database (registered via another module's appComponents) must have a componentDefinition with:

PropertyTypeRequiredDefaultDescription
props.targetSlotstringYesMust match the slot's name prop
props.ordernumberNo0Sort order; lower values render first
layoutobjectYesThe component layout to render

YAML Examples

Defining a Slot

# In a shipment dashboard layout — extension point for additional tabs
- component: slot
props:
name: "TMS/ShipmentDashboard/Tabs"

Dynamic Slot Name with Template

- component: slot
props:
name: "TMS/{{entityType}}/Actions"

Slot with Item Wrapper

- component: slot
props:
name: "TMS/ShipmentDashboard/Sidebar"
itemTag: "div"

Extension Component (registered by another module)

name: "TMS/ShipmentDashboard/TrackingTab"
props:
targetSlot: "TMS/ShipmentDashboard/Tabs"
order: 10
layout:
component: tab
props:
label:
en-US: "Tracking"
children:
- component: layout
props:
component: "TMS/Tracking/Panel"

Slot Naming Convention

Use a hierarchical naming pattern:

{Module}/{Entity}/{Location}

Examples:

  • TMS/ShipmentDashboard/Tabs
  • TMS/OrderDetail/Actions
  • CRM/ContactPage/Sidebar

Technical Notes

  • Uses GraphQL query with allowCache: true (15-minute cache)
  • Filters server-side using Lucene filter componentDefinition.props.targetSlot:<slotName>, with client-side filtering as a safety net
  • Variables and context from the parent component are passed through to each extension
  • Query errors are handled gracefully (renders nothing, no crash)