Skip to main content
Documentation

BumbleTap Guide

Everything you need to master keyboard shortcuts and automation — the same guide that ships inside the extension.

Getting Started

BumbleTap lets you control any website with keyboard shortcuts and automated workflows. Here's the quick overview.

Keyboard Shortcuts

Bind any key combination to click elements, type text, trigger browser events, or run custom JavaScript.

Auto-Actions

Automated step sequences that run on page load, URL change, element appearance, or custom conditions.

Macro Recorder

Record your clicks, typing, and scrolling, then replay them as auto-actions.

Custom JavaScript

Write code that runs when you press a key or when an action triggers. Full DOM access, async/await, helper functions.

Command Palette

Fuzzy-search all your bindings and run them instantly. Like Spotlight for your shortcuts.

Variables

Extract data from pages and pass it between steps using {{variableName}} syntax.

Quick Start

  1. Click the BumbleTap icon in your browser toolbar to open the popup.
  2. Click + Add Key Binding and record a key combination.
  3. Choose an action: click an element, type text, trigger a built-in event, or write custom code.
  4. Use the element picker (crosshair icon) to select elements on the page.
  5. Press your shortcut on the page to trigger the action.

Tip: Use the right-click context menu on any element to quickly create a binding for it.

Global vs Site Bindings

Site bindings only work on the site you created them for (e.g., youtube.com). Global bindings work on every site. Toggle between them using the globe icon in the popup.

Global bindings can exclude specific sites if needed. Site bindings always take priority over global bindings with the same key.

Keybindings

Each keybinding maps a key combination to an action. You can create single-key shortcuts or multi-key chord sequences.

Action Types

Click ElementMost common

Simulates a click on a page element identified by CSS selector.

  • Use the element picker to select any element visually
  • Set a friendly element name for readability
  • Use selector index to target the Nth match when multiple elements match
Type Text

Inserts text into an input field. Two modes:

  • In a textbox — target a specific field by CSS selector
  • During typing — insert at current cursor position (requires modifier key)

Supports variable interpolation: {{date}}, {{clipboard}}, {{url}}, etc.

Options: Clear field first, Press Enter after typing.

Built-in Event

Trigger browser/media functionality without writing code. Categories: Scroll, Media, Navigation, Zoom. See the Built-in Events page for the full list.

Custom Code

Execute JavaScript code with full page access and built-in helpers. See the Custom Code page for details.

First use: You'll need to enable User Scripts in Chrome. See Setup & Permissions.


Chord Shortcuts

Chords are multi-key sequences pressed one after another — like G then D. Unlike key combos (Ctrl+S), chords let you create hundreds of shortcuts using memorable letter sequences.

  • Chord timeout (200–3000ms) — how long to wait between keys before resetting
  • Chord overlay — optional visual indicator showing chord progress
  • Configure both in the popup's Global Defaults settings

URL Scoping

Restrict when a binding activates by matching the current URL:

ModeExampleUse case
All pagesAlways active on this site
Pattern*/video/*Only on video pages
Regex^https://.*\.com/watchComplex URL matching

Use the Test URL button to verify your pattern matches the current page.

Built-in Events

Pre-built browser and media actions you can trigger without writing code.

Scroll

ActionDescription
Scroll Up / DownVertical scroll. Amount: small (100px), medium (300px), large (500px), full viewport, or custom pixels/percentage.
Scroll Left / RightHorizontal scroll with same amount options.
Scroll to TopJump to the top of the page instantly.
Scroll to BottomJump to the bottom of the page.

Media

ActionDescription
Play/PauseToggle playback on the active video or audio element.
Mute/UnmuteToggle audio mute.
Volume Up / DownAdjust volume in 1–25% steps.
Seek Forward / BackwardSkip 5s, 10s, 30s, or a custom amount.
FullscreenToggle fullscreen mode on the video.
Picture-in-PictureToggle PiP floating window.

Media actions auto-detect the active video/audio. You can also target a specific element by CSS selector.

Navigation

ActionDescription
Go BackBrowser back button (history.back).
Go ForwardBrowser forward button (history.forward).
RefreshReload the page. Optional confirmation dialog.

Zoom

ActionDescription
Zoom In / OutScale the page in 5–50% increments.
Reset ZoomReturn to 100% (1x) zoom.

Auto-Actions

Automated workflows that run sequences of steps when triggered. Each auto-action has a trigger (when to run), optional URL filter (where to run), and a list of steps (what to do).

Visual Editor

Build workflows visually with drag-and-drop steps, inline previews, and one-click testing.

6 Step Types

Click, Type Text, Wait, Custom JS, If/Else branching, and Extract data from the page.

6 Trigger Types

Page load, delay, element visible, URL change, JS condition, or key press.

Variables

Extract data from elements and pass it to later steps using {{variables}}.


How It Works

  1. Open the popup on your target site and click + Add Auto-Action.
  2. Name your action and choose a trigger (when it should fire).
  3. Optionally set a URL filter to restrict which pages it runs on.
  4. Add steps — each step performs one operation in sequence.
  5. Click Test to try it on the current page, then Save.

Tip: Use the Macro Recorder to capture your clicks and typing, then convert them into auto-action steps automatically.


URL Filtering

Control which pages the action runs on:

  • All pages — runs on every page of the site
  • Pattern — wildcard matching, e.g., */video/*
  • Regex — full regular expression, e.g., /watch\?v=/

See the sub-topics in the sidebar for details on each trigger type, step type, the Extract system, and If/Else branching.


Triggers

Triggers determine when your auto-action fires.

Page LoaddomReady

Fires when the page's DOM is fully loaded and parsed. This is the most common trigger — use it for actions that should run on every page visit.

Delayms

Fires after a configurable delay (in milliseconds). Useful when you need to wait for dynamic content that loads after the DOM is ready.

Example: set to 2000 to wait 2 seconds after page load.

Element Visiblepolling

Fires when a specific element appears on the page. Uses polling to check periodically.

Great for: cookie banners, popups, or dynamically loaded content you want to auto-dismiss.

URL ChangeSPA

Fires when the URL changes without a full page reload. Essential for single-page apps (YouTube, Twitter, etc.) where navigation happens via JavaScript.

JS Conditionadvanced

Fires when a custom JavaScript expression returns true. Polled periodically.

Example: document.querySelectorAll('.item').length > 10

Key Presshotkey

Fires when a specific key combination is pressed. Like a keybinding, but triggers a full auto-action workflow.

Run modes: Once per page, Every press, or Once per session.


Step Types

Each auto-action consists of steps executed in order. Add steps via the + buttons in the editor.

Click

Click an element identified by CSS selector. Use the element picker to select it visually.

  • Selector — CSS selector for the target element
  • Element name — optional human-readable label
  • Selector index — which match to click if multiple elements match (0 = first)

Text Input

Type text into a form field.

  • Text content — what to type. Supports {{variables}}
  • Clear first — select all existing text before typing
  • Press Enter — submit after typing

Wait

Pause execution before continuing to the next step. Three modes:

ModeDescription
Time delayWait a fixed number of milliseconds.
Element visibleWait until a CSS selector matches an element on the page. Has a configurable timeout.
JS conditionWait until a JavaScript expression returns true.

Custom JS

Run arbitrary JavaScript code. Same helpers as keybinding custom code. Use ctx.get() / ctx.set() to read and write variables. See the Custom Code and ctx API pages.

Extract

Pull data from page elements into named variables for use in later steps. This is a powerful data-capture step — see Extract & Variables for full details.

If/Else

Conditional branching based on element presence or a JavaScript condition. See If/Else Branching for details.


Extract & Variables

The Extract step pulls data from page elements and stores it in named variables. Later steps can reference these variables using {{variableName}} syntax.

How to Use

  1. Add an Extract step in the auto-action editor.
  2. Enter a variable name (e.g., pageTitle).
  3. Pick an element using the element picker or type a CSS selector.
  4. Choose what to extract (text, value, attribute, etc.).
  5. Click Preview to test the extraction on the current page.
  6. In later steps, use {{pageTitle}} in text fields, or ctx.get('pageTitle') in Custom Code steps.

Extraction Targets

TargetReturnsExample use
Text ContentElement's visible textRead a heading, price, or label
Input ValueForm field valueRead what's typed in a search box
hrefLink URLCapture a link destination
AttributeAny HTML attributeRead data-id, src, aria-label, etc.
innerHTMLElement's inner HTMLCapture formatted content
outerHTMLFull element markupCapture element with its tags
Computed StyleCSS property valueRead color, display, font-size
DimensionsPosition & size objectGet width, height, top, left
Regex MatchPattern match from textExtract numbers, IDs, or patterns from text
Table/ListArray of row objectsScrape tabular data into structured arrays

Extract All Matches

Enable "Extract all matches" to capture data from every element matching the selector, not just the first.

  • Result is always an array
  • {{prices}} joins with comma: 10.00,25.00,7.50
  • {{prices[0]}} accesses the first item: 10.00
  • {{prices[2]}} accesses the third item: 7.50

Table Extraction

Extract structured data from HTML tables or repeated list elements:

// Configuration:
Row selector:  "table.prices tbody tr"
Columns:
  product  →  "td:nth-child(1)"
  price    →  "td:nth-child(2)"

// Result stored in variable: [ { product: "Widget A", price: "$10.00" }, { product: "Widget B", price: "$25.00" } ]


Transform

Apply a JavaScript expression to modify the extracted value before storing it. The raw value is available as value:

Transform expressionWhat it does
value.trim()Remove leading/trailing whitespace
parseInt(value)Convert to integer
value.replace('$', '')Remove dollar sign
value.split(',')[0]Take first comma-separated part
value.toUpperCase()Convert to uppercase

Safety: If the transform expression throws an error, the original untransformed value is kept. No data is lost.


Live Preview

Click the Preview button to run the extraction on the current page instantly. The result appears inline — green for success, red for errors. Transform is applied in the preview too.


Using Extracted Data in Custom Code

In text fields, use {{variableName}}. But in Custom JS steps, variables are accessed through the ctx API instead:

// Read a value set by a previous Extract step
const title = ctx.get('pageTitle');
const price = ctx.get('prices[0]');  // array access

// Write a new variable for later steps ctx.set('fullLabel', title + ' — ' + price);

All ctx operations are synchronous — no await needed. See the full ctx API reference for path syntax and lifecycle details.


If/Else Branching

Add conditional logic to your workflows. Run different steps based on whether an element exists or a JavaScript expression is true.

Condition Types

TypeHow it works
Element existsCheck if a CSS selector matches any element on the page. True if the element is found.
JS conditionEvaluate a JavaScript expression. True if it returns a truthy value.

Branches

  • Then — steps that run if the condition is true
  • Else — steps that run if the condition is false (optional)
  • Each branch can contain any step type: click, text, wait, JS, or even nested if/else
IF element exists: "#cookie-banner .accept-btn"
  THEN:
    Click → "#cookie-banner .accept-btn"
  ELSE:
    Wait → 2000ms
    IF element exists: ".gdpr-overlay .dismiss"
      THEN: Click → ".gdpr-overlay .dismiss"

Lazy resolution: Variables set in earlier steps of a branch are available in later steps of the same branch. Branch substeps are resolved when they execute, not when the If step is encountered.

Custom Code

Write JavaScript that runs when you press a shortcut or when an auto-action step executes. Your code has full DOM access, async/await support, and a set of built-in helper functions.

Tip: You can paste this entire page into an AI chatbot and ask it to write code for you. Just describe what you want to automate!

Rules

  • await works directly — no wrapper function needed
  • External libraries: add them via the Libraries panel on the custom-code step (fetched once at edit time, then cached offline)
  • DOM access works normally — read, modify, create any HTML element
  • Page JavaScript variables are not accessible (isolated execution context). Bundle libraries via the Libraries panel.

Examples

Click a button

$('.subscribe-button').click();

Wait for element, then click

const btn = await waitForElement('.cookie-accept');
btn.click();
toast('Done!', 'success');

Toggle video playback speed

const v = getActiveVideo();
if (v) {
  v.playbackRate = v.playbackRate === 1 ? 2 : 1;
  toast('Speed: ' + v.playbackRate + 'x');
}

Save data across page loads

let count = storage.get('clicks') || 0;
count++;
storage.set('clicks', count);
toast('Clicked ' + count + ' times');

Use a bundled library

Attach canvas-confetti via the Libraries panel (it fetches once from a CDN and caches the bundle with the action). Then reference its export directly:

confetti({ particleCount: 200, spread: 90 });

Libraries are fetched at edit time and stored offline — actions keep working with no network access. Re-fetch to update a pinned version.

See Helper Functions and ctx API in the sidebar for the complete reference.

Helper Functions

Available directly in your custom code — no imports needed.

DOM Selection

HelperDescription
$(selector)Find one element. Alias for document.querySelector()
$$(selector)Find all matching elements as an array. Alias for [...document.querySelectorAll()]
findByText(text, tag)Find an element by its visible text content. Optional tag filter (e.g., "button")
waitForElement(selector, timeout)Wait for an element to appear. Returns a Promise. Default timeout: 5000ms

Media

HelperDescription
getActiveVideo()Get the currently playing or visible <video> element
getActiveAudio()Get the currently playing <audio> element
getMedia()Alias for getActiveVideo()

Async

HelperDescription
sleep(ms)Wait for a duration. Usage: await sleep(1000)

External JS libraries are added via the Libraries panel on the custom-code step (edit time, cached offline). The library's exports become available as globals inside your code.

Storage

HelperDescription
storage.get(key)Read a saved value. Returns null if not found. Data persists across page loads.
storage.set(key, value)Save a value. Stored in localStorage with a BumbleTap prefix.
storage.remove(key)Delete a saved value.

UI

HelperDescription
toast(message)Show a notification popup. Default type: "info"
toast(message, type)Types: "success", "error", "info", "warning"

Context Objects

ObjectDescription
bindingThe keybinding object that triggered this code (keys, selector, action type, etc.)
keyEventInfo about the key press event: key, code, ctrlKey, shiftKey, etc.

ctx API

In custom JS steps, the ctx object gives you synchronous read/write access to the shared variable pool.

Why ctx instead of {{}}? Custom code is NOT interpolated with {{...}} because it would conflict with JavaScript template literals. Use ctx.get() and ctx.set() instead.

API Reference

MethodDescription
ctx.get(path)Read a variable. Supports dot/bracket paths: ctx.get('items[0].name')
ctx.set(name, value)Write a variable. Available to all subsequent steps and actions.
ctx.getAll()Get a copy of all variables as a plain object.

Examples

Read a variable from a previous Extract step
const title = ctx.get('pageTitle');
toast('Title: ' + title);
Set a variable for later steps
const count = $$('.item').length;
ctx.set('itemCount', count);
// Later steps can use {{itemCount}} in text fields
Read nested paths
// If a previous extract stored an object or array:
const first = ctx.get('prices[0]');        // array index
const name = ctx.get('user.name');        // dot path
const deep = ctx.get('data[0].items[2].id'); // deep path

Lifecycle

  • All ctx operations are synchronous — no await needed
  • Variables are pre-loaded before your code runs and written back after it completes
  • Variables persist across page navigations within the same browser session
  • Variables are shared across all actions and tabs (cross-action by design)
  • Variables clear when the browser closes

Variables

Use {{variableName}} in any text field to insert dynamic values. Variables can be built-in or created by Extract steps and custom code.

Built-in Variables

VariableValueExample output
{{date}}Current date (localized)3/10/2026
{{time}}Current time HH:MM02:30 PM
{{url}}Current page URLhttps://example.com/page
{{title}}Page titleMy Page Title
{{random}}Random 8-character stringa7f3b2x9
{{clipboard}}Clipboard contentswhatever you copied

User Variables

Create your own variables two ways:

  • Extract step — pull data from page elements into a named variable
  • ctx.set() — write a variable from custom JavaScript code

Path Syntax

Access nested data with dot notation and bracket indexes:

SyntaxResolves to
{{myVar}}The variable value (string, number, or comma-joined array)
{{items[0]}}First element of an array
{{user.name}}Nested object property
{{data[0].items[2].id}}Deep nested access

Where Variables Work

  • Text input steps and keybindings — {{email}} in the text field
  • CSS selectors.item[data-id="{{itemId}}"]
  • Wait conditions — dynamic wait targets
  • NOT in custom code — use ctx.get() instead
  • NOT in variable names — variableName is always literal

Variables Sidebar

The auto-action editor has a Variables sidebar (toggle via the header button) that shows all current variables with their names, sources (which step created them), and values. It updates after every test run.

Missing variables: {{nonexistent}} resolves to an empty string, never throws an error. If used as a selector, the step will fail with "element not found."

Macro Recorder

Record your interactions — clicks, typing, scrolling, navigation — and convert them into auto-action steps.

How to Record

  1. Open the auto-action editor and click the Record button.
  2. A dark toolbar appears at the top of the page showing recording status.
  3. Interact with the page normally — your actions are captured as steps.
  4. Click Stop in the toolbar (or press the stop button) to finish.
  5. The recorded steps appear in the auto-action editor for review and editing.

What Gets Captured

InteractionRecorded as
Clicking elementsClick step with CSS selector and element name
Typing in fieldsText Input step with selector, text, clear/enter flags
ScrollingScroll step with direction and position
Page navigationNavigate step with URL
Special keys (Enter, Tab, Escape)Special-key step with modifiers

Toolbar Controls

ControlShortcutDescription
Pause / ResumeTemporarily stop/restart recording
UndoCtrl+ZRemove the last recorded step
NoteCtrl+Shift+NAdd a text annotation to the last step
Decision PointCtrl+Shift+DMark a point where manual decisions happen
Step FeedExpand to see all recorded steps in real-time
StopEnd recording and return steps to the editor

Cross-page recording: If you navigate to a new page during recording, the recorder auto-resumes on the new page. Your steps are preserved.

Command Palette

A searchable overlay listing all your keybindings — site-specific and global. Find and execute any binding instantly.

How to Use

  1. Press the palette shortcut (configure in popup's Global Defaults under "Command Palette Shortcut").
  2. A search overlay appears. Start typing to filter bindings.
  3. Use arrow keys to navigate, Enter to execute, Esc to close.

Features

  • Fuzzy search across binding names, selectors, element names, and custom code names
  • Dimmed items — bindings whose target elements are missing on the current page appear dimmed
  • Instant execution — run any binding without remembering its shortcut
  • Shows both site-specific and global bindings applicable to the current page

Side Panel

BumbleTap ships with a Chrome side panel SPA — a dockable editor for actions, bindings, recording, and per-site settings. It opens alongside the page, or as a detached pop-out window.

Dockable sidebar

Click the BumbleTap icon or press Ctrl+Shift+Y to open the side panel in the current window.

Detachable pop-out

Click the pop-out icon to open as a floating window — useful for multi-monitor workflows.

Pin to a tab or site

Choose a binding mode so the panel stays focused on the tab or hostname you're working with, even as you switch tabs.

What's in the panel

  • Home — site dashboard, scope switcher, recent activity.
  • Auto-Actions — list, inline editor, run/test, logs, per-action variables.
  • Keybindings — inline-expand rows for add/edit/delete/duplicate.
  • Recorder — live capture + review before saving.
  • Sites — manage every registered site from one place.
  • Settings — playback, recording defaults, import/export, and binding mode defaults.

The sidebar is per window — each Chrome window has its own. Pop-outs are standalone and can follow a specific tab, a specific hostname, or the focused window.


Binding Modes

A binding mode controls which tab the side panel (or pop-out) reads bindings from and runs actions against. Change the default in Settings → Pop-out & Sidebar, or override per-instance via the pin button in the header.

ModeBehaviorBest for
Follow source window
Default
Tracks the active tab of the window the panel opened from. Switching tabs changes which site the panel shows.Everyday browsing; no commitment.
Pin to tabAnchored to one tab ID. Follows that tab across navigations and even between windows. If the tab closes, an empty state with a re-pin button appears.Editing one workflow while browsing other tabs.
Pin to hostnameAnchored to a site (e.g. youtube.com). Runs actions against the most recently active matching tab; opens a fresh tab if none is open.Comparing or testing bindings across tabs of the same site.
Follow focused window
Pop-out only
Retargets to whichever Chrome window is currently focused (debounced 250ms). Sidebars fall back to Follow source window.Floating pop-out used across multiple windows.

Action-lock

If an auto-action is running, the panel queues any incoming tab or mode changes until the run completes. Your action finishes against the hostname it started on — no mid-flight context shifts.

Edge cases

  • Pinned tab navigates to a new site → the panel follows; the tab identity is the anchor.
  • Pinned tab closes → empty state with a re-pin call-to-action.
  • Pinned tab moves to another window → the panel follows to the new window.
  • Tab is discarded (Chrome sleep) → auto-waked when an action runs.
  • No tab matches a pinned hostname → a fresh tab is opened with the last-known URL.
  • Browser restart with Pin to tab → the panel tries to re-pin to a tab whose URL matches; otherwise shows the empty state.

Per-instance override: Each pop-out tracks its own mode. Closing the pop-out discards its override — new pop-outs start from your global default.


Pop-out & Pinning

The header pin control lives next to the title: an icon button opens the mode menu, the pill next to it shows the current target (favicon + name). Click the pill to re-pin.

Opening a pop-out

  1. Open the side panel (Ctrl+Shift+Y or extension icon).
  2. Click the pop-out icon in the home header — a detached window spawns.
  3. The new pop-out starts in your global default mode (Settings → Pop-out & Sidebar).

Changing mode on a running pop-out

  1. Click the pin icon in the header (or press Ctrl+Shift+P).
  2. Pick a mode from the menu.
  3. For Pin to tab, click the target pill to choose which tab (current tab, or pick from a list).

Unsaved edits? If you're editing an action or binding when you change pin mode, BumbleTap asks before discarding the edit.


Multiple pop-outs

Each pop-out is independent. One can be pinned to youtube.com, another to a specific Jira ticket tab, a third in follow-window mode — they all work side by side.

Window title

Pop-outs update their window title with the pin target (e.g. BumbleTap — pinned to youtube.com). Handy when several pop-outs are in your taskbar.

The docked sidebar supports the same modes except Follow focused window (which is incoherent for a docked UI). Picking that mode in Settings has no effect on sidebars.


Keyboard Shortcuts

All panel-side shortcuts work in both the sidebar and the pop-out. They do not conflict with page-level bindings — BumbleTap binds them on the panel document only.

ShortcutAction
Ctrl+Shift+YOpen / toggle the side panel (Chrome command — rebind in chrome://extensions/shortcuts)
Ctrl+KOpen the command palette
Ctrl+Shift+POpen the pin / binding-mode menu
Ctrl+Shift+DCopy a debug info dump to the clipboard (pin state, cached hostname, queued changes) — share with a bug report
Ctrl+SSave the current action or binding
Ctrl+EnterRun / test the current action
Ctrl+NNew action (from the actions list)
Ctrl+RRecord new action (from the actions list)
j / kNavigate between step cards in the editor
e / SpaceExpand / collapse the selected step
EscDismiss dirty-state warnings, collapse expanded step, or go back

The Ctrl+Shift+P shortcut works even when the pin switcher is not visible (e.g. inside a step editor) — the menu appears at the top-right.

Setup & Permissions

BumbleTap requires a one-time setup for custom code features.

Enable User Scripts (Required for Custom Code)

  1. Go to chrome://extensions in your browser.
  2. Find BumbleTap and click Details.
  3. Find "Allow in Developer Mode" (or "Allow User Scripts") and turn it ON.
  4. Click the reload button (↻) on BumbleTap, then refresh any open pages.

Note: This only needs to be done once. If custom code stops working after a Chrome update, repeat these steps.

Permissions Explained

PermissionWhy it's needed
storageSave your shortcuts and settings locally on your device
unlimitedStorageStore settings for many sites without hitting the 5 MB cap
activeTabInteract with the current tab when you use a shortcut
scriptingExecute actions like clicking elements or running custom code
userScriptsRun custom JavaScript in an isolated sandbox (CSP-exempt)
tabsDetect tab switches to load the right shortcuts
webNavigationDetect page navigation for auto-actions and SPA support
contextMenusRight-click menu for creating bindings and selecting elements
clipboardReadSupport the {{clipboard}} variable in workflows
sidePanelShow the side panel editor alongside the page
Host permissionsAllow shortcuts to work on any website you choose to configure

Privacy

All your data stays on your device. BumbleTap has no servers, no accounts, and no analytics. Your settings are stored locally using Chrome's storage API. Nothing is ever transmitted.

See the Privacy Policy for full details.