Overlay View Components
Updated: Mar 25, 2026
Copy for LLM
Overlay views are built using a declarative XML syntax. Each XML element maps to an HTML element that Meta renders inside a secure iframe. You compose these elements to display player information — names, profile pictures, scores — that your game cannot access directly under the Zero Permissions model.
This page documents every available component, its attributes, and how to use it effectively.
Unity developers: You can create overlay views using the C# API (FBInstant.OverlayViews.CreateOverlayViewAsync) or the visual Overlay View Builder editor tool. See the Unity Plugin for details.
How Components Work
When you create an overlay view using
FBInstant.overlayViews.createOverlayViewAsync(), the platform parses your XML, resolves any template expressions (such as ``), and renders the result as HTML inside an iframe. Your game controls the iframe’s position and size, but Meta controls the content inside it.Components fall into two categories:
- Basic components render visible elements — containers, text, buttons, and images.
- Control structure components handle logic — loops, conditionals, and compound conditions.
Basic Components
View
A generic container element. Renders as a
<div></div> in the final HTML. Use View to group other components, apply layout styles, and handle tap events.| Attribute | Type | Description |
|---|---|---|
className | String | CSS class name defined in your styles.css file (included in your game bundle). |
style | String | Inline CSS styles applied directly to the element. Use CSS property syntax with semicolons (e.g., "display: flex; gap: 8px"). |
onTapEvent | String | A custom event name that fires when the user taps or clicks this element. The event is delivered to your game via FBInstant.overlayViews.setCustomEventHandler(). |
<View className="card" style="display: flex; align-items: center; gap: 12px" onTapEvent="selectPlayer_"> <!-- Child components go here --> </View>
Text
Renders a paragraph of text. Renders as a
<p></p> element in the final HTML.| Attribute | Type | Description |
|---|---|---|
className | String | CSS class name for styling. |
style | String | Inline CSS styles. |
content | String | The text to display. Supports template expressions like or. |
<Text content="Welcome, !" className="greeting" />
An interactive button element. Renders as a
<button></button> in the final HTML. Buttons can either fire a custom event (via onTapEvent on a parent View) or trigger a built-in context action.| Attribute | Type | Description |
|---|---|---|
className | String | CSS class name for styling. |
style | String | Inline CSS styles. |
content | String | The button’s display text. Supports template expressions. |
action | String | A context action to execute when pressed. Use or to trigger context changes directly from the overlay. |
<Button content="Challenge" action=")}}" className="challengeBtn" />
Image
Displays an image. Renders as an
<img> element in the final HTML.| Attribute | Type | Description |
|---|---|---|
className | String | CSS class name for styling. |
style | String | Inline CSS styles. |
src | String | The image source (see allowed sources below). |
width | Number | Image width in pixels (e.g., width="48"). |
onTapEvent | String | A custom event name that fires when the image is tapped. |
<Image src="" className="avatar" width="48" style="border-radius: 50%" />
Note: When a player opts for their actual profile image (rather than a gaming avatar), the image is 128x128 pixels.
Allowed Image Sources
Overlay views can only load images from specific sources. External CDN URLs (Cloudflare, AWS, etc.) are not supported.
| Source | Example | Works? |
|---|---|---|
Game bundle (relative path) | src="icons/sword.png" | Yes |
Player photo template | src="" | Yes |
Arbitrary player photo | src="].photo}}" | Yes |
Base64 data URL (via initialData) | src="" | Yes |
External CDN URL | src="https://cdn.example.com/img.png" | No |
If you need to display images from your CDN, fetch them in your game’s JavaScript, convert to base64, and pass them via
initialData:// In your game code async function toBase64(url) { var res = await fetch(url); var blob = await res.blob(); return new Promise(function(resolve) { var reader = new FileReader(); reader.onloadend = function() { resolve(reader.result); }; reader.readAsDataURL(blob); }); } var icon = await toBase64('https://your-cdn.com/icon.png'); var overlay = await FBInstant.overlayViews.createOverlayViewAsync( 'overlays/inventory.xml', container, iframeStyle, null, { iconBase64: icon } );
<Image src="" width="32" />
Control Structure Components
Control structures let you add logic to your overlay views — iterating over lists of players, conditionally showing content, and combining conditions.
For
Iterates over a data source and renders its child components once for each item. This is how you build lists of players, leaderboard entries, or any repeated UI pattern.
| Attribute | Type | Required | Description |
|---|---|---|---|
source | String | Yes | The data to iterate over. Can be a built-in source like or, or a custom list passed via initialData. |
itemName | String | Yes | The variable name used to reference each item inside the loop body (e.g., "player"). Access item properties with ,, etc. |
sortKey | String | No | A property name to sort items by. Can reference player data keys or custom data. |
order | String | No | Sort direction: ASC (ascending) or DESC (descending). Defaults to ASC. |
limit | Number | No | Maximum number of items to render. |
startIndex | Number | No | The starting index for iteration. Defaults to 1. |
scrollStyle | String | No | Controls overflow scroll position when the list exceeds the visible area. Values: top, bottom, center. |
scrollIndex | Number | No | When scrollStyle is center, specifies which item index to center the scroll on. |
<View> <For source="" itemName="friend" sortKey="name" order="ASC" limit="10"> <View className="friendRow" style="display: flex; align-items: center; gap: 8px"> <Image src="" style="width: 40px; height: 40px; border-radius: 50%" /> <Text content="" className="friendName" /> </View> </For> </View>
You can also sort by dynamic keys using nested template expressions. This is useful when you have score data keyed by player ID:
<For source="" itemName="player" sortKey="]}}" order="DESC"> <View> <Text content="" /> <Text content="Score: ]}}" /> </View> </For>
If, ElseIf, and Else
Conditional rendering blocks. Use
If to show content only when a condition is met, with optional ElseIf and Else branches for fallback content.<If> <Condition lhs="" operator="GREATER_THAN" rhs="1000" /> <View> <Text content="High scorer!" className="badge" /> </View> <ElseIf> <Condition lhs="" operator="GREATER_THAN" rhs="500" /> <View> <Text content="Getting there!" /> </View> </ElseIf> <Else> <View> <Text content="Keep playing!" /> </View> </Else> </If>
Condition
Defines a comparison inside an
If or ElseIf block.| Attribute | Type | Description |
|---|---|---|
lhs | String | The left-hand side value. Supports template expressions. |
operator | String | The comparison operator (see table below). |
rhs | String | The right-hand side value. Supports template expressions. |
Available operators:
| Operator | Meaning |
|---|---|
EQUALS | lhs == rhs |
NOT_EQUALS | lhs != rhs |
GREATER_THAN | lhs > rhs |
NOT_GREATER_THAN | lhs <= rhs |
LESS_THAN | lhs < rhs |
NOT_LESS_THAN | lhs >= rhs |
IN | lhs is contained in rhs (array or string) |
NOT_IN | lhs is not contained in rhs |
ConditionGroup
Combines multiple
Condition elements under a logical operator. Use this when you need to evaluate more than one condition together.| Attribute | Type | Description |
|---|---|---|
operator | String | AND (all conditions must be true) or OR (at least one must be true). |
<If> <ConditionGroup operator="AND"> <Condition lhs="" operator="GREATER_THAN" rhs="5" /> <Condition lhs="" operator="EQUALS" rhs="true" /> </ConditionGroup> <View> <Text content="Secret area unlocked!" /> </View> </If>
Styling Best Practices
Overlay views support CSS styling through both inline
style attributes and external CSS files referenced when creating the overlay.Recommended approach:
- Define reusable styles in a
styles.cssfile in your game bundle. - Reference classes via the
classNameattribute on components. - Use inline
stylefor one-off positioning or dynamic values.
/* styles.css */
.friendRow {
display: flex;
align-items: center;
padding: 8px;
border-bottom: 1px solid #eee;
}
.avatar {
width: 48px;
height: 48px;
border-radius: 50%;
}
Known issue:position: absolutecan cause rendering issues in overlay views. Useposition: relativewith flexbox layouts as a workaround.
Custom Fonts
Custom fonts must be defined using
@font-face in an external CSS file — you cannot add <style> blocks inside XML. Only TTF font files are supported./* styles.css */
@font-face {
font-family: 'MyGameFont';
src: url('MyGameFont.ttf');
}
.game-text {
font-family: 'MyGameFont';
font-size: 18px;
}
Include the font file in your game bundle alongside the CSS file. The font is loaded before the overlay renders, so there is no flash of unstyled text.
Overlay Reuse
Overlays are not garbage collected when dismissed —
dismissAsync() only hides the iframe. To avoid unnecessary memory usage:- Reuse overlays by calling
updateAsync()+showAsync()instead of creating new ones. - Pre-create a pool for variable-count overlays (e.g., per-player name tags) at startup and recycle them.
- Keep frequently updated overlays small. Every
updateAsync()call triggers a full re-render, including re-fetching all images.
Next Steps
- Example Game Use Cases — See complete examples of overlay views for friend lists, leaderboards, and more.
- Overlay Preview Tool — Build and test overlay views interactively in the browser.
- API Reference — Full reference for the
FBInstant.overlayViewsmodule.