Appearance
Creative-Engine ↔ Application-Frontend Integration Guide
This document explains how Creative-Engine and Application-Frontend integrate, including local development setup, block registration, and common workflows.
Full Local Development Setup
Prerequisites
- Pull latest version of all repositories from main branch
- PostgreSQL Database: Set up local PostgreSQL using Postico 2 with credentials from Backend
.env:bashDB_CONNECTION=pg PG_HOST=localhost PG_PORT=5432 PG_USER=nicolay PG_PASSWORD= PG_DB_NAME=cavai_backend
Package.json Configuration
Set file paths in package.json for local development in all three repositories (Application-Frontend, Creative-Engine, and Application-Backend):
json
{
"dependencies": {
"@cavai/creative-engine": "file:../Creative-Engine",
"@cavai/creative-composer": "file:../Creative-Composer"
}
}Important: These local file paths must be set in dependencies for all three repos to ensure correct parsing through the Composer.
Quick Setup with Git Stash
Create a named stash for local development paths:
bash
git stash push -m "local-dev-paths" package.json package-lock.jsonApply local development paths when needed:
bash
git stash apply stash^{/local-dev-paths}Reset to normal package versions:
bash
git checkout package.json package-lock.jsonGit Aliases for Quick Switching
Create aliases (one-time setup):
bash
git config --global alias.local-dev '!git stash apply stash^{/local-dev-paths}'
git config --global alias.reset-deps '!git checkout package.json package-lock.json'Quick switching:
bash
git local-dev # Activate local paths
git reset-deps # Reset to normal package versionsStartup Sequence
After setting up local package paths:
Install Creative-Composer locally in Creative-Engine and Application-Frontend:
bashnpm i ../Creative-ComposerStart Creative-Engine with hot reload:
bashnpm run watchStart Application-Backend:
bashnpm run devStart Application-Frontend:
bashnpm run dev
Troubleshooting Local Development
When Application-Backend doesn't work:
bash
npx @cavai/creative-composer ci -e ../Creative-EngineThis reloads dependencies and is especially needed after publishing/deleting creatives.
Overview
- Blocks vs Operators: Builder Visuals uses blocks (e.g.,
textProperties,sliderProperties,formProperties) rendered by CE and configured in AF. Conversation flow uses operators (Composer), which is separate. - Glue: CC compresses/remaps creative data and produces build artifacts consumed by AB (stub.js, creative-engine.js). AF is the authoring UI; CE is the renderer.
- Reload Composer deps when Backend acts up
- From
Application-Backend/:npx @cavai/creative-composer ci -e ../Creative-Engine - This refreshes CC’s view of CE after changes or creative deletions.
- From
Implementing/Updating Blocks
To add or change blocks, you must touch both AF and CE.
Register Block Types
- AF:
src/pages/Chatbots/components/BuilderVisuals/constants/blocks.ts - CE:
src/utils/constants.ts(include inBLOCKS)
- AF:
Visual Elements vs Specialized Blocks
- Visual Elements (Text/Graphic/HTML/Button): rendered via
CreativeVisualElements.vueand must be inVISUAL_ELEMENTS. - Specialized Blocks (Video/Slider/Conversation/Form): dedicated CE components imported in
CreativeBody.vue; do NOT add toVISUAL_ELEMENTS.
- Visual Elements (Text/Graphic/HTML/Button): rendered via
AF Tasks
- Defaults:
Blocks/data/defaults.ts - Types:
Blocks/data/types.ts - Config UI:
Configuration/configs/<Block>Configuration.vue - Add option in
AddBlockTool.vue - i18n entries in
assets/i18n/en.js
- Defaults:
CE Tasks
- Interfaces:
src/payload-v2/index.tsand updateCreativeBlocksinterface - Rendering component: e.g.,
src/components/creative/Creative<YourBlock>/... - For specialized blocks: subblock handling via utils (see below)
- Build CE after changes:
npm run build:library
- Interfaces:
Subblock Handling Pattern
- Create a utility in CE (e.g.,
blockUtils.ts) to extract subblocks from the parent block and sort byorder(e.g.,getFormInputBlocks, similar to slider). - Ensure subblocks have:
blockName,blockType,parent,order,displayName,isSubBlock: true. - For duplication/uniqueness, mirror slider’s approach to avoid name collisions.
- Create a utility in CE (e.g.,
Build Pipeline and Artifacts
CC drives builds; AB stores outputs.
Artifacts location
Application-Backend/tmp/creatives/assets/creatives/[creative-id]/built/assets/creative-engine.js— entire CE bundlebuilt/assets/stub.js— main compiled creative entrycreative.json— full creative datalog.txt— composer build logstag.html— embedding tag
Debugging order
- Inspect
creative-engine.js(components registered?) - Inspect
stub.js - Read
log.txtfor CC messages - Check
creative.jsonstructure - Verify
tag.html
- Inspect
Common Pitfalls
- Forgetting CE build: After CE code changes, run
npm run build:librarybefore testing in AF/AB. - Incorrect block registration: Missing entries in AF/CE block constants cause invisible/non-rendered blocks.
- Wrong blockName: Visual elements’
blockNamemust contain a VISUAL_ELEMENTS string; specialized blocks use static keys (e.g.,formProperties). - Missing i18n: Hardcoded strings — ensure everything goes into
en.js. - Composer cache/staleness: If AB builds don’t reflect changes, run
npx @cavai/creative-composer ci -e ../Creative-Enginefrom AB.
Workflow Cheatsheet
- Implement/modify block in AF and CE
- Build CE:
npm run build:library - In CC/AB environment, refresh deps:
npx @cavai/creative-composer ci -e ../Creative-Engine - Publish creative and verify artifacts in AB
tmp/creatives/... - If issues, diff structure against a working block (e.g., slider) and check subblock utilities
Troubleshooting
- Preview mismatch (local vs full): Validate that all style properties exist and are applied consistently; compare to slider rendering.
- Serialization errors: Ensure subblock uniqueness and proper references (avoid duplicate definitions; store references by
blockNamearrays when appropriate). - Missing context menu options: Add block type to
isDeletablein AFutils.ts. - Backend not updating: Clear old creative under AB
tmp/creatives/...and republish if needed.
Preview fails due to component <style> blocks (scoped)
- Symptom: Published preview fails to render the Form block; inspecting shows selectors like
form-block-wrap[...(Vue adds attribute selectors for scoped styles). - Cause: A
<style>(especially withscoped) at the bottom of a CE component (e.g.,CreativeFormBlock.vue) conflicted with the engine’s injected CSS. CE already injects CSS viaStyleAndClassNameGenerationMixin; an extra<style>can override or break selectors in the built preview. - Fix: Remove the component
<style>block (or at least removescopedand conflicting rules). Prefer relying on the mixin-injected CSS fromstyles. - Debug path used:
- Saw selector with
[in DevTools (Vue scoped attribute). - Removed
scoped→ same issue. - Removed the entire
<style>block → preview started working.
- Saw selector with
Real-time Updates Limitation
Architecture Issue
Application-Frontend and Creative-Engine run in separate contexts:
- Application-Frontend: Main window with Vue/Vuex store
- Creative-Engine: Runs inside iframe with isolated DataStore
Current Behavior
- Configuration changes in Application-Frontend are saved correctly
- Changes don't reflect in real-time in Creative-Engine preview
- Preview updates require iframe reload or creative republish
Root Cause
Creative-Engine's DataStore.creativeSettings is isolated from Application-Frontend's Vuex store. The iframe boundary prevents automatic reactivity between the two systems.
Communication Methods
Data passes between contexts via:
postMessageAPI (seen inPreviewIframe.vue)- iframe src URL parameters
- Creative republishing process
Workaround
For immediate preview updates, manually reload the preview iframe or republish the creative. Configuration changes are always saved correctly in the backend.
Future Solution
Implementing real-time cross-iframe communication would require:
- postMessage listeners in Creative-Engine
- Change detection in Application-Frontend
- Selective data synchronization mechanism
Reference Files
- AF:
AddBlockTool.vue,CreativeBody.vue,CreativeVisualElements.vue,Blocks/data/defaults.ts,Blocks/data/types.ts,assets/i18n/en.js - CE:
src/components/creative/**,src/utils/constants.ts,src/payload-v2/index.ts,blockUtils.ts - CC:
src/bin/composer.ts(debug entry),src/remapper/* - AB:
tmp/creatives/assets/creatives/[id]/*