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 area | Use it for |
|---|---|
| modals | Open a second app view or a focused flow on top of the current app |
| resize | Keep the iframe height in sync with your rendered content |
| fullsize | Expand the app from compact card mode into a larger surface |
| declarative actions | Trigger common SDK actions from HTML without writing much JavaScript |
| bottom sheet | Open 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>
);
}
Modal Helpers
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:
| Action | What it does |
|---|---|
openModal | opens a modal from data-shuuka-* attributes |
closeModal | closes the current modal |
adjustIframeHeight | recalculates the current frame height |
setCardStyle | toggles card style |
openBottomSheet | sends 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
sdkfor UI behavior andshkApifor 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.