Skip to main content

App SDK UI Helpers

Use the Shuuka SDK for embed behavior such as modals, bottom sheets, height updates, and fullsize transitions. Use shkApi for data and storage. Use the SDK for UI behavior.

Important scope note:

  • this page documents the iframe app SDK runtime used by Simple, Smart, and marketplace app surfaces
  • first-party Native apps mounted directly into the public profile DOM do not automatically receive this SDK UI surface
  • if a Native app needs modal or fullsize behavior today, implement it in the Native app itself unless the platform explicitly exposes a shared host bridge for Native mounts

What This Page Covers

Helper areaUse it for
modalsOpen a second app view or a focused flow on top of the current app
resizeKeep the iframe height in sync with your rendered content
fullsizeExpand the app from compact card mode into a larger surface
declarative actionsTrigger common SDK actions from HTML without writing much JavaScript
bottom sheetOpen a platform-managed mobile-style sheet from a simple or smart app

React Starting Point

For React apps, import the provider and read the SDK from useShuuka():

import { HashRouter } from 'react-router-dom';
import { ShuukaProvider, useShuuka } from '@shuuka/sdk/index.sdk.js';

function AppContent() {
const { sdk, uiState } = useShuuka();

return (
<button onClick={() => sdk?.openModalRoute?.('/details', { title: 'Details' })}>
Open details
</button>
);
}

export default function App() {
return (
<HashRouter>
<ShuukaProvider autoResize={false}>
<AppContent />
</ShuukaProvider>
</HashRouter>
);
}

Use a modal when the current app should open a focused secondary view without leaving the installed app.

Open a built URL

const baseUrl = window.location.href.split('#')[0];
sdk.openModal(`${baseUrl}#/newpage`, 'Developer Guide', 'default');

Open a route inside the current bundle

openModalRoute() is the cleanest option for React apps that already use a hash router.

sdk.openModalRoute('/ask', {
title: 'Ask OpenAI',
fullscreen: true,
query: { source: 'app-card' }
});

Open a modal with an options object

sdk.openModal({
route: '#/settings',
title: 'Settings',
mode: 'default',
query: { tab: 'privacy' }
});

Close the current modal

sdk.closeModal();

Read modal state

In React:

const { uiState } = useShuuka();

if (uiState?.isOpen) {
console.log('This app is inside an open modal');
}

Resize Helpers

If your app content changes height after render, update the host so the app frame stays correct.

Re-measure from the current DOM

sdk.updateHeight();

Use this after state changes such as:

  • opening or closing an inline form
  • showing validation or success messages
  • loading async content
  • changing tabs or accordions

Set an explicit height

sdk.uiSafe.setHeight(640, true);

Use an explicit height when the app has a known compact or expanded state.

Toggle auto resize

sdk.enableResize(true);

Safe wrapper:

sdk.uiSafe.enableResize(true);

Fullsize Helpers

Use fullsize when a compact card should grow into a larger app surface.

Expand to fullsize

sdk.uiSafe.expandFullsize();

Read fullsize state

const { uiState } = useShuuka();

if (uiState?.isFullsize) {
console.log('The app is in fullsize mode');
}

Declarative HTML Actions

Simple and smart HTML apps can use SDK UI actions without writing custom listeners for every button.

<button
data-shuuka-action="openModal"
data-shuuka-url="public/result.html"
data-shuuka-title="View result"
data-shuuka-mode="default">
Open result
</button>

<button
data-shuuka-action="adjustIframeHeight">
Recalculate height
</button>

If your app adds new DOM after load, call:

sdk.rebindActions();

Supported public patterns worth using:

ActionWhat it does
openModalopens a modal from data-shuuka-* attributes
closeModalcloses the current modal
adjustIframeHeightrecalculates the current frame height
setCardStyletoggles card style
openBottomSheetsends the bottom-sheet open event for simple and smart apps

Bottom Sheet Pattern

Bottom sheet is a platform-managed mobile-style sheet. Use it when the app should open a focused form or gate in a sheet instead of expanding inline.

This pattern is mainly for simple and smart HTML apps.

Manifest requirement

If your app supports this behavior, declare bottom_sheet_contract in manifest.json. Read App Manifest.

Open the bottom sheet

window.parent.postMessage({
type: 'SHUUKA_APP_BOTTOM_SHEET',
appId: String(window.__shuukaCtx?.billboardAppId || ''),
action: 'open',
state: 'form',
height: 560
}, '*');

Close the bottom sheet

window.parent.postMessage({
type: 'SHUUKA_APP_BOTTOM_SHEET',
appId: String(window.__shuukaCtx?.billboardAppId || ''),
action: 'done'
}, '*');

HTML trigger version

<button
data-shuuka-action="openBottomSheet"
data-shuuka-app-id="{{app_id}}"
data-shuuka-state="form"
data-shuuka-height="560">
Open form
</button>

Sheet instance rule

When the platform opens the sheet, it reloads the app in sheet mode. Your app should detect the bottom-sheet query parameter and render the sheet content directly instead of the normal trigger card.

Use bottom_sheet_contract to describe that behavior clearly for review and maintenance.

Builder Rules

  • Do not hardcode internal platform routes for UI flows.
  • Use sdk for UI behavior and shkApi for data operations.
  • Use openModalRoute() for React hash-router flows.
  • Call updateHeight() after every meaningful layout change.
  • Use bottom sheet only when the app genuinely needs a focused overlay flow.