Skip to content

Resolve Slot Page

The resolveSlotPage.js script is a required file in every extension archive. The platform calls this script each time it needs to render a slot, passing the current slot type, context, and extension settings. The script must return a key from views.pages to tell the platform which HTML page to load — or null to skip rendering.

How It Works

  1. The platform loads your extension for a specific slot.
  2. It calls the default export of resolveSlotPage.js with three arguments.
  3. Your function returns a page key (a string matching a key in views.pages) or null.
  4. If a key is returned, the platform loads the corresponding HTML file into the slot iframe.
  5. If null is returned, the slot is not rendered.

Function Signature

js
export default function resolveSlotPage(slotType, context, extSettings) {
  // return a key from views.pages or null
}

Arguments

ArgumentTypeDescription
slotTypeTV1ExtensionSlotA runtime slot constant indicating which slot is being resolved.
contextTV1ExtContextThe current extension context containing model and/or user objects.
extSettingsunknownExtension settings saved by the model. See Extension Settings.

TV1ExtensionSlot

The slotType argument receives one of the following values:

ConstantCorresponds to manifest slot
EXTENSION_SLOT_MAIN_GAME_FUNmainGameFun
EXTENSION_SLOT_MAIN_SEX_TOYmainSexToy
EXTENSION_SLOT_RIGHT_OVERLAYrightOverlay
EXTENSION_SLOT_MOVEABLE_OVERLAYmoveableOverlay
EXTENSION_SLOT_BACKGROUNDbackground
EXTENSION_SLOT_VIDEO_DECORATIVE_OVERLAYvideoDecorativeOverlay

TV1ExtContext

The extension context contains information about the current model and/or user.

Canonical entity definitions live in the API reference:

If you need to load or track context outside of the resolver, see:

Return Value

The function must return either:

  • A string — a key from views.pages in your manifest. The platform will load the corresponding HTML file.
  • null — the platform will skip rendering for this slot.

If the function throws an error or returns a non-string value, the slot will not be rendered.

Basic Example

Given this manifest:

json
{
  "version": "v2.0",
  "views": {
    "slots": ["EXTENSION_SLOT_MAIN_GAME_FUN", 
            "EXTENSION_SLOT_RIGHT_OVERLAY",
            "EXTENSION_SLOT_BACKGROUND"],
    "pages": {
      "menu": "menu.html",
      "overlay": "overlay.html",
      "background": "background.html"
    },
    "resolveSlotPageScript": "resolveSlotPage.js"
  }
}

A simple resolver that maps each slot to a page:

js
// resolveSlotPage.js

export default function resolveSlotPage(slotType) {
  switch (slotType) {
    case 'EXTENSION_SLOT_MAIN_GAME_FUN':
      return 'menu';
    case 'EXTENSION_SLOT_RIGHT_OVERLAY':
      return 'overlay';
    case 'EXTENSION_SLOT_BACKGROUND':
      return 'background';
    default:
      return null;
  }
}

Context-Aware Example

You can use context to return different pages depending on who is viewing — for example, showing different UI for models and viewers.

Given this manifest:

json
{
  "version": "v2.0",
  "views": {
    "slots": ["EXTENSION_SLOT_MAIN_GAME_FUN",
            "EXTENSION_SLOT_RIGHT_OVERLAY",
            "EXTENSION_SLOT_BACKGROUND"],
    "pages": {
      "model-menu": "model-menu.html",
      "viewer-menu": "viewer-menu.html",
      "model-overlay": "model-overlay.html",
      "viewer-overlay": "viewer-overlay.html",
      "background": "background.html"
    },
    "resolveSlotPageScript": "resolveSlotPage.js"
  }
}
js
// resolveSlotPage.js

export default function resolveSlotPage(slotType, context) {
  const isCurrentUserModel = context.user?.id === context.model?.id;

  if (slotType === 'EXTENSION_SLOT_MAIN_GAME_FUN') {
    return isCurrentUserModel ? 'model-menu' : 'viewer-menu';
  }

  if (slotType === 'EXTENSION_SLOT_RIGHT_OVERLAY') {
    return isCurrentUserModel ? 'model-overlay' : 'viewer-overlay';
  }

  if (slotType === 'EXTENSION_SLOT_BACKGROUND') {
    return 'background';
  }

  return null;
}

In this case, views.pages includes separate page keys for models and viewers — "model-menu" / "viewer-menu" and "model-overlay" / "viewer-overlay" — each pointing to a different HTML file.

Settings-Aware Example

You can use extSettings to conditionally enable or disable slots based on model configuration.

Given this manifest:

json
{
  "version": "v2.0",
  "views": {
    "settings": "settings.html",
    "slots": ["EXTENSION_SLOT_MAIN_GAME_FUN",
            "EXTENSION_SLOT_RIGHT_OVERLAY",
            "EXTENSION_SLOT_BACKGROUND"],
    "pages": {
      "menu": "menu.html",
      "overlay": "overlay.html",
      "background": "background.html"
    },
    "resolveSlotPageScript": "resolveSlotPage.js"
  }
}
js
// resolveSlotPage.js

export default function resolveSlotPage(slotType, context, extSettings) {
  if (slotType === 'EXTENSION_SLOT_MAIN_SEX_TOY') {
    return 'main';
  }

  if (slotType === 'EXTENSION_SLOT_MOVEABLE_OVERLAY') {
    return extSettings?.enableOverlay ? 'overlay' : null;
  }

  if (slotType === 'EXTENSION_SLOT_BACKGROUND') {
    return 'background';
  }

  return null;
}

TIP

Keep the resolver simple and fast. It runs every time the platform needs to resolve a slot, so avoid heavy logic or async operations.