FragmentFragment

Component

Reusable template-backed renderer with full reactive access.

A Component is a reusable renderer bound to a template Instance stored in your assets. When called via Fragment.useComponent, the template is cloned and the renderer runs against the clone with the given props and the calling Handle — giving the Component full access to Effect, Connect, RegisterContainer, stores, contexts, and hooks.

Client Only

Components are part of the Fragment reactive system and only run on the client.


Registration

Fragment.newComponent(name, path)

Creates a new Component definition. The path resolves from the DataModel root (game).

Prop

Type

Call the returned Component with a renderer to complete registration.

Components/ItemCard.luau
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local Fragment = require(ReplicatedStorage.Fragment)

local Component = Fragment.newComponent("ItemCard", {
    "ReplicatedStorage", "BE_Shared", "Assets", "UI", "ItemCardTemplate"
})

return Component(function(element: Frame, props: {
    Id:    string,
    Name:  string,
    Price: number,
}, handle: any)
    element.Name = props.Id
    element:FindFirstChild("NameLabel").Text  = props.Name
    element:FindFirstChild("PriceLabel").Text = `🪙 {props.Price}`
end)

Renderer signature

function(element: Instance, props: { [string]: any }, handle: any)

Prop

Type


Render-cycle access

Because the Handle is forwarded, a Component renderer has access to the same full set of render-cycle methods as the Handle's own renderer.

Effects

Components/LiveTimer.luau
return Component(function(element, props, handle)
    handle.Effect(function() 
        local conn = RunService.Heartbeat:Connect(function()
            element.Text = os.date("%H:%M:%S")
        end)
        return function()
            conn:Disconnect()
        end
    end) 
end)

Connections

Components/BuyButton.luau
return Component(function(element, props, handle)
    handle.Connect("Buy_" .. props.Id, element.Activated, function() 
        ShopService:PurchaseAsync(props.Id)
    end) 
end)

Stores

Components/CoinBadge.luau
return Component(function(element, props, handle)
    local store = Fragment.useStore("PlayerData") 
    element.Text = `🪙 {store.getData().coins}`
end)

Contexts

Components/CloseButton.luau
local WindowContext = require(path.to.Contexts.WindowContext)

return Component(function(element, props, handle)
    local win = handle:pull(WindowContext) 

    handle.Connect("Close_" .. props.windowName, element.Activated, function()
        win.close(props.windowName) 
    end)
end)

Hooks

Components/ToggleRow.luau
local useToggle = require(path.to.Hooks.useToggle)

return Component(function(element, props, handle)
    local isOn, toggle = useToggle(props.initialState) 

    element.Toggle.Active = isOn()

    handle.Connect("Toggle_" .. props.id, element.Toggle.Activated, function()
        toggle()
    end)
end)

Nested Containers

Components can register their own Containers to manage dynamic children.

Components/InventorySection.luau
return Component(function(element, props, handle)
    local list = handle.RegisterContainer(element.ItemList) 

    for _, item in ipairs(props.items) do
        local row = Fragment.useComponent("ItemRow", { id = item.id, name = item.name })
        list.UpsertChild(item.id, row)
    end
end)

Usage

Fragment.useComponent(name, props)

Clones the registered template, runs the renderer, and returns the unparented clone. Always pass the result to a Container via UpsertChild.

Prop

Type

Handles/ShopHandle.luau
local grid = Handle.RegisterContainer(element.ItemGrid)

for _, item in ipairs(data.items) do
    local card = Fragment.useComponent("ItemCard", { 
        Id    = item.id, 
        Name  = item.displayName, 
        Price = item.price, 
    }) 
    grid.UpsertChild(item.id, card)
end

useComponent is safe anywhere

useComponent can be called in the renderer body, inside an Effect callback, or inside an Action handler. The active Handle is captured at call time.

On this page