Instant Games

Arbitrary Player Rendering

Updated: Mar 25, 2026
Copy for LLM
Overlay views can render any player’s profile information — name and photo — given their player ID. The target player does not need to be a friend of the current player or share a game context. This makes it possible to build custom leaderboards, matchmaking UIs, and spectator features that display players from across your entire game.

Basic Usage

Reference a player by ID using the FBInstant.players[{{playerID}}] template expression:
XML:
<View className="playerCard">
  <Image src="{{FBInstant.players[{{playerID}}].photo}}" className="avatar" />
  <Text content="{{FBInstant.players[{{playerID}}].name}}" className="name" />
</View>
JavaScript:
var container = document.getElementById('opponentCard');

FBInstant.overlayViews.createOverlayViewAsync(
  'overlays/player_card.xml',
  container,
  'width: 200px; height: 60px; border: none;',
  'overlays/styles.css',
  { playerID: '456789012345' }
).then(function(overlay) {
  overlay.showAsync();
});
The playerID is passed as initialData, and the overlay system resolves it to the player’s name and photo at render time.
Note: If a player opts for their actual profile image (rather than a gaming avatar), the image will be 128x128 pixels.

Rendering Multiple Players

To display a list of arbitrary players — for example, leaderboard entries or matchmaking candidates — pass an array of player IDs and use a For loop:
XML (overlays/player_list.xml):
<View className="playerList">
  <For source="{{players}}" itemName="entry">
    <View className="playerRow" onTapEvent="selectPlayer_{{entry.playerID}}">
      <Image src="{{FBInstant.players[{{entry.playerID}}].photo}}" className="avatar" />
      <Text content="{{FBInstant.players[{{entry.playerID}}].name}}" className="name" />
    </View>
  </For>
</View>
JavaScript:
var container = document.getElementById('playerListContainer');

FBInstant.overlayViews.createOverlayViewAsync(
  'overlays/player_list.xml',
  container,
  'width: 100%; height: 300px; border: none;',
  'overlays/styles.css',
  {
    players: [
      { playerID: '123' },
      { playerID: '456' },
      { playerID: '789' }
    ]
  }
).then(function(overlay) {
  overlay.showAsync();
});

// Handle player selection
FBInstant.overlayViews.setCustomEventHandler(function(eventStr, overlayID) {
  if (eventStr.startsWith('selectPlayer_')) {
    var playerID = eventStr.replace('selectPlayer_', '');
    handlePlayerSelected(playerID);
  }
});

Common Use Cases

Custom Leaderboard

Fetch ranked entries from your own backend server, then render player profiles using overlay views:
// Fetch leaderboard from your server
fetch('https://yourserver.com/api/leaderboard/top?limit=10')
  .then(function(res) { return res.json(); })
  .then(function(data) {
    // data.entries = [{ rank: 1, playerID: '123', score: 5000 }, ...]
    return FBInstant.overlayViews.createOverlayViewAsync(
      'overlays/leaderboard.xml',
      document.getElementById('leaderboard'),
      'width: 100%; height: 500px; border: none;',
      'overlays/styles.css',
      { players: data.entries }
    );
  });
See Global Leaderboards for the full implementation guide including server-side identity verification.

Matchmaking Result

After your server matches two players, display the opponent’s profile:
// Your server returns the matched opponent's player ID
fetch('https://yourserver.com/match', { method: 'POST' })
  .then(function(res) { return res.json(); })
  .then(function(match) {
    return FBInstant.overlayViews.createOverlayViewAsync(
      'overlays/opponent_card.xml',
      document.getElementById('opponentContainer'),
      'width: 300px; height: 80px; border: none;',
      'overlays/styles.css',
      { playerID: match.opponentPlayerID }
    );
  });

Next Steps