Theme
Ninja editor
The Ninja editor lets you configure the app's appearance and behavior through JSON, including settings that are not available in the standard form, such as menu accent colors, custom icons, the splash screen, and header buttons.
Configuration format
json
{
"CONFIG_VERSION": 1,
"params": {
"NATIVE_NAV_BAR_BG_COLOR": "#FFFFFF",
"NATIVE_NAV_BAR_ACTIVE_ICON_COLOR": "#FFFFFF",
"NATIVE_NAV_BAR_ACCENT_COLOR": "#009966"
}
}Add settings to the existing params object. JSON values override the standard form. To control a setting through the form again, remove it from the JSON and save the configuration.
Parameter names are case-sensitive. JSON does not support comments or trailing commas. The key -SKELETON_BLOCKS does not enable the skeleton: use SKELETON_BLOCKS without the hyphen. Unknown keys do not add new app features.
Menu colors and appearance
| Parameter | Value |
|---|---|
SHOW_NATIVE_NAV_BAR | true to show the menu, false to hide it |
NATIVE_NAV_TYPE_ID | Style number from 1 to 7, as in the “Menu appearance” field |
NATIVE_NAV_BAR_BG_COLOR | Bar background |
NATIVE_NAV_BAR_ICON_COLOR | Inactive icon and label color |
NATIVE_NAV_BAR_ACTIVE_ICON_COLOR | Active icon and label color |
NATIVE_NAV_BAR_ACCENT_COLOR | Accent color for the pill or dot, depending on the style |
Use colors in #RRGGBB format, such as #009966. The active icon color and accent color are independent: you can use a white icon on a green pill. The accent appears in styles 2, 3, 5, and 7; the other styles have no pill or dot.
Styling an individual item
The NATIVE_NAV_BAR array changes the appearance of existing items. It does not add items or set their destinations.
json
{
"CONFIG_VERSION": 1,
"params": {
"NATIVE_NAV_BAR": [
{
"id": "Home",
"icon": "Home",
"color": "#64748B",
"activeColor": "#009966"
}
]
}
}Here, id is the exact item name in the form, such as “Home”, rather than its internal numeric identifier. If you rename the item, update id in the JSON. Items with the same name receive the same override.
| Field | Purpose |
|---|---|
id | Name of the item to apply the settings to |
icon | Standard or custom icon |
color | Inactive icon and label color |
activeColor | Active icon and label color |
activeIcon | Custom SVG icon for the active state |
Missing fields use the shared settings. The current preview does not apply an item's activePillColor; set the accent color through NATIVE_NAV_BAR_ACCENT_COLOR. Changing activeIcon to another standard icon name is also not reflected in the preview — use SVG for a separate active icon.
Custom icons
For icon, you can use a standard icon name:
Home, Search, ShoppingCart, User, Heart, Bell, Grid3X3, Settings, MessageCircleMore, Menu, Percent, Receipt, Tag, Package, Truck, Store.
Custom menu and header icons use SVG in data:image/svg+xml;base64,... format: encode the SVG file contents in Base64 and add this prefix. PNG is suitable for the splash screen, but not for menu or button icons in the current preview.
This example provides a ready-to-use circular SVG icon for the “Home” item:
json
{
"CONFIG_VERSION": 1,
"params": {
"NATIVE_NAV_BAR": [
{
"id": "Home",
"icon": "data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyNCAyNCI+PGNpcmNsZSBjeD0iMTIiIGN5PSIxMiIgcj0iOCIgZmlsbD0ibm9uZSIgc3Ryb2tlPSJjdXJyZW50Q29sb3IiIHN0cm9rZS13aWR0aD0iMiIvPjwvc3ZnPg==",
"color": "#64748B",
"activeColor": "#009966"
}
]
}
}In the SVG, use viewBox and stroke="currentColor" or fill="currentColor" so the settings control its color. The bottom menu recolors the SVG for the current state; a multicolor image may lose its original colors. For header icons, it is especially important to use currentColor in the SVG itself.
Header buttons
HEADER_ACTIONS defines the left and right button arrays. Buttons appear in array order.
json
{
"CONFIG_VERSION": 1,
"params": {
"HEADER_ACTIONS": {
"left": [
{ "icon": "Home", "click": "/" }
],
"right": [
{ "icon": "Bell", "click": "/notifications", "color": "#009966" },
{ "icon": "Search", "click": "js:window.openAppSearch()" }
]
}
}
}| Field | Purpose |
|---|---|
icon | Standard icon name or Base64-encoded SVG |
click | Website path or JavaScript with the js: prefix |
color | Button color; defaults to HEADER_BACK_BUTTON_COLOR |
To run JavaScript in the current preview, place the button in right: js: handlers for left are not yet connected. Regular links work on both sides. Define the example function window.openAppSearch on your website or in “Additional JS” — see Click actions.
The following settings control the bar itself:
| Parameter | Purpose |
|---|---|
HEADER_COLOR | Header background |
HEADER_BACK_BUTTON_COLOR | Shared button color |
SHOW_HEADER_LOGO_TYPE | none, text, or img |
HEADER_TEXT_LOGO | Logo text |
HEADER_TEXT_LOGO_COLOR | Text logo color |
Upload the image logo through the standard form. For the mobile app, use only PNG, JPEG, or WebP: GIF and SVG are not supported by config:sync. The current preview does not use HEADER_LOGO_CLICK; use a separate header button for navigation.
Page titles
HEADER_TITLES changes the app header title based on the current page URL. Add the rules to params in the Ninja editor:
json
{
"CONFIG_VERSION": 1,
"params": {
"HEADER_TITLES": [
{ "url": "/invoice", "title": "Orders" },
{ "url": "/invoice/*", "title": "Order details" },
{ "url": "/profile", "title": "Profile", "exact": false }
]
}
}Use a path from the website root, without a domain, ?query, or #hash. Exact paths, inherited titles, and a trailing /* wildcard are supported. title must be a non-empty string.
| Field | Behavior |
|---|---|
exact: true or omitted | Title applies only to the specified path |
exact: false | Title applies to the specified path and all its child pages |
For example, /profile with exact: false sets “Profile” for /profile, /profile/settings, and /profile/settings/security, but not /profiles. If a child page has its own matching rule, that rule is used. The rule / with exact: false sets a shared title for all website pages.
exact accepts only the JSON values true and false, without quotes. For the /invoice/* wildcard, this flag does not change the behavior: the wildcard covers only child paths, excluding /invoice itself.
| Current page | Title |
|---|---|
/invoice or /invoice/?sort=date | Orders |
/invoice/42 or /invoice/42/edit | Order details |
/profile#settings or /profile/settings/security | Profile |
/catalog | Default logo or text from the header settings |
An exact rule (exact: true or no exact field) takes priority over inheritance and wildcards, regardless of order. Among matching exact: false rules and wildcards, the longest prefix wins: /invoice/paid/* takes priority over /invoice/*. The /invoice/* wildcard excludes /invoice itself and the neighboring path /invoices. A trailing / does not affect matching; paths are case-sensitive. If rules have equal specificity, the first one is used.
When a rule matches, the image logo is temporarily hidden and the title text appears. In text mode, the text changes; in none mode, a title still appears for a matching page. The title uses HEADER_TEXT_LOGO_COLOR and the header's standard bold font. Long titles are truncated to one line. If no rule matches, the original header appearance returns.
The title updates in the mobile app and builder preview during regular navigation, redirects, back navigation, and SPA navigation through the History API. Query parameters and fragments do not affect the rule. Inheritance depends on the current URL, not browsing history: opening a child page directly or from a push notification gives the same title. Routes stored only in #hash are not supported.
To disable this feature, remove HEADER_TITLES or set it to an empty array []. After changing it for the mobile app, create a new release configuration revision, run config:sync, and rebuild the app.
Splash screen
The splash screen is shown when the app starts, before the website appears.
| Parameter | Purpose |
|---|---|
SPLASH_SCREEN_BG | Background color; the preview defaults to HEADER_COLOR |
SPLASH_SCREEN_IMG | Splash image in PNG, JPEG, or WebP format, as a URL or Data URL |
json
{
"CONFIG_VERSION": 1,
"params": {
"SPLASH_SCREEN_BG": "#FFFFFF",
"SPLASH_SCREEN_IMG": "https://example.com/splash.png"
}
}Replace the example URL with your image URL or a complete data:image/png;base64,... string. Do not leave the ellipsis in the actual image string. Mobile builds support only PNG, JPEG, and WebP; GIF and SVG may appear in the browser preview, but config:sync does not accept them.
If SPLASH_SCREEN_BG and SPLASH_SCREEN_IMG are set both in the builder and in NinjaEditor's params, the NinjaEditor values are used when creating the release configuration. After changing them, create a new configuration revision, run config:sync in the mobile project, and rebuild the app. On iOS, the image appears at startup; Android keeps the system splash screen with the icon on a white background.
Without SPLASH_SCREEN_IMG, the preview shows the image logo if it is enabled and uploaded; otherwise, it shows the app icon. Reload the builder page to see the splash screen again.
Page loading
The startup splash screen and page loading animation are configured separately.
| Parameter | Purpose |
|---|---|
SHOW_LOADING_PROGRESS | Enable the progress bar with true or false |
LOADING_PROGRESS_COLOR | Bar color |
LOADING_PROGRESS_BG_COLOR | Bar background |
SHOW_LOADING_SKELETON | Enable the loading animation with true or false |
LOADING_SKELETON | skeleton for placeholders, box-spinner for a block with a spinner |
LOADING_SKELETON_SPINNER_BG_COLOR | Spinner block background |
LOADING_SKELETON_SPINNER_COLOR | Spinner color |
LOADING_SKELETON_SPINNER_ICON | Spinner icon, such as spinner-2 |
SKELETON_BLOCKS | Array of skeleton blocks in display order |
json
{
"CONFIG_VERSION": 1,
"params": {
"SHOW_LOADING_SKELETON": true,
"LOADING_SKELETON": "skeleton",
"SKELETON_BLOCKS": ["CAROUSEL", "TEXT", "CARD_GRID", "SPACER_BOTTOM"]
}
}Available blocks:
| Blocks | What they represent |
|---|---|
HEADER, BACK_BAR, SECTION_TITLE | Header, back bar, section title |
SEARCH_FORM, FILTER_BAR, TABS, CHIPS | Search, filters, tabs, tags |
HERO, CAROUSEL | Large introductory block, carousel |
TEXT, TEXT_IMG | Text, text with an image |
CARD, CARD_LIST, CARD_GRID | Card, card list, card grid |
LIST, TABLE | List, table |
BOTTOM_TABBAR, SPACER_BOTTOM | Bottom bar, bottom spacing |
SKELETON_BG, SKELETON_BLOCK_COLOR, SKELETON_BORDER_COLOR, and PRELOADER do not control the current browser preview. A key's presence in the JSON does not confirm that it is applied.