Chrome Extension Badge & Action API — How to Update Icons, Badges, and Tooltips

9 min read

Chrome Extension Badge & Action API — How to Update Icons, Badges, and Tooltips

The chrome.action API is one of the most powerful tools in a Chrome extension developer’s arsenal. It allows you to control the extension’s icon in the browser toolbar, display notification badges, set tooltips, and provide visual feedback to users without requiring them to open a popup. This guide covers everything you need to know about dynamic badge manipulation, icon management, and per-tab state handling.

Understanding the Action API

The chrome.action API (formerly chrome.browserAction in Manifest V2) provides methods to control the extension’s toolbar icon, badge text, badge background color, and tooltip. In Manifest V3, this API is essential for creating interactive extensions that communicate state changes visually.

Manifest Configuration

First, ensure your manifest.json declares the necessary permissions:

{
  "permissions": ["activeTab"],
  "action": {
    "default_icon": {
      "16": "images/icon16.png",
      "48": "images/icon48.png",
      "128": "images/icon128.png"
    },
    "default_title": "My Extension",
    "default_popup": "popup.html"
  }
}

The action key defines the default appearance of your extension’s toolbar button. You can optionally specify a default popup, but many extensions rely on dynamic updates instead.

Setting Badge Text

The badge displays a small text overlay on top of the extension icon. It’s commonly used to show unread counts, notification numbers, or status indicators.

Basic Badge Operations

// Set badge text (max 4 characters)
chrome.action.setBadgeText({ text: '5' });

// Clear the badge
chrome.action.setBadgeText({ text: '' });

// Set badge for a specific tab
chrome.action.setBadgeText({ text: '3', tabId: targetTabId });

The badge text is limited to four characters, and any additional characters will be truncated. Use empty string to clear the badge entirely.

Setting Badge Colors

By default, Chrome uses a red background for badges. You can customize both the background color and text color:

// Set badge background color (RGBA array: [red, green, blue, alpha])
chrome.action.setBadgeBackgroundColor({ color: [0, 120, 255, 255] });

// Set both color and text color
chrome.action.setBadgeBackgroundColor({ color: '#FF0000' }); // Hex also works

Color values can be specified as:

Dynamic Icon Updates

Dynamic icons allow you to change the extension’s appearance based on application state, user preferences, or environmental factors. This is particularly useful for extensions that track state, such as page analyzers, password managers, or productivity tools.

Setting Icons Programmatically

// Set icon using image paths
chrome.action.setIcon({
  path: {
    '16': 'images/icon-active16.png',
    '48': 'images/icon-active48.png',
    '128': 'images/icon-active128.png'
  }
});

// Set icon for a specific tab
chrome.action.setIcon({
  path: 'images/icon-tab-specific.png',
  tabId: targetTabId
});

Using ImageData for Dynamic Generation

For more dynamic control, you can generate icons programmatically using ImageData:

function createBadgeIcon(text, color) {
  const canvas = document.createElement('canvas');
  canvas.width = 128;
  canvas.height = 128;
  const ctx = canvas.getContext('2d');
  
  // Draw background
  ctx.fillStyle = color;
  ctx.fillRect(0, 0, 128, 128);
  
  // Draw text
  ctx.fillStyle = 'white';
  ctx.font = 'bold 80px sans-serif';
  ctx.textAlign = 'center';
  ctx.textBaseline = 'middle';
  ctx.fillText(text, 64, 64);
  
  return ctx.getImageData(0, 0, 128, 128);
}

chrome.action.setIcon({ imageData: createBadgeIcon('5', '#FF5722') });

This approach is powerful for creating badge-like indicators directly on the toolbar icon.

Per-Tab Badge Management

Chrome extensions often need different badge states for different tabs. The Action API supports this through tab-specific configuration.

Tab-Specific Badge Updates

// Update badge when a tab changes
chrome.tabs.onUpdated.addListener((tabId, changeInfo, tab) => {
  if (changeInfo.status === 'complete' && tab.url.includes('example.com')) {
    chrome.action.setBadgeText({ text: 'NEW', tabId });
    chrome.action.setBadgeBackgroundColor({ color: '#4CAF50', tabId });
  }
});

// Clear badge when leaving a page
chrome.tabs.onRemoved.addListener((tabId) => {
  chrome.action.setBadgeText({ text: '', tabId });
});

Querying Tab State

Retrieve the current action state for a specific tab:

chrome.action.getBadgeText({ tabId: targetTabId }, (result) => {
  console.log('Current badge:', result);
});

chrome.action.getTitle({ tabId: targetTabId }, (result) => {
  console.log('Current tooltip:', result);
});

Setting Tooltips and Titles

The tooltip appears when users hover over the extension icon. Dynamic tooltips provide contextual information:

// Set default tooltip
chrome.action.setTitle({ title: 'My Extension' });

// Set tab-specific tooltip
chrome.action.setTitle({ title: 'Unread: 5 messages', tabId: targetTabId });

// Get current tooltip
chrome.action.getTitle({ tabId: targetTabId }, (result) => {
  console.log(result);
});

Tooltips are particularly useful for providing quick status updates without requiring user interaction.

Practical Examples

Email Notifier Extension

// Background script for email notifier
chrome.runtime.onMessage.addListener((message) => {
  if (message.type === 'unread-count') {
    const count = message.count;
    const display = count > 999 ? '999+' : String(count);
    
    chrome.action.setBadgeText({ text: display });
    chrome.action.setBadgeBackgroundColor({ 
      color: count > 0 ? [200, 0, 0, 255] : [128, 128, 128, 255] 
    });
    chrome.action.setTitle({ 
      title: count > 0 ? `${count} unread emails` : 'All caught up!' 
    });
  }
});

Page Analyzer Extension

// Analyze page and update icon based on results
function updateIconForAnalysis(tabId, issues) {
  if (issues.critical > 0) {
    chrome.action.setIcon({
      path: { '128': 'icons/critical.png' },
      tabId
    });
    chrome.action.setBadgeText({ text: String(issues.critical), tabId });
    chrome.action.setBadgeBackgroundColor({ color: '#F44336', tabId });
  } else if (issues.warnings > 0) {
    chrome.action.setIcon({
      path: { '128': 'icons/warning.png' },
      tabId
    });
    chrome.action.setBadgeText({ text: String(issues.warnings), tabId });
    chrome.action.setBadgeBackgroundColor({ color: '#FF9800', tabId });
  } else {
    chrome.action.setIcon({
      path: { '128': 'icons/ok.png' },
      tabId
    });
    chrome.action.setBadgeText({ text: '', tabId });
    chrome.action.setBadgeBackgroundColor({ color: '#4CAF50', tabId });
  }
}

Best Practices

  1. Clear badges when no longer relevant: Always clear badges when their context no longer applies to prevent confusing users.

  2. Use appropriate colors: Choose colors that provide clear visual hierarchy. Red typically indicates alerts, green indicates success, and yellow/orange indicates warnings.

  3. Limit badge text: Keep badge text short (1-4 characters) for readability.

  4. Consider accessibility: Ensure color choices are distinguishable for users with color vision deficiencies.

  5. Throttle updates: If updating badges frequently, consider debouncing to avoid performance issues.

  6. Test per-tab behavior: Verify that tab-specific states are properly managed when tabs are created, updated, or closed.

Conclusion

The chrome.action API provides powerful tools for creating dynamic, responsive Chrome extensions. By mastering badge text, icon updates, and per-tab state management, you can create extensions that communicate important information to users at a glance. Whether you’re building a notifier, analyzer, or any extension that benefits from visual state indication, the Action API is an essential part of your development toolkit.

Remember to test your implementation across different scenarios, especially when dealing with multiple tabs and dynamic content updates.

No previous article
No next article