@embeddables/cli 0.11.0 → 0.12.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.prompts/custom/build-funnel.md +1 -1
- package/.prompts/embeddables-cli.md +245 -26
- package/dist/cli.js +240 -1
- package/dist/cli.js.map +1 -1
- package/dist/commands/init.d.ts.map +1 -1
- package/dist/commands/init.js +26 -1
- package/dist/commands/init.js.map +1 -1
- package/dist/compiler/reverse.d.ts.map +1 -1
- package/dist/compiler/reverse.js +19 -6
- package/dist/compiler/reverse.js.map +1 -1
- package/package.json +1 -1
|
@@ -2,7 +2,7 @@ We need to build the pages from the attached images. Please create a plan and hi
|
|
|
2
2
|
|
|
3
3
|
Embeddable ID: <EMBEDDABLE_ID>
|
|
4
4
|
|
|
5
|
-
Important: Always read the Embeddables CLI context before starting (e.g. @.cursor/rules/embeddables-cli.md, @.claude/embeddables-cli.md,
|
|
5
|
+
Important: Always read the Embeddables CLI context before starting (e.g. @.cursor/rules/embeddables-cli.md, @.claude/embeddables-cli.md, @AGENTS.md, or @.agent/rules/embeddables-cli.md depending on your editor).
|
|
6
6
|
|
|
7
7
|
[KEEP / REMOVE]
|
|
8
8
|
Use the designs from the images but use the content from the attached document instead, and build out the pages based on that content. Therefore, when using the designs from the images, for each page just find the most relevant design for the page's content and design it based on that. However, don't be confined to the provided designs - just find the closest design and modify it to fit the content required.
|
|
@@ -7,7 +7,9 @@ alwaysApply: true
|
|
|
7
7
|
|
|
8
8
|
This document provides comprehensive context for Cursor AI when working with Embeddables in the CLI codebase. The CLI transforms Embeddable JSON into a local file structure for development, then compiles it back to JSON for saving.
|
|
9
9
|
|
|
10
|
-
|
|
10
|
+
## Types as Source of Truth (MANDATORY)
|
|
11
|
+
|
|
12
|
+
**Always consult `.types/` before adding, modifying, or using component props, Flow properties, or any API.** The types are the authoritative source of truth.
|
|
11
13
|
|
|
12
14
|
## Overview
|
|
13
15
|
|
|
@@ -498,13 +500,17 @@ Computed fields are stored in `Flow.computedFields` and transform to JS files. T
|
|
|
498
500
|
|
|
499
501
|
**File Mapping**: `computed-fields/{key}.js` (e.g., `computed-fields/total_price.js`)
|
|
500
502
|
|
|
501
|
-
**Code Structure**: The `code` property contains JavaScript that must include a function called `result`
|
|
503
|
+
**Code Structure**: The `code` property contains JavaScript that must include a function called `result`. The runtime passes a `context` object as the first argument:
|
|
502
504
|
|
|
503
505
|
```javascript
|
|
504
|
-
function result() {
|
|
506
|
+
function result(context) {
|
|
505
507
|
// Access user data via global userData object
|
|
506
508
|
const price = userData.price || 0
|
|
507
509
|
const quantity = userData.quantity || 0
|
|
510
|
+
|
|
511
|
+
// context.triggerContext is available (see Actions section for shape)
|
|
512
|
+
// context.trackCustomEvent(name, props) can track analytics events
|
|
513
|
+
|
|
508
514
|
return price * quantity
|
|
509
515
|
}
|
|
510
516
|
```
|
|
@@ -515,6 +521,7 @@ function result() {
|
|
|
515
521
|
- The function has access to a global `userData` object containing all user data
|
|
516
522
|
- If `async` is true, the function can return a Promise
|
|
517
523
|
- `input_triggers` specify additional keys that trigger recalculation
|
|
524
|
+
- The `context` parameter provides `triggerContext` and `trackCustomEvent()` — same as actions (see "Trigger Context" and "Custom Event Tracking" under Actions)
|
|
518
525
|
|
|
519
526
|
## Actions Structure
|
|
520
527
|
|
|
@@ -529,14 +536,20 @@ Actions are stored in `Flow.dataOutputs` and transform to JS files. The `Action`
|
|
|
529
536
|
|
|
530
537
|
**File Mapping**: `actions/{name}.js` (e.g., `actions/submit_form.js`)
|
|
531
538
|
|
|
532
|
-
**Code Structure**: For `output: "custom"`, the `code` property contains JavaScript that must include a function called `output
|
|
539
|
+
**Code Structure**: For `output: "custom"`, the `code` property contains JavaScript that must include a function called `output`. The runtime passes a `context` object as the first argument:
|
|
533
540
|
|
|
534
541
|
```javascript
|
|
535
|
-
function output() {
|
|
542
|
+
function output(context) {
|
|
536
543
|
// Access user data via global userData object
|
|
537
544
|
const email = userData.email
|
|
538
545
|
const name = userData.name
|
|
539
546
|
|
|
547
|
+
// context.triggerContext contains metadata about what fired this action (see below)
|
|
548
|
+
const trigger = context.triggerContext
|
|
549
|
+
|
|
550
|
+
// Track a custom analytics event (in-action usage)
|
|
551
|
+
context.trackCustomEvent('form_submitted', { email })
|
|
552
|
+
|
|
540
553
|
// Perform action (API call, data transformation, etc.)
|
|
541
554
|
return {
|
|
542
555
|
success: true,
|
|
@@ -547,10 +560,195 @@ function output() {
|
|
|
547
560
|
|
|
548
561
|
**Important**:
|
|
549
562
|
|
|
550
|
-
- Actions are triggered by
|
|
563
|
+
- Actions are triggered by `outputs_on*` fields (see "Action Trigger Wiring" below) or programmatically
|
|
551
564
|
- The function has access to a global `userData` object
|
|
565
|
+
- The `context` parameter provides `triggerContext` and `trackCustomEvent` (see below)
|
|
552
566
|
- For non-custom actions (airtable, hubspot, etc.), the action configuration is stored in config.json, not in the JS file
|
|
553
567
|
|
|
568
|
+
### Action Trigger Wiring (`outputs_on*` Fields)
|
|
569
|
+
|
|
570
|
+
Actions are wired to events via `outputs_on*` properties. Each property holds an **action ID** (string) or an **array of action IDs** (`string[]`) referencing entries in `dataOutputs`. When the event fires, the engine runs the referenced actions.
|
|
571
|
+
|
|
572
|
+
#### Flow-Level Triggers
|
|
573
|
+
|
|
574
|
+
These are top-level properties on the `Flow` object (stored in `config.json`):
|
|
575
|
+
|
|
576
|
+
| Field | Type | Fires when |
|
|
577
|
+
| ---------------------- | -------------------- | ---------------------------------------------- |
|
|
578
|
+
| `outputs_onloadflow` | `string \| string[]` | The embeddable script loads and initializes |
|
|
579
|
+
| `outputs_onviewflow` | `string \| string[]` | The embeddable becomes visible in the viewport |
|
|
580
|
+
| `outputs_onremoved` | `string[]` | The embeddable is removed from the DOM |
|
|
581
|
+
| `outputs_onopenpopup` | `string \| string[]` | A popup embeddable is opened |
|
|
582
|
+
| `outputs_onclosepopup` | `string \| string[]` | A popup embeddable is closed |
|
|
583
|
+
|
|
584
|
+
#### Page-Level Triggers
|
|
585
|
+
|
|
586
|
+
These are properties on `FlowPage` objects (stored in the page entry in `config.json`):
|
|
587
|
+
|
|
588
|
+
| Field | Type | Fires when |
|
|
589
|
+
| ------------------------- | -------------------- | ---------------------------------------------------------- |
|
|
590
|
+
| `outputs_oncomplete` | `string \| string[]` | The user completes this page (i.e. moves to the next page) |
|
|
591
|
+
| `outputs_onload` | `string \| string[]` | The page is loaded / navigated to |
|
|
592
|
+
| `outputs_onopen_infobox` | `string[]` | An info box on this page is opened |
|
|
593
|
+
| `outputs_onclose_infobox` | `string[]` | An info box on this page is closed |
|
|
594
|
+
|
|
595
|
+
#### Component-Level Triggers
|
|
596
|
+
|
|
597
|
+
These are properties on component objects (written as props in React/TSX files):
|
|
598
|
+
|
|
599
|
+
**Base (all components)**:
|
|
600
|
+
|
|
601
|
+
| Field | Type | Fires when |
|
|
602
|
+
| ---------------------------- | ---------- | ------------------------------------ |
|
|
603
|
+
| `outputs_onmounted` | `string[]` | The component mounts in the DOM |
|
|
604
|
+
| `outputs_onunmounted` | `string[]` | The component unmounts from the DOM |
|
|
605
|
+
| `outputs_onrepeatablerender` | `string[]` | A repeater re-renders this component |
|
|
606
|
+
|
|
607
|
+
**CustomButton**:
|
|
608
|
+
|
|
609
|
+
| Field | Type | Fires when |
|
|
610
|
+
| ----------------- | -------------------- | --------------------- |
|
|
611
|
+
| `outputs_onclick` | `string \| string[]` | The button is clicked |
|
|
612
|
+
|
|
613
|
+
**InputBox**:
|
|
614
|
+
|
|
615
|
+
| Field | Type | Fires when |
|
|
616
|
+
| ------------------ | ---------- | ----------------------- |
|
|
617
|
+
| `outputs_onchange` | `string[]` | The input value changes |
|
|
618
|
+
|
|
619
|
+
**OptionSelector**:
|
|
620
|
+
|
|
621
|
+
| Field | Type | Fires when |
|
|
622
|
+
| ----------------------------------- | ---------- | ------------------------------ |
|
|
623
|
+
| `outputs_onchange` | `string[]` | The selected option(s) change |
|
|
624
|
+
| `outputs_onbuttonsrepeatablerender` | `string[]` | The button repeater re-renders |
|
|
625
|
+
|
|
626
|
+
**FileUpload**:
|
|
627
|
+
|
|
628
|
+
| Field | Type | Fires when |
|
|
629
|
+
| ------------------ | ---------- | ----------------------------- |
|
|
630
|
+
| `outputs_onchange` | `string[]` | Files are uploaded or removed |
|
|
631
|
+
|
|
632
|
+
**Payment Components** (StripeCheckout2, PaypalCheckout):
|
|
633
|
+
|
|
634
|
+
| Field | Type | Fires when |
|
|
635
|
+
| ------------------------------ | -------- | ---------------------------------- |
|
|
636
|
+
| `on_payment_complete_outputs` | `string` | Payment succeeds |
|
|
637
|
+
| `on_payment_failed_outputs` | `string` | Payment fails (Stripe only) |
|
|
638
|
+
| `on_payment_attempted_outputs` | `string` | Payment is attempted (Stripe only) |
|
|
639
|
+
|
|
640
|
+
#### Example: Wiring an Action to a Button Click
|
|
641
|
+
|
|
642
|
+
```tsx
|
|
643
|
+
<CustomButton
|
|
644
|
+
id="comp_0000000001"
|
|
645
|
+
key="submit_button"
|
|
646
|
+
text="Submit"
|
|
647
|
+
action="no-action"
|
|
648
|
+
outputs_onclick={['action_1234567890']}
|
|
649
|
+
/>
|
|
650
|
+
```
|
|
651
|
+
|
|
652
|
+
Where `action_1234567890` is the `id` of an action in `dataOutputs`. The button's built-in `action` prop (`"next-page"`, `"prev-page"`, etc.) handles navigation; `outputs_onclick` fires separate data actions.
|
|
653
|
+
|
|
654
|
+
#### Example: Wiring an Action to Page Completion
|
|
655
|
+
|
|
656
|
+
In `config.json`:
|
|
657
|
+
|
|
658
|
+
```json
|
|
659
|
+
{
|
|
660
|
+
"pages": [
|
|
661
|
+
{
|
|
662
|
+
"id": "page_0000000001",
|
|
663
|
+
"key": "contact_page",
|
|
664
|
+
"outputs_oncomplete": ["action_1234567890"]
|
|
665
|
+
}
|
|
666
|
+
]
|
|
667
|
+
}
|
|
668
|
+
```
|
|
669
|
+
|
|
670
|
+
### Programmatic Action Triggering
|
|
671
|
+
|
|
672
|
+
You can trigger an Action from code by doing this:
|
|
673
|
+
|
|
674
|
+
```javascript
|
|
675
|
+
window.Savvy.triggerAction(embeddableId, actionId)
|
|
676
|
+
```
|
|
677
|
+
|
|
678
|
+
### Trigger Context (`triggerContext`)
|
|
679
|
+
|
|
680
|
+
When the engine fires an action, it passes a `context` object to the `output(context)` function. `context.triggerContext` contains metadata about what triggered the action:
|
|
681
|
+
|
|
682
|
+
| Field | Type | Description |
|
|
683
|
+
| -------------- | --------------------- | --------------------------------------------------------------------------------------------------------------------------------- |
|
|
684
|
+
| `triggerType` | `string` | The event type that fired the action (e.g. `"onclick"`, `"onchange"`, `"oncomplete"`, `"onloadflow"`, `"onviewflow"`, `"manual"`) |
|
|
685
|
+
| `componentId` | `string \| undefined` | The component ID that fired the trigger (for component-level triggers) |
|
|
686
|
+
| `componentKey` | `string \| undefined` | The component key that fired the trigger |
|
|
687
|
+
| `pageId` | `string \| undefined` | The page ID associated with the trigger |
|
|
688
|
+
| `pageKey` | `string \| undefined` | The page key associated with the trigger |
|
|
689
|
+
|
|
690
|
+
Example usage inside an action:
|
|
691
|
+
|
|
692
|
+
```javascript
|
|
693
|
+
function output(context) {
|
|
694
|
+
const { triggerType, componentKey, pageKey } = context.triggerContext || {}
|
|
695
|
+
|
|
696
|
+
if (triggerType === 'oncomplete' && pageKey === 'checkout_page') {
|
|
697
|
+
// Only run full submission on checkout page completion
|
|
698
|
+
return submitOrder(userData)
|
|
699
|
+
}
|
|
700
|
+
|
|
701
|
+
// For other triggers, just track progress
|
|
702
|
+
return { tracked: true }
|
|
703
|
+
}
|
|
704
|
+
```
|
|
705
|
+
|
|
706
|
+
Computed fields also receive `context` in the `result(context)` function with the same `triggerContext` shape, which is useful for computed fields that need to behave differently based on what triggered their recalculation.
|
|
707
|
+
|
|
708
|
+
### Custom Event Tracking
|
|
709
|
+
|
|
710
|
+
Embeddables support tracking custom analytics events. There are two contexts where you can track events:
|
|
711
|
+
|
|
712
|
+
#### 1. Inside Action or Computed Field Code (Runtime Context)
|
|
713
|
+
|
|
714
|
+
Use `context.trackCustomEvent(eventName, eventProps)` inside `output()` or `result()` functions:
|
|
715
|
+
|
|
716
|
+
```javascript
|
|
717
|
+
function output(context) {
|
|
718
|
+
const plan = userData.selected_plan
|
|
719
|
+
|
|
720
|
+
// Track a custom event from within an action
|
|
721
|
+
context.trackCustomEvent('plan_selected', {
|
|
722
|
+
plan: plan,
|
|
723
|
+
price: userData.plan_price,
|
|
724
|
+
})
|
|
725
|
+
|
|
726
|
+
return { success: true }
|
|
727
|
+
}
|
|
728
|
+
```
|
|
729
|
+
|
|
730
|
+
#### 2. From the Host Page (Window API)
|
|
731
|
+
|
|
732
|
+
Use `window.Savvy.trackCustomEvent(flowId, eventName, eventProps)` from the host page embedding the embeddable:
|
|
733
|
+
|
|
734
|
+
```javascript
|
|
735
|
+
window.Savvy.trackCustomEvent('flow_abc123', 'external_checkout_complete', {
|
|
736
|
+
orderId: '12345',
|
|
737
|
+
total: 99.99,
|
|
738
|
+
})
|
|
739
|
+
```
|
|
740
|
+
|
|
741
|
+
- `flowId` — the embeddable's `id`
|
|
742
|
+
- `eventName` — a custom event name string
|
|
743
|
+
- `eventProps` — an object of key-value pairs to attach to the event
|
|
744
|
+
|
|
745
|
+
#### When to Use Which
|
|
746
|
+
|
|
747
|
+
| Context | API | Use when |
|
|
748
|
+
| ------------------------------ | ---------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
749
|
+
| Inside `output()` / `result()` | `context.trackCustomEvent(name, props)` | Tracking events as part of action/computed field logic (e.g. after a form submission, when a computed value changes) |
|
|
750
|
+
| Host page JS | `window.Savvy.trackCustomEvent(flowId, name, props)` | Tracking events from outside the embeddable (e.g. after an external checkout, on a parent SPA route change, from a third-party integration callback) |
|
|
751
|
+
|
|
554
752
|
## Conditions Structure
|
|
555
753
|
|
|
556
754
|
Conditions control visibility of components and pages based on User Data. The `Condition`, `ConditionOperator`, `ConditionValue`, and `ConditionalTag` types are defined in `src/types-builder.ts`.
|
|
@@ -601,6 +799,7 @@ The `config.json` file contains the reduced Embeddable JSON with:
|
|
|
601
799
|
- Style selectors but NOT style values (styles are in CSS files)
|
|
602
800
|
- Computed field metadata (id, key, inputs, etc.) but NOT code (code is in JS files)
|
|
603
801
|
- Action metadata (id, name, output, mappings, etc.) but NOT code (code is in JS files)
|
|
802
|
+
- `_docs` (string) — preserved at top-level, in pages, computedFields, and dataOutputs
|
|
604
803
|
- All other Flow properties (experiments, transitions, settings, etc.)
|
|
605
804
|
|
|
606
805
|
**Example config.json structure**:
|
|
@@ -643,6 +842,22 @@ The `config.json` file contains the reduced Embeddable JSON with:
|
|
|
643
842
|
}
|
|
644
843
|
```
|
|
645
844
|
|
|
845
|
+
## \_docs Property
|
|
846
|
+
|
|
847
|
+
The `_docs` property (string only) documents non-obvious aspects of the embeddable. It can appear at:
|
|
848
|
+
|
|
849
|
+
- **Top-level** — embeddable-wide notes (e.g. flow purpose, integration details)
|
|
850
|
+
- **Pages** — page-specific notes (e.g. why a page exists, routing logic)
|
|
851
|
+
- **Computed fields** — notes about formulas or dependencies
|
|
852
|
+
- **Actions (dataOutputs)** — notes about what an action does or when it runs
|
|
853
|
+
|
|
854
|
+
**AI behavior**:
|
|
855
|
+
|
|
856
|
+
- **Read** all `_docs` when working on an embeddable, page, computed field, or action to understand context that may not be obvious from the code.
|
|
857
|
+
- **Add** `_docs` when building or discovering something that should be documented because it is non-obvious (e.g. a computed field with non-trivial logic, an action with special side effects, a page with conditional routing).
|
|
858
|
+
|
|
859
|
+
**Storage**: When reverse-compiled, `_docs` is preserved in `config.json` at the corresponding level (top-level, `pages[]`, `computedFields[]`, `dataOutputs[]`).
|
|
860
|
+
|
|
646
861
|
## File Organization Rules
|
|
647
862
|
|
|
648
863
|
### React Files (Pages)
|
|
@@ -671,19 +886,21 @@ The `config.json` file contains the reduced Embeddable JSON with:
|
|
|
671
886
|
|
|
672
887
|
- Location: `computed-fields/{key}.js`
|
|
673
888
|
- Export: Function named `result` that returns computed value
|
|
674
|
-
- Access: Global `userData` object available
|
|
889
|
+
- Access: Global `userData` object available; `context` parameter provides `triggerContext` and `trackCustomEvent()`
|
|
675
890
|
|
|
676
891
|
### JS Files (Actions)
|
|
677
892
|
|
|
678
893
|
- Location: `actions/{name}.js`
|
|
679
894
|
- Export: Function named `output` for custom actions
|
|
680
|
-
- Access: Global `userData` object available
|
|
895
|
+
- Access: Global `userData` object available; `context` parameter provides `triggerContext` and `trackCustomEvent()`
|
|
681
896
|
|
|
682
897
|
## Key Principles for Modifications
|
|
683
898
|
|
|
684
|
-
1. **
|
|
899
|
+
1. **Types first**: Before adding or changing any component props, Flow properties, validation, or behavior, read the relevant interfaces in `.types/types.d.ts`. Use the types as the source of truth—do not guess or infer from examples.
|
|
900
|
+
|
|
901
|
+
2. **Component Keys**: Must be unique and descriptive. Keys become User Data keys for input components.
|
|
685
902
|
|
|
686
|
-
|
|
903
|
+
3. **Tags**: Used for CSS styling. Apply tags consistently:
|
|
687
904
|
- Primary tag (required): Describes component type (e.g., `standard_button`, `price_card`)
|
|
688
905
|
- Secondary tag (optional): Variant of primary (e.g., `primary_button`, `outline_button`)
|
|
689
906
|
- Utility tag (optional): Only for margins that can't be applied via primary/secondary (e.g., `m_2`)
|
|
@@ -691,28 +908,28 @@ The `config.json` file contains the reduced Embeddable JSON with:
|
|
|
691
908
|
- Standard tags to recognize:
|
|
692
909
|
`standard_plain_text`, `standard_rich_text`, `standard_container`, `standard_image`, `standard_button`, `standard_media_embed`, `standard_slider`, `standard_input`, `standard_checkbox`, `standard_option_buttons`, `standard_dropdown`, `standard_switch`, `standard_file_upload`, `standard_stripe_checkout`, `standard_calendly`, `standard_hubspot`, `standard_progress_bar`, `standard_progress_circle`
|
|
693
910
|
|
|
694
|
-
|
|
911
|
+
4. **Component Types**:
|
|
695
912
|
- Use `PlainText` by default
|
|
696
913
|
- Use `RichTextMarkdown` only for mixed formatting (bold, italic, lists, links, colors)
|
|
697
914
|
- Use `CustomHTML` for presentational content only (overlays, inline SVGs, decorative HTML). **Caution**: CustomHTML is for presentational content only. For interactive elements like buttons or selectable options, always use `CustomButton` or `OptionSelector` — CustomHTML elements have no access to flow actions or user data outputs.
|
|
698
915
|
|
|
699
|
-
|
|
916
|
+
5. **Nested Components**: Containers can have `components[]` array with child components. Render as nested JSX.
|
|
700
917
|
|
|
701
|
-
|
|
918
|
+
6. **Global Components**: Must use the filenames to replace the `_location` property.
|
|
702
919
|
|
|
703
|
-
|
|
920
|
+
7. **Conditions**: Stored in config.json, applied at runtime. Multiple values in one condition = OR, multiple conditions = AND. For experiment-gated conditions, when setting the control variant's conditions always include both the control variant value and `_no_value` so both control and unassigned users see the intended default.
|
|
704
921
|
|
|
705
|
-
|
|
922
|
+
8. **CSS Selectors**: Must follow exact structure with proper spacing (trailing space on breakpoints, leading space on sub-elements).
|
|
706
923
|
|
|
707
|
-
|
|
924
|
+
9. **No `!important` in CSS**: Do not use `!important` in embeddable styles. If a style does not apply, fix the selector per the CSS Selector System (principle 8); do not use `!important` as a fix.
|
|
708
925
|
|
|
709
|
-
|
|
926
|
+
10. **User Data Keys**: Input component keys become User Data keys. Choose descriptive names (e.g., `email` not `email_input`).
|
|
710
927
|
|
|
711
|
-
|
|
928
|
+
11. **Computed Field Dependencies**: `inputs` array defines which User Data keys trigger recalculation. Can reference other computed fields.
|
|
712
929
|
|
|
713
|
-
|
|
930
|
+
12. **Action Triggers**: Actions fire from `outputs_on*` fields that store action IDs. Flow-level triggers (e.g. `outputs_onloadflow`) go in `config.json` top-level; page-level triggers (e.g. `outputs_oncomplete`) go in the page entry in `config.json`; component-level triggers (e.g. `outputs_onclick`, `outputs_onchange`) go as props in React files. Actions can be invoked via `window.Savvy.triggerAction()`. See "Action Trigger Wiring" and "Programmatic Action Triggering" sections for details.
|
|
714
931
|
|
|
715
|
-
|
|
932
|
+
13. **Asset URL Source of Truth**: If `assets.json` exists in the project root, use it as the first source for image/file URLs. Prefer matching by `flow_id` (or `flow_id: null` for project-level shared assets) and use `relativePath` when mapping local files to uploaded URLs. Always use the (uploaded) url property, not local relative paths, as the image src when building in React.
|
|
716
933
|
|
|
717
934
|
## Common Patterns
|
|
718
935
|
|
|
@@ -725,11 +942,12 @@ The `config.json` file contains the reduced Embeddable JSON with:
|
|
|
725
942
|
|
|
726
943
|
### Adding a Component to a Page
|
|
727
944
|
|
|
728
|
-
1.
|
|
729
|
-
2.
|
|
730
|
-
3.
|
|
731
|
-
4. If
|
|
732
|
-
5.
|
|
945
|
+
1. Check `.types/types.d.ts` for the component interface (e.g. `InputBox`, `CustomButton`) and `Base` for shared props—use only props that exist in the types.
|
|
946
|
+
2. Update the page's React file (`pages/{pageKey}.page.tsx`)
|
|
947
|
+
3. Add component JSX with appropriate props
|
|
948
|
+
4. If new tags are used, ensure CSS exists for those tags
|
|
949
|
+
5. If any tag is a `standard_*` tag, check `default-styles.css` in project root and add missing style selectors for that tag to `styles/index.css`
|
|
950
|
+
6. Update config.json if component metadata is needed (rarely)
|
|
733
951
|
|
|
734
952
|
### Styling a Component
|
|
735
953
|
|
|
@@ -748,9 +966,10 @@ The `config.json` file contains the reduced Embeddable JSON with:
|
|
|
748
966
|
### Adding an Action
|
|
749
967
|
|
|
750
968
|
1. Create JS file: `actions/{name}.js`
|
|
751
|
-
2. Implement `output()` function (for custom actions)
|
|
969
|
+
2. Implement `output(context)` function (for custom actions) — use `context.triggerContext` for trigger metadata and `context.trackCustomEvent()` for analytics
|
|
752
970
|
3. Add metadata to config.json: `dataOutputs` array
|
|
753
971
|
4. Configure action type and mappings in config.json
|
|
972
|
+
5. Wire the action to a trigger: add the action's `id` to the appropriate `outputs_on*` field on the flow (config.json top-level), page (config.json pages entry), or component (React prop)
|
|
754
973
|
|
|
755
974
|
### Modifying Global Components
|
|
756
975
|
|