Aspect Development
This guide covers the full Aspect development workflow with the CLI: choosing a template or preset, previewing in the OLB playground or a local mock dashboard, and submitting for review.
What Are Aspects?
Aspects are JavaScript files that Candescent dynamically injects into the Digital Banking platform at runtime. They manipulate the page's DOM, add overlays, or integrate third-party services. Aspects support two patterns:
- Context-less — Anonymous Aspects that run without user identity (banners, toasts, modals, vendor loaders)
- Context-aware — Aspects that read session context via
dbk.sessionInfo(), use OIDC, load personalized vendor SDKs, or use the mobile JSBridge token flow
For a closer look at how Aspects work, see the Aspects Overview and the Web Technical Reference sections.
Templates
The CLI ships 15 built-in Aspect templates. Some are web-only or mobile-only; others support both platforms. Run forge aspect templates (optionally with --platform web, --platform mobile, or --context-aware) for the list the CLI will accept today.
Context-less templates
| Template | Platform | Description |
|---|---|---|
banner | Both | Full-width bar with dismiss button — announcements and offers |
toast | Both | Corner popup that auto-dismisses — tips and soft promotions |
card | Both | Floating card with icon, message, and CTA — product highlights |
modal | Both | Centered overlay dialog — important announcements and consent |
countdown | Both | Gradient banner with live countdown timer — flash sales and events |
vendor-script-loader | Both | Single dbk.loadScript() (with host fallback) — chat, engagement, or partner SDKs that self-mount |
vendor-script-with-config | Both | Vendor JS + CSS plus window config globals — patterns like loader + tenant JSON |
tag-manager | Web only | Google Tag Manager bootstrap (dataLayer + script injection) for a container id |
floating-action-button | Both | Fixed-position action button (for example help) that opens a URL in a new tab |
Context-aware templates
| Template | Pattern | Platform | Description |
|---|---|---|---|
welcome-banner | global-variable | Both | Personalized banner using dbk.sessionInfo().userFullName with fallback |
personalized-toast | global-variable | Both | Toast that greets the user by name via session context |
oidc-snippet | oidc | Both | Full OIDC auth scaffold — works with the local OIDC Toolkit or production credentials |
hidden-iframe-sso | global-variable | Both | Hidden iframe SSO handoff with postMessage; optional dbk.isWebview() gate |
vendor-sdk-personalized | global-variable | Web only | Loads a vendor SDK after seeding identity from dbk.sessionInfo() (pre-chat, routing) |
mobile-vendor-chat-jsbridge | jsbridge-token | Mobile only | Mobile WebView: token via native JSBridge, then vendor mobile SDK init |
Browse templates interactively:
forge aspect templates # list all templates
forge aspect templates --id welcome-banner # details for a specific template
forge aspect templates --id banner --preview-code # view the generated JavaScript
forge aspect templates --format ids # one template id per line (for scripts)
forge aspect templates --format preset-ids # one preset id per line
Presets and mock partners
Presets are named bundles of default URLs and options (no real FI or vendor secrets) that map common integration shapes onto generic templates — for example a vendor script loader preset that points at a local mock SDK URL.
- Presets are listed in
forge aspect templatesand enumerated with--format preset-ids. - Use
--preset <id>withforge aspect preview --template <template-id>so the CLI merges preset defaults before your flags and prompts. If a preset does not apply to the chosen template, the CLI exits with an error. - For code preview only, combine
forge aspect templates --id <template> --preset <id> --preview-codeto print generated JavaScript with the preset applied.
Vendor-oriented presets expect a mock partner HTTP server (for example on http://localhost:4011) that serves stub scripts and JSON. The CLI auto-detects a running mock partner when possible; you can also set MOCK_PARTNERS_URL or MOCK_PARTNERS_PORT so previews resolve the right host.
Example preset ids (see the CLI output for the authoritative list): glia, link-live-retail, link-live-business, gtm, iframe-sso, salesforce-chat, five9, acquire, fab-help, mobile-ujet, mobile-salesforce.
forge aspect preview --template vendor-script-loader --preset glia
forge aspect templates --id vendor-script-loader --preset glia --preview-code
Creating an Aspect
Run forge aspect create or forge aspect preview to interactively select a template and enter your message:
forge aspect create
If no template is specified, the CLI prompts you to choose one (or paste custom source code, or open an empty playground).
Previewing an Aspect
OLB Docker Playground (Default)
forge aspect preview --template banner --message 'Summer savings!'
This generates the Aspect JavaScript, starts the OLB Docker playground, registers the Aspect in-memory, and opens the banking shell at http://localhost:4200. Reload the page to see the Aspect.
Local Mock Dashboard
forge aspect preview --template banner --message 'Quick preview' --no-playground
The --no-playground flag starts a lightweight local mock banking dashboard instead of the full Docker environment. This is useful for rapid iteration instead of deploying Docker.
From a File
Preview a hand-written JavaScript file with live reload:
forge aspect preview --code-file ./aspects/my-aspect.js
The preview server watches the file for changes and reloads automatically.
Mobile Preview
forge aspect preview --template banner --message 'Mobile promo' --platform mobile
Mobile Aspects are saved as .html documents and opened in a browser for manual testing. See the Mobile Aspects Technical Reference section for the native bridge API.
Interactive prompting
When you run forge aspect preview without content flags, the CLI prompts for:
- Source — Use a built-in template, load from a JavaScript file, or open the playground shell only (add Aspects manually in the UI)
- Template (when you pick a template) — Choose from the filtered list for your
--platform - Message — Enter copy where the template uses a message (some templates skip this prompt)
Multiline Messages
From bash or zsh, use ANSI-C quoting ($'...') so \n is interpreted as a real newline:
forge aspect preview --template banner --message $'Drive smarter with auto loans.\nLower rates, flexible terms.'
Plain single quotes ('...\n...') pass a literal backslash-n, not a newline. This is a common source of "banner not showing" issues.
OIDC-Authenticated Aspects
The oidc-snippet template scaffolds a complete OIDC authorization code flow:
# Auto-starts the local OIDC Toolkit (zero config)
forge aspect preview --template oidc-snippet
# Production scaffold with real FI credentials
forge aspect preview --template oidc-snippet --client-id my-app --fi-domain acmebank
When the OIDC Toolkit is running (forge oidc up), the CLI auto-detects it, fetches the auto-generated client_id and client_secret, and wires them into the generated snippet.
For the full OIDC integration workflow, see OIDC local development.
Submitting an Aspect
From a Template
forge aspect submit "summer sale" --template banner --message 'Summer savings!' --platform web --wait
From a File
forge aspect submit "summer sale" --code-file ./aspects/summer-sale.js --platform web --wait
Updating an Existing PR
If a submission PR fails checks, edit the file and resubmit to the same PR:
forge aspect submit "summer sale" --code-file ./aspects/summer-sale.js --pr 3 --platform web
Key Submit Flags
| Flag | Description |
|---|---|
--template <id> | Use a built-in template |
--message <text> | Message text for the template (use $'...' for newlines) |
--cta-text <text> | CTA button text (requires --template) |
--cta-url <url> | CTA button URL (requires --template) |
--code-file <path> | Submit from a JavaScript file |
--code <snippet> | Submit an inline JavaScript snippet |
--description <text> | Aspect description (used in the PR body) |
--platform <web|mobile|both> | Target platform (validated against creation-time metadata) |
--iframe / --no-iframe | Render the Aspect in an iframe (default: --iframe) |
--pr <number> | Update an existing PR instead of creating a new one |
--env <env> | Submission environment override |
--force | Skip platform and metadata validation |
--wait | Poll until the GitHub PR is created |
--save / --no-save | Save generated code locally (default: --save) |
Tracking, Publishing, and Deploying
forge submission list # list all submissions
forge submission list --status ALL # include all statuses
forge submission dashboard # aggregated stats
forge submission publish summer-sale-aspect # merge approved PR + trigger CI deploy
forge submission deploy summer-sale-aspect # promote the published Aspect to production
Lifecycle: Submit → PR Created → In Review → Approved → Publish (merge PR + CI deploy) → Deploy (production)
Web vs. Mobile Aspects
| Web | Mobile | |
|---|---|---|
| Format | .js IIFE injected into host page | .html document loaded in a WebView |
| Auth | fetch() + session cookies, or dbk.sessionInfo() | tokenApiDetails native bridge |
| Preview | OLB Docker playground or local mock | HTML opened in browser |
| Submit platform | --platform web | --platform mobile |
Preview flags reference
| Flag | Description |
|---|---|
--platform <web|mobile> | Target platform (default: web) |
--playground / --no-playground | OLB Docker playground (default) or local mock dashboard |
--open / --no-open | Open the OLB shell after registering (playground flows; default: open) |
--pull | Pull fresh Docker images before starting the playground |
--template <id> | Built-in Aspect template |
--preset <id> | Preset bundle (requires --template) |
--message <text> | Template message (use $'...' in bash/zsh for real newlines) |
--cta-text / --cta-url | CTA label and URL when supported |
--client-id <id> | OIDC client ID (for oidc-snippet) |
--fi-domain <domain> | FI domain for OIDC auth URL (for oidc-snippet) |
--code-file <path> | Preview a JavaScript file with live reload |
--code <snippet> | Preview an inline JavaScript snippet |
--save <path> | Custom save path (default: ./aspects/<template>.js) |
--no-save | Do not write generated code to disk |
--port <n> | Mock dashboard port for --no-playground only (default: 3456) |
MOCK_PARTNERS_URL / MOCK_PARTNERS_PORT | Optional; point the CLI at your mock partner server |
Next Steps
- Widget Development — Build and submit widgets
- Command Reference — Full list of Aspect commands and flags
- Troubleshooting — Common Aspect development issues