cpq-custom-actions

Use when adding, configuring, or troubleshooting custom action buttons in the Salesforce CPQ Quote Line Editor (QLE), product configurator, or amendment/renewal screens. Trigger keywords: CPQ custom action, QLE button, SBQQ__CustomAction__c, CPQ Flow button, CPQ URL action. NOT for standard Salesforce quick actions on non-CPQ objects, Lightning Experience action bars outside the QLE, or CPQ Price Rules and Product Rules.

Best use case

cpq-custom-actions is best used when you need a repeatable AI agent workflow instead of a one-off prompt.

Use when adding, configuring, or troubleshooting custom action buttons in the Salesforce CPQ Quote Line Editor (QLE), product configurator, or amendment/renewal screens. Trigger keywords: CPQ custom action, QLE button, SBQQ__CustomAction__c, CPQ Flow button, CPQ URL action. NOT for standard Salesforce quick actions on non-CPQ objects, Lightning Experience action bars outside the QLE, or CPQ Price Rules and Product Rules.

Teams using cpq-custom-actions should expect a more consistent output, faster repeated execution, less prompt rewriting.

When to use this skill

  • You want a reusable workflow that can be run more than once with consistent structure.

When not to use this skill

  • You only need a quick one-off answer and do not need a reusable workflow.
  • You cannot install or maintain the underlying files, dependencies, or repository context.

Installation

Claude Code / Cursor / Codex

$curl -o ~/.claude/skills/cpq-custom-actions/SKILL.md --create-dirs "https://raw.githubusercontent.com/PranavNagrecha/AwesomeSalesforceSkills/main/skills/apex/cpq-custom-actions/SKILL.md"

Manual Installation

  1. Download SKILL.md from GitHub
  2. Place it in .claude/skills/cpq-custom-actions/SKILL.md inside your project
  3. Restart your AI agent — it will auto-discover the skill

How cpq-custom-actions Compares

Feature / Agentcpq-custom-actionsStandard Approach
Platform SupportNot specifiedLimited / Varies
Context Awareness High Baseline
Installation ComplexityUnknownN/A

Frequently Asked Questions

What does this skill do?

Use when adding, configuring, or troubleshooting custom action buttons in the Salesforce CPQ Quote Line Editor (QLE), product configurator, or amendment/renewal screens. Trigger keywords: CPQ custom action, QLE button, SBQQ__CustomAction__c, CPQ Flow button, CPQ URL action. NOT for standard Salesforce quick actions on non-CPQ objects, Lightning Experience action bars outside the QLE, or CPQ Price Rules and Product Rules.

Where can I find the source code?

You can find the source code on GitHub using the link provided at the top of the page.

SKILL.md Source

# CPQ Custom Actions

This skill activates when configuring or debugging `SBQQ__CustomAction__c` records that surface as clickable buttons in the Salesforce CPQ Quote Line Editor (QLE), product configurator, or amendment/renewal screens. It covers all action types (URL, Flow, standard CPQ operations), the Location field that controls placement, conditional visibility through the CPQ condition evaluation engine, and the hard limit of five custom actions per context.

---

## Before Starting

Gather this context before working on anything in this domain:

- Confirm the CPQ managed package (`SBQQ__`) is installed and the user has the "Salesforce CPQ Admin" or appropriate permission set to create and edit `SBQQ__CustomAction__c` records.
- Identify the target screen: QLE (Quote Line Editor), product configurator, or amendment/renewal flow. Each is a separate `Location` value on the `SBQQ__CustomAction__c` object.
- Count the existing custom actions for the target context — CPQ enforces a hard limit of five per location (see **The Five-Action Hard Limit Per Context** below).
- Determine whether Apex logic is required. Custom actions cannot invoke Apex directly — only URL navigation, Screen/Autolaunched Flow execution, or standard CPQ operations (Save, Calculate, Add Group) are supported action types.

---

## Core Concepts

### SBQQ__CustomAction__c — The Object Behind Every QLE Button

CPQ custom actions are standard Salesforce object records of type `SBQQ__CustomAction__c` in the SBQQ managed package. Each record represents one button. Fields that control behavior:

| Field | Behavior |
|---|---|
| `SBQQ__Type__c` | The action type. Valid values: `URL` (opens a URL in a new tab or same tab), `Flow` (launches a Screen Flow or Autolaunched Flow), `Calculate` (triggers CPQ price recalculation), `Save` (triggers CPQ quote save), `Add Group` (adds a new quote line group). Only these values are recognized; arbitrary strings fail silently. |
| `SBQQ__Location__c` | Controls which CPQ screen and position renders the button. Values include `Line Item` (in each quote line row), `Group` (at the group header level), `Global` (once per quote, above the line grid). The configurator and amendment screens have their own location values. |
| `SBQQ__DisplayOrder__c` | Integer controlling the left-to-right display order of buttons when multiple custom actions share the same location. |
| `SBQQ__Active__c` | Boolean; only active records are rendered in the UI. |
| `SBQQ__FlowName__c` | API name of the Flow to invoke when type is `Flow`. |
| `SBQQ__URL__c` | The URL to navigate to when type is `URL`. Supports merge field syntax for passing CPQ record IDs. |

### The Five-Action Hard Limit Per Context

Salesforce CPQ enforces a hard limit of **five custom actions per location context**. This is not a configurable setting or a governor limit — it is a rendering constraint in the QLE Lightning component. If more than five active `SBQQ__CustomAction__c` records exist for a given `Location__c` value, CPQ renders only five and silently ignores the rest (ordering is not guaranteed for the dropped actions). Architects must audit the existing action count before adding new ones.

### Conditional Visibility — CPQ Condition Engine, Not Flow or Apex

Custom action visibility can be made conditional — for example, showing a validation button only when a quote is in `Draft` status. This is controlled by CPQ's **built-in condition evaluation engine**, the same engine that drives Product Rules and Price Rules. Conditions are configured by associating `SBQQ__CustomActionCondition__c` records (or equivalent condition child records) with the custom action and setting the `SBQQ__ConditionsMet__c` picklist on the action (`All`, `Any`, or `Formula`).

This is a frequent source of confusion: practitioners often attempt to control button visibility through Flow decisions or Apex triggers on the quote. Neither approach works. The CPQ rendering layer reads conditions at page load from the CPQ condition framework — it does not evaluate Apex triggers or Flow output to decide whether to render a button.

### Apex Execution — Only via Workaround

Custom actions of type `Flow` or `URL` are the only paths to executing Apex logic from a custom button. There is no `Apex` action type on `SBQQ__CustomAction__c`. Two supported workarounds:

1. **Flow calling Apex** — Configure the action as type `Flow`, then use an Apex-defined invocable method called from an Action element inside the Flow. The Flow acts as the bridge.
2. **URL to a Visualforce page** — Configure the action as type `URL` pointing to a Visualforce page that invokes an Apex controller. Pass the quote or line ID via URL parameters using CPQ merge field syntax (e.g., `{!SBQQ__Quote__c}`).

---

## Common Patterns

### Pattern: Flow-Backed Validation Button in the QLE

**When to use:** A business rule requires reps to validate quote data (e.g., checking product compatibility or minimum order quantities) before submitting, and the validation logic is complex enough to require Apex.

**How it works:**
1. Build an Autolaunched Flow with an Apex action (invocable method) containing the validation logic. The Flow receives the Quote ID as an input variable.
2. Create an `SBQQ__CustomAction__c` record: `SBQQ__Type__c = Flow`, `SBQQ__FlowName__c` = the Flow API name, `SBQQ__Location__c = Global` (one button per quote, not per line).
3. Add a `SBQQ__CustomActionCondition__c` record if the button should only appear in Draft status: field = `SBQQ__Quote__r.SBQQ__Status__c`, operator = `Equals`, value = `Draft`.
4. Set `SBQQ__Active__c = true` and an appropriate `SBQQ__DisplayOrder__c`.

**Why not the alternative:** Using a standard CPQ Price Rule or Product Rule for validation fires automatically on save/calculate and cannot be triggered on demand by the rep. A custom action gives the rep explicit control over when validation runs.

### Pattern: URL Action Opening an External Pricing Tool

**When to use:** The org integrates with an external pricing or CPQ tool that should be launched in context from the QLE, passing the current quote and line IDs to the external system.

**How it works:**
1. Create an `SBQQ__CustomAction__c` record: `SBQQ__Type__c = URL`.
2. In `SBQQ__URL__c`, use CPQ merge field syntax to embed the record ID: `https://external-tool.example.com/quote?sfQuoteId={!SBQQ__Quote__c}&sfLineId={!Id}`. The `{!Id}` token resolves to the current line item record ID when `Location__c = Line Item`.
3. Set `SBQQ__Location__c = Line Item` if the external tool is line-specific, or `Global` if it operates at the quote level.
4. Verify the URL is added to the org's Content Security Policy (CSP) trusted sites if it opens in a Lightning iframe context.

**Why not the alternative:** Visualforce pages embedded in the QLE introduce complexity and session context issues. A URL action that opens in a new browser tab is simpler, avoids CSP complications, and works with any external tool.

---

## Decision Guidance

| Situation | Recommended Approach | Reason |
|---|---|---|
| Need to execute Apex logic from a QLE button | Flow action type with an Apex invocable method inside the Flow | Custom actions have no Apex type; Flow is the supported bridge |
| Need to open an external tool in context | URL action type with CPQ merge field tokens in the URL | Simplest path; no managed package extension needed |
| Need to trigger standard CPQ recalculation on demand | `Calculate` action type | Purpose-built; no custom code required |
| Need conditional button visibility | CPQ condition records on the action (SBQQ__CustomActionCondition__c) | CPQ rendering evaluates its own condition engine; Flow/Apex are not evaluated at render time |
| At or near the 5-action limit per context | Consolidate actions into a single Flow with a choice screen | The 5-action limit is hard; the Flow can branch to multiple logical operations |
| Need a button per line row vs. per quote | Line Item location for per-row, Global location for per-quote | Location field controls rendering granularity |

---

## Recommended Workflow

Step-by-step instructions for an AI agent or practitioner working on this task:

1. **Audit existing custom actions** — Query `SBQQ__CustomAction__c` filtered by the target `SBQQ__Location__c` and `SBQQ__Active__c = true`. Count records. If already at 5, the new action must replace an existing one or be consolidated into a Flow with branching logic before proceeding.
2. **Determine action type** — Decide whether the button should navigate to a URL, launch a Flow, or trigger a standard CPQ operation (Save, Calculate, Add Group). If Apex logic is required, plan the Flow-as-bridge or Visualforce-URL workaround at this step.
3. **Build the Flow or Visualforce page if needed** — For Flow-backed actions, build and activate the Flow first. Confirm the Flow API name. For URL actions pointing to an org page, create and deploy the Visualforce page before creating the action record.
4. **Create the SBQQ__CustomAction__c record** — Set `SBQQ__Type__c`, `SBQQ__Location__c`, `SBQQ__FlowName__c` or `SBQQ__URL__c`, `SBQQ__DisplayOrder__c`, and `SBQQ__Active__c = true`. Use a meaningful label in `Name` — this appears as the button label in the QLE.
5. **Configure conditional visibility if required** — Create `SBQQ__CustomActionCondition__c` records referencing the parent action. Set the `SBQQ__ConditionsMet__c` field on the action to `All`, `Any`, or `Formula`. Test by loading the QLE with a quote that meets and does not meet the conditions.
6. **Test end-to-end in the QLE** — Open a test quote in the QLE. Verify the button renders at the correct location, the label is correct, the action fires correctly, and conditional visibility behaves as expected. Check browser console for JavaScript errors if the button does not appear.
7. **Review checklist before deploying to production** — Confirm the 5-action limit is not exceeded, Flow is activated, URL CSP trusted sites are configured, and the action is tested on both new and amendment quotes if applicable.

---

## Review Checklist

Run through these before marking work in this area complete:

- [ ] Active custom action count for the target location is 5 or fewer
- [ ] Flow is activated (not Draft) before the custom action record is created
- [ ] For URL actions, the target URL domain is added to CSP Trusted Sites if it opens in a Lightning context
- [ ] Conditional visibility is configured via CPQ condition records, not via Flow decisions or Apex
- [ ] The action has been tested on both the target CPQ screen and, if applicable, on amendment/renewal quotes
- [ ] Button label in `Name` field is clear and rep-facing (not an internal API name)
- [ ] `SBQQ__DisplayOrder__c` is set to avoid collisions with existing actions

---

## Salesforce-Specific Gotchas

See [`references/gotchas.md`](references/gotchas.md) for detailed write-ups with avoidance strategies. Key gotchas at a glance:

1. **Five-action limit is silent, not an error** — exceeding 5 active actions per location silently drops buttons with no log entry.
2. **Flow must be Activated before the action fires** — Draft Flows cause a generic runtime error when the rep clicks the button.
3. **Conditional visibility evaluates at page load only** — field changes inside the QLE do not toggle button visibility until reload.
4. **URL merge fields resolve based on Location context** — `{!Id}` means line ID at `Line Item` location but quote ID at `Global`.
5. **Custom actions render only in CPQ screens** — buttons do not appear on the standard Lightning record page.

---

## Output Artifacts

| Artifact | Description |
|---|---|
| SBQQ__CustomAction__c record | The configured custom action button record in the CPQ org |
| Flow (if type = Flow) | The activated Flow wired to the action, optionally containing an Apex invocable action |
| SBQQ__CustomActionCondition__c records | Condition records controlling button visibility (if conditional behavior required) |
| Visualforce page (if type = URL to VF) | Page wired to an Apex controller for Apex-execution workaround via URL action |
| Audit query results | SOQL results confirming action count per location is within the 5-action limit |

---

## Related Skills

- `cpq-architecture-patterns` — Covers QLE performance limits, Large Quote Mode, and bundle design patterns that interact with custom action placement
- `apex-invocable-actions` — Use alongside this skill when a Flow-backed custom action needs to call an Apex invocable method

Related Skills

customer-data-request-workflow

8
from PranavNagrecha/AwesomeSalesforceSkills

Implement GDPR/CCPA data subject rights (access, deletion, rectification) using Salesforce Privacy Center and/or custom workflow. NOT for general backup or org-level data retention policy.

omnistudio-remote-actions

8
from PranavNagrecha/AwesomeSalesforceSkills

Use when configuring, troubleshooting, or choosing between Remote Action types in OmniScript or FlexCard. Triggers: 'remote action', 'OmniScript action', 'IP action', 'Apex action element', 'VlocityOpenInterface2', 'Send/Response JSON Path'. NOT for Integration Procedure internal design (use integration-procedures) or generic Apex callout patterns (use apex integration skills).

omnistudio-custom-lwc-elements

8
from PranavNagrecha/AwesomeSalesforceSkills

Creating and integrating custom Lightning Web Components within OmniScripts: LWC override patterns, pubsub event handling, custom validation, OmniStudio data passing conventions. Use when a standard OmniScript element cannot meet a UX requirement. NOT for standalone LWC development (use lwc/* skills). NOT for Integration Procedures (use integration-procedures). NOT for embedding an OmniScript inside an LWC (use omnistudio-lwc-integration).

lwc-quick-actions

8
from PranavNagrecha/AwesomeSalesforceSkills

Use when building a Lightning Web Component that runs from a record page quick-action button — either a screen action that renders UI in a modal or a headless action that invokes logic with no UI. Triggers: 'lwc quick action on record page', 'headless quick action no ui', 'closeactionscreenevent not working', 'how to pass recordid into quick action lwc', 'quick action vs flow action', 'quick action modal size'. NOT for Flow screen components — use `lwc-in-flow-screens` — and NOT for global actions without a record context or for list-view bulk actions that do not receive a single `recordId`.

lwc-custom-lookup

8
from PranavNagrecha/AwesomeSalesforceSkills

Custom lookup component in LWC — typeahead/autocomplete that searches records via Apex SOSL/SOQL, shows pills, supports keyboard navigation, and manages open/close state. Use when lightning-input-field or lightning-record-picker won't work (cross-org search, computed filters, custom result rendering). NOT for in-form lookups inside lightning-record-edit-form (use lightning-input-field) or lookup filters (use admin lookup filter config).

lwc-custom-event-patterns

8
from PranavNagrecha/AwesomeSalesforceSkills

When and how to design CustomEvent traffic out of an LWC — bubbles / composed / cancelable flag choices, detail payload shape, naming rules, and propagation control. Trigger keywords: 'event not reaching parent', 'composed shadow DOM', 'CustomEvent detail mutation', 'stopPropagation vs stopImmediatePropagation'. NOT for parent-to-child communication (use `@api` — see `lwc/component-communication`), NOT for sibling fan-out (use Lightning Message Service — see `lwc/lightning-message-service`), NOT for wire-service data plumbing.

lwc-custom-datatable-types

8
from PranavNagrecha/AwesomeSalesforceSkills

Use when you need to extend `lightning-datatable` with custom cell renderings: status pills, progress bars, image thumbnails, action cells, editable pickliststo, rich-text, or any column that `lightning-datatable` does not ship out of the box. Triggers: 'custom cell type lightning datatable', 'progress bar column', 'image column', 'inline edit picklist in datatable', 'rich text column'. NOT for basic datatable usage (see `lwc-data-table`) and NOT for tree-grid or large-dataset virtualization (see `virtualized-lists`).

experience-cloud-search-customization

8
from PranavNagrecha/AwesomeSalesforceSkills

Use this skill when configuring or extending search on an Experience Cloud site — covering Search Manager scope configuration, LWR vs Aura search component selection, federated search setup, guest user search access, and custom search result components. NOT for SOSL/SOQL query development. NOT for internal Salesforce global search or Einstein Search for agents.

custom-property-editor-for-flow

8
from PranavNagrecha/AwesomeSalesforceSkills

Use when building or reviewing an LWC Custom Property Editor for Flow screen or action configuration, including the `configurationEditor` metadata hook, builder-side APIs, validation, and value-change events. Triggers: 'custom property editor', 'Flow configuration editor', 'builderContext', 'inputVariables', 'configurationEditor'. NOT for ordinary runtime screen-component behavior when no Flow Builder design-time customization is involved.

flow-custom-property-editors

8
from PranavNagrecha/AwesomeSalesforceSkills

Use when designing or reviewing Flow custom property editor patterns for screen components or actions, including when Flow Builder needs guided design-time configuration, generic type mapping, or builder-context-aware validation. Triggers: 'Flow custom property editor', 'configurationEditor', 'builderContext', 'inputVariables', 'Flow screen component setup'. NOT for general LWC runtime behavior when Flow Builder customization is not involved.

github-actions-for-salesforce

8
from PranavNagrecha/AwesomeSalesforceSkills

Use this skill to set up, review, or troubleshoot GitHub Actions CI/CD pipelines for Salesforce using SFDX JWT Bearer Flow authentication, Apex test gates, and branch-conditional deployments. Trigger keywords: github actions, CI pipeline, jwt auth, sfdx ci, workflow yaml, github secrets, apex coverage threshold. NOT for other CI tools such as Jenkins, Copado, Bitbucket Pipelines, or Azure DevOps.

feature-flag-custom-metadata

8
from PranavNagrecha/AwesomeSalesforceSkills

Implement environment-safe feature flags using Custom Metadata Types for Apex, LWC, and Flow. NOT for user-level entitlements or permission sets.