Skip to content

feat: Add Betterbugs SDK support#41532

Merged
subrata71 merged 11 commits intoreleasefrom
feat/add-betterbugs-support
Feb 13, 2026
Merged

feat: Add Betterbugs SDK support#41532
subrata71 merged 11 commits intoreleasefrom
feat/add-betterbugs-support

Conversation

@sebastianiv21
Copy link
Contributor

@sebastianiv21 sebastianiv21 commented Jan 27, 2026

Description

Tip

Add a TL;DR when the description is longer than 500 words or extremely technical (helps the content, marketing, and DevRel team).

Please also include relevant motivation and context. List any dependencies that are required for this change. Add links to Notion, Figma or any other documents that might be relevant to the PR.

This PR integrates Betterbugs bug reporting SDK into the Appsmith client application, providing users with an enhanced bug reporting experience directly within the application interface.

Motivation and Context
Currently, users need to manually report bugs through external channels, which can be cumbersome and may result in incomplete bug reports. By integrating Betterbugs, we enable:

  • Streamlined bug reporting: Users can report bugs directly from the application
  • Rich context capture: Automatically captures session metadata, user information, and application state
  • Better debugging: Provides development team with comprehensive bug reports including screenshots, console logs, and user actions
  • Improved user experience: Reduces friction in the bug reporting process

Fixes #Issue Number
or
Fixes Issue URL

Warning

If no issue exists, please create an issue first, and check with the maintainers if the issue is valid.

Automation

/ok-to-test tags="@tag.All"

🔍 Cypress test results

Tip

🟢 🟢 🟢 All cypress tests have passed! 🎉 🎉 🎉
Workflow run: https://github.com/appsmithorg/appsmith/actions/runs/21915839106
Commit: f70f563
Cypress dashboard.
Tags: @tag.All
Spec:


Fri, 13 Feb 2026 01:50:46 UTC

Communication

Should the DevRel and Marketing teams inform users about this change?

  • Yes
  • No

Summary by CodeRabbit

  • New Features

    • Adds a "Send support info" option in help menus and homepage header (visible when enabled) to let users send diagnostic/support info.
  • Chores

    • Integrates a third‑party support widget and SDK, adds a feature‑flagged configuration with an API key toggle, wires build/deploy and runtime settings, and ensures widget metadata updates automatically on navigation.
@coderabbitai
Copy link
Contributor

coderabbitai bot commented Jan 27, 2026

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review

Walkthrough

Adds Betterbugs frontend integration: SDK dependency and wrapper, build and env wiring for an API key, runtime config and types, UI menu triggers to open the widget, route-change metadata refresh, and nginx/jest substitution flags.

Changes

Cohort / File(s) Summary
Dependency
app/client/package.json
Adds @betterbugs/web-sdk ^0.0.40.
Public config / flags
app/client/jest.config.js, app/client/public/index.html, app/client/docker/templates/nginx-app.conf.template
Adds betterbugs to APPSMITH_FEATURE_CONFIGS, a DISABLE_BETTERBUGS env flag and corresponding nginx sub_filter for substitution.
Build / CI / Docker
Dockerfile, .github/workflows/... (multiple), scripts/deploy_preview.sh
Wires APPSMITH_BETTERBUGS_API_KEY as ARG/ENV and propagates it into CI build-args and deploy Helm values.
Config types & mapping
app/client/src/ce/configs/index.ts, app/client/src/ce/configs/types.ts
Adds betterbugs config (apiKey) to injected env mapping and extends AppsmithUIConfigs with betterbugs: { enabled, apiKey }.
SDK wrapper & analytics util
app/client/src/utils/Analytics/betterbugs.ts
New BetterbugsUtil: dynamic SDK import, lifecycle methods (init/show/hide/destroy/updateMetadata), runtime metadata collection and syncing, airgap/enable checks.
UI triggers
app/client/src/pages/Editor/HelpButton.tsx, app/client/src/pages/common/SearchBar/HomepageHeaderAction.tsx
Adds "Send support info" menu items (icon support) shown when betterbugs.enabled and not airgapped; items call BetterbugsUtil.show(user).
Routing integration
app/client/src/RouteChangeListener.tsx
Calls BetterbugsUtil.updateMetadata() on route changes to refresh runtime metadata.
Messages
app/client/src/ce/constants/messages.ts
Adds SEND_SUPPORT_INFO message constant.
Tests / Jest config
app/client/jest.config.js
Exposes betterbugs.apiKey in globals for test/runtime substitution.

Sequence Diagram(s)

sequenceDiagram
    participant User
    participant UI as "Help Menu / Homepage"
    participant Config as "App Configs"
    participant Util as "BetterbugsUtil"
    participant SDK as "@betterbugs/web-sdk"
    participant Router as "RouteChangeListener"

    User->>UI: Click "Send support info"
    UI->>Config: read betterbugs.enabled, apiKey
    UI->>Util: show(user)
    Util->>Util: destroy existing instance (if any)
    Util->>Config: read apiKey, appVersion, tenantId, runtime metadata
    Util->>SDK: dynamic import (browser)
    SDK-->>Util: module loaded
    Util->>SDK: create widget with user, metadata, styles
    SDK-->>Util: instance created
    Util->>SDK: openWidget()
    SDK-->>User: Widget displayed

    Note over Router,Util: On route change
    Router->>Util: updateMetadata()
    Util->>SDK: setMetadata(updatedRuntimeMetadata)
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~22 minutes

Poem

🐞 A tiny widget wakes and hums,
Click "Send support info" — the message comes,
Metadata bundled, routes in tow,
A debug beacon set to glow,
Help arrives where problems roam.

🚥 Pre-merge checks | ✅ 2 | ❌ 1
❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Title check ✅ Passed The PR title 'feat: Add Betterbugs SDK support' clearly and concisely summarizes the main change—integrating Betterbugs SDK into the Appsmith client.
Description check ✅ Passed PR description is mostly complete with motivation, context, and Cypress test results, but lacks specific issue reference and DevRel/Marketing communication decision.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch feat/add-betterbugs-support

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@sebastianiv21 sebastianiv21 changed the title Feat/add betterbugs support Jan 27, 2026
@github-actions github-actions bot added the Enhancement New feature or request label Jan 27, 2026
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🤖 Fix all issues with AI agents
In `@app/client/src/pages/common/SearchBar/HomepageHeaderAction.tsx`:
- Around line 146-153: Only render the "Send support info" MenuItem when
Betterbugs is enabled and has a valid API key, and localize its label via
createMessage; update the JSX in HomepageHeaderAction to conditionally include
the <MenuItem> that calls BetterbugsUtil.show(user) by checking the Betterbugs
config flag or API key presence (use whatever config accessor exists in this
component), and replace the hardcoded text with createMessage({ id: '...',
defaultMessage: 'Send support info' }) to match other menu items.

In `@app/client/src/pages/Editor/HelpButton.tsx`:
- Line 42: The menu item for "Send support info" is added and the BetterBugs SDK
is invoked unconditionally; update the HelpButton component to only render the
menu item when the feature flag is enabled (check the app config or
betterbugs.enabled) and guard the click handler to no-op if Betterbugs isn't
configured. Concretely: in HelpButton (where the menu is built / renderMenu or
addMenuItem is called) wrap the menu-item creation in a conditional that checks
betterbugs.enabled (or call a helper like BetterbugsUtil.isEnabled()), and in
the sendSupportInfo / onSendSupportInfo handler call BetterbugsUtil only after
verifying BetterbugsUtil.isEnabled() or API key presence; if not enabled, return
early (and optionally log a debug message) so the SDK is never triggered when no
API key is configured.
@tomjose92
Copy link
Contributor

@sebastianiv21 , we need to have an option to allow the user to disable betterbugs. This is in scenarios where its airgapped, or the user has hosted in an isolated environment and does not want to outgoing traffic to betterbugs.
Or wouldnt whitelist it. It will throw up a lot of console errors or failed network

@tomjose92
Copy link
Contributor

/build-deploy-preview skip-tests=true

@github-actions
Copy link

github-actions bot commented Feb 2, 2026

Deploying Your Preview: https://github.com/appsmithorg/appsmith/actions/runs/21598576654.
Workflow: On demand build Docker image and deploy preview.
skip-tests: true.
env: ``.
PR: 41532.
recreate: .

@github-actions
Copy link

github-actions bot commented Feb 2, 2026

Deploy-Preview-URL: https://ce-41532.dp.appsmith.com

@sebastianiv21
Copy link
Contributor Author

/build-deploy-preview skip-tests=true

@github-actions
Copy link

github-actions bot commented Feb 4, 2026

Deploying Your Preview: https://github.com/appsmithorg/appsmith/actions/runs/21679221046.
Workflow: On demand build Docker image and deploy preview.
skip-tests: true.
env: ``.
PR: 41532.
recreate: .

@github-actions
Copy link

github-actions bot commented Feb 4, 2026

Deploy-Preview-URL: https://ce-41532.dp.appsmith.com

@sebastianiv21
Copy link
Contributor Author

/build-deploy-preview skip-tests=true

@github-actions
Copy link

github-actions bot commented Feb 5, 2026

Deploying Your Preview: https://github.com/appsmithorg/appsmith/actions/runs/21716034843.
Workflow: On demand build Docker image and deploy preview.
skip-tests: true.
env: ``.
PR: 41532.
recreate: .

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
scripts/deploy_preview.sh (1)

117-126: ⚠️ Potential issue | 🟡 Minor

Consider conditional injection for all optional API keys, not just Betterbugs.

Empty values are currently passed unconditionally to Helm for all optional API keys (OPENAI_API_KEY, APPSMITH_CARBON_API_KEY, APPSMITH_BETTERBUGS_API_KEY). While the application code handles empty Betterbugs keys explicitly, applying conditional injection consistently across all optional keys would prevent unnecessary ConfigMap pollution and avoid potential SDK initialization side effects.

Either implement conditional injection for all optional API keys, or confirm the Helm chart and application layers treat empty strings as disabled across the board.

@sebastianiv21
Copy link
Contributor Author

/build-deploy-preview skip-tests=true

@github-actions
Copy link

github-actions bot commented Feb 5, 2026

Deploying Your Preview: https://github.com/appsmithorg/appsmith/actions/runs/21718750696.
Workflow: On demand build Docker image and deploy preview.
skip-tests: true.
env: ``.
PR: 41532.
recreate: .

@github-actions
Copy link

github-actions bot commented Feb 5, 2026

Deploy-Preview-URL: https://ce-41532.dp.appsmith.com

@github-actions
Copy link

github-actions bot commented Feb 5, 2026

Deploying Your Preview: https://github.com/appsmithorg/appsmith/actions/runs/21725726438.
Workflow: On demand build Docker image and deploy preview.
skip-tests: true.
env: ``.
PR: 41532.
recreate: .

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Fix all issues with AI agents
In `@app/client/src/utils/Analytics/betterbugs.ts`:
- Around line 183-195: The hide() method on the BetterBugs utility is marked
async but contains no await or asynchronous work; remove the async modifier from
the hide method declaration to avoid misleading callers and adjust any callers
only if they unnecessarily await BetterBugs.hide(); update references to the
method signature (BetterBugs.hide and this.instance.hide) accordingly so the
method is a plain synchronous function.
🧹 Nitpick comments (1)
app/client/src/utils/Analytics/betterbugs.ts (1)

145-148: Redundant updateMetadata() call.

init() already calls getRuntimeMetadata() and includes it in the initial metadata (line 113). Calling updateMetadata() immediately after is redundant since the runtime state hasn't changed between these synchronous calls.

♻️ Remove redundant call
     // Initialize fresh instance
     await this.init(user);
 
-    this.updateMetadata();
-
     if (this.instance?.openWidget) {
@github-actions
Copy link

github-actions bot commented Feb 5, 2026

Deploy-Preview-URL: https://ce-41532.dp.appsmith.com

@sebastianiv21
Copy link
Contributor Author

/build-deploy-preview skip-tests=true

@github-actions
Copy link

github-actions bot commented Feb 9, 2026

Deploying Your Preview: https://github.com/appsmithorg/appsmith/actions/runs/21827305063.
Workflow: On demand build Docker image and deploy preview.
skip-tests: true.
env: ``.
PR: 41532.
recreate: .

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Fix all issues with AI agents
In `@app/client/src/utils/Analytics/betterbugs.ts`:
- Around line 95-114: The code is sending raw PII to Betterbugs: remove or
anonymize user.email and user.name from both the top-level SDK field
(user.email) and from metaData (user_email, user_name); instead pass a hashed or
non-identifying user ID (e.g., hash(user.email) or an internal userId) or omit
these fields entirely, and ensure any sensitive appVersion fields remain safe;
also replace the direct access store.getState().organization?.tenantId with the
canonical selector (use the same selector pattern as getInstanceId) to fetch
tenant_id consistently.
🧹 Nitpick comments (3)
app/client/src/utils/Analytics/betterbugs.ts (3)

117-117: Unsafe type assertion as BetterbugsInstance.

If the SDK constructor's return type drifts from your interface (e.g., a version bump removes openWidget), this cast silently hides the mismatch. A runtime shape check or a wrapper that adapts the SDK instance to the interface would be safer.


133-155: Concurrent show() calls can leak orphaned SDK instances.

If show() is invoked twice before the first await this.init(user) resolves, both calls see this.instance as null, both execute new Betterbugs(...), and the first instance is overwritten without being destroyed — a resource leak.

A simple guard (e.g., a static initializing promise or flag) would prevent this.

♻️ Suggested guard
 class BetterbugsUtil {
   private static instance: BetterbugsInstance | null;
+  private static initPromise: Promise<void> | null = null;

   // ...

   public static async show(user?: User) {
     if (isAirgapped() || !getAppsmithConfigs().betterbugs.enabled) {
       log.warn("BetterBugs is disabled.");
       return;
     }

+    // Serialize concurrent calls
+    if (this.initPromise) {
+      await this.initPromise;
+    }
+
     if (this.instance) {
       this.destroy();
     }

-    await this.init(user);
+    this.initPromise = this.init(user);
+    await this.initPromise;
+    this.initPromise = null;

     this.updateMetadata();

     if (this.instance?.openWidget) {
       this.instance.openWidget();
     } else {
       log.warn("BetterBugs openWidget() is not available.");
     }
   }

157-181: Redundant optional chaining after null guard.

Line 162: this.instance?.setMetadata — the early return on line 158-160 already guarantees this.instance is non-null. Same pattern on line 174 with getMetadata. Not a bug, just noise.

♻️ Suggested cleanup
-    if (!this.instance?.setMetadata) {
+    if (!this.instance.setMetadata) {
       return;
     }
     // ...
-    const existingMeta = this.instance.getMetadata?.() || {};
+    const existingMeta = this.instance.getMetadata?.() || {}; // this one is fine — getMetadata is optional on the interface

Actually getMetadata is optional on the interface so ?. is correct there. Only the setMetadata check on line 162 has the redundant ?..

-    if (!this.instance?.setMetadata) {
+    if (!this.instance.setMetadata) {
Comment on lines 95 to 114
...(user?.email ? { email: user.email } : {}),
showActionButton: false,
styles: this.getDefaultStyles(),
mainHeading: "Send support info",
recordType: "recordVideo",
position: { bottom: "30px", right: "20px" },
successMessageHeaderText: "Information received",
successMessageSubHeaderText:
"Our support team will use it to review the issue",
metaData: {
...(user?.email ? { user_email: user.email } : {}),
...(user?.name ? { user_name: user.name } : {}),
instance_id: getInstanceId(store.getState()),
tenant_id: store.getState().organization?.tenantId,
version: appVersion.id,
commit_sha: appVersion.sha,
edition: appVersion.edition,
release_date: appVersion.releaseDate,
...this.getRuntimeMetadata(),
},
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

User PII (email, name) is sent to a third-party service.

user.email is passed both as a top-level SDK field (line 95) and inside metaData (lines 105-106), along with user.name. This sends personally identifiable information to Betterbugs servers. Verify this aligns with your privacy policy and data processing agreements. Consider whether hashed identifiers or anonymized values would suffice for debugging.

Also, line 108 accesses store.getState().organization?.tenantId directly instead of using a selector — minor inconsistency with line 107 which uses getInstanceId.

🤖 Prompt for AI Agents
In `@app/client/src/utils/Analytics/betterbugs.ts` around lines 95 - 114, The code
is sending raw PII to Betterbugs: remove or anonymize user.email and user.name
from both the top-level SDK field (user.email) and from metaData (user_email,
user_name); instead pass a hashed or non-identifying user ID (e.g.,
hash(user.email) or an internal userId) or omit these fields entirely, and
ensure any sensitive appVersion fields remain safe; also replace the direct
access store.getState().organization?.tenantId with the canonical selector (use
the same selector pattern as getInstanceId) to fetch tenant_id consistently.
@github-actions
Copy link

github-actions bot commented Feb 9, 2026

Deploy-Preview-URL: https://ce-41532.dp.appsmith.com

@sebastianiv21 sebastianiv21 added the ok-to-test Required label for CI label Feb 9, 2026
@sebastianiv21 sebastianiv21 added ok-to-test Required label for CI and removed ok-to-test Required label for CI labels Feb 9, 2026
}
}

if (item.id === "betterbugs-trigger") {
Copy link
Contributor

@ashit-rath ashit-rath Feb 10, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@subrata71 Right now this HelpButton is present in App and Workflows. Should be add it to packages as well?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, we should otherwise it will just remain as half-baked solution.

@sebastianiv21
Copy link
Contributor Author

/build-deploy-preview skip-tests=true

@github-actions
Copy link

Deploying Your Preview: https://github.com/appsmithorg/appsmith/actions/runs/21893986809.
Workflow: On demand build Docker image and deploy preview.
skip-tests: true.
env: ``.
PR: 41532.
recreate: .

@github-actions
Copy link

Deploy-Preview-URL: https://ce-41532.dp.appsmith.com

@sebastianiv21
Copy link
Contributor Author

/build-deploy-preview skip-tests=true

@github-actions
Copy link

Deploying Your Preview: https://github.com/appsmithorg/appsmith/actions/runs/21915963289.
Workflow: On demand build Docker image and deploy preview.
skip-tests: true.
env: ``.
PR: 41532.
recreate: .

@github-actions
Copy link

Deploy-Preview-URL: https://ce-41532.dp.appsmith.com

Copy link
Collaborator

@subrata71 subrata71 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please create an issue to add BetterBugs support for packages and workflows.

@subrata71 subrata71 merged commit 81165f4 into release Feb 13, 2026
351 of 359 checks passed
@subrata71 subrata71 deleted the feat/add-betterbugs-support branch February 13, 2026 10:50
@sebastianiv21 sebastianiv21 restored the feat/add-betterbugs-support branch February 13, 2026 15:27
@sebastianiv21 sebastianiv21 deleted the feat/add-betterbugs-support branch February 16, 2026 15:58
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Enhancement New feature or request ok-to-test Required label for CI

4 participants