Chrome Extension History API — How to Search, Read, and Delete Browser History

18 min read

History API Guide

Overview

Required Permission

Add the history permission to your manifest.json:

{
  "permissions": ["history"]
}

In Manifest V3, history permission is a “host permission” for the purposes of permission warnings. Users will see a warning indicating your extension can “Read and change all your data on all websites.”

Searching History

The chrome.history.search() method is the primary way to query browser history. It accepts a query object and returns matching history items.

// Basic search - finds pages matching text in URL or title
chrome.history.search({
  text: 'chrome extension',
  maxResults: 50
}, (results) => {
## Overview
The Chrome History API provides comprehensive access to the user's browsing history. This API allows extensions to search, read, add, and delete history entries, as well as listen for history changes in real-time.

## Required Permissions
To use the History API, add `"history"` to the permissions array in your `manifest.json`:

```json
{
  "name": "History Extension",
  "permissions": [
    "history"
  ]
}

For more details on permissions, see docs/permissions/history.md.

Data Types

HistoryItem

Returned by search and getVisits, represents a single history entry:

{
  id: "123",                    // Unique identifier
  url: "https://example.com/",  // Page URL
  title: "Example Page",        // Page title (may be empty)
  lastVisitTime: 1699900000000, // Timestamp in milliseconds
  visitCount: 5,                // Number of times visited
  typedCount: 2                 // Number of times typed directly
}

VisitItem

Returned by getVisits, represents a single visit to a URL:

{
  id: "visit123",               // Unique visit identifier
  visitId: "1",                 // Visit ID within the URL
  url: "https://example.com/",  // The visited URL
  visitTime: 1699900000000,     // Timestamp in milliseconds
  referringVisitId: "0"         // ID of the visit that led here
}

Searching History - chrome.history.search

The primary method for accessing history data. Supports text search and time-based filtering.

// Search all history (returns up to 100 results by default)
chrome.history.search({ text: '' }, (results) => {
  results.forEach(item => {
    console.log(item.title, item.url, item.lastVisitTime);
  });
});

// Search with date range
chrome.history.search({
  startTime: new Date('2024-01-01').getTime(),
  endTime: new Date('2024-12-31').getTime(),
  maxResults: 100
}, (results) => {
  // Results from specific time period
});

The search method accepts several parameters:

Each result is a HistoryItem object containing:

Getting Detailed Visit Information

The chrome.history.getVisits() method provides detailed information about all visits to a specific URL.

chrome.history.getVisits({ url: 'https://developer.chrome.com/' }, (visits) => {
  visits.forEach(visit => {
    console.log('Visit time:', visit.visitTime);
    console.log('Referrer:', visit.referrer);
    console.log('Transition:', visit.transition);

Search with Text Query

// Search for specific text in title or URL
chrome.history.search({ text: 'chrome extension' }, (results) => {
  console.log(`Found ${results.length} matching visits`);
});
// Get visits from the last 24 hours
const oneDayAgo = Date.now() - 24 * 60 * 60 * 1000;
chrome.history.search({
  text: '',
  startTime: oneDayAgo
}, (results) => {
  console.log(`Last 24 hours: ${results.length} pages visited`);
});

// Get visits from a specific date range
chrome.history.search({
  text: '',
  startTime: new Date('2024-01-01').getTime(),
  endTime: new Date('2024-01-31').getTime()
}, (results) => {
  console.log(`January 2024: ${results.length} visits`);
});

Limiting Results

// Limit to most recent 10 results
chrome.history.search({
  text: '',
  maxResults: 10
}, (results) => {
  // Only returns top 10 most recent
});

Getting Visit Details - chrome.history.getVisits

Retrieves detailed visit information for a specific URL, including navigation context.

// Get all visits for a specific URL
const url = 'https://developer.chrome.com/';
chrome.history.getVisits({ url }, (visits) => {
  visits.forEach(visit => {
    console.log('Visit ID:', visit.visitId);
    console.log('Visit Time:', new Date(visit.visitTime));
    console.log('Referring Visit:', visit.referringVisitId);
  });
});

The visit object includes:

The transition types include:

Deleting History

The History API provides multiple methods for removing browsing data.

Deleting a Single URL

chrome.history.deleteUrl({ url: 'https://example.com/bad-page' }, () => {
  console.log('URL removed from history');
});

This removes all visits to the specified URL from browser history.

Deleting by Time Range

const oneWeekAgo = Date.now() - (7 * 24 * 60 * 60 * 1000);

chrome.history.deleteRange({
  startTime: 0,
  endTime: oneWeekAgo
}, () => {
  console.log('All history older than one week deleted');
});

Deleting All History

chrome.history.deleteAll(() => {
  console.log('All browsing history cleared');
});

Use this with caution—it’s irreversible and will affect all browser profiles.

Listening for History Changes

The History API provides event listeners to track browser history changes in real-time.

chrome.history.onVisited.addListener((result) => {
  console.log('Page visited:', result.title, result.url);
  // Update extension state or trigger actions
The `referringVisitId` can trace how the user navigated to this page (e.g., from a search, direct link, or bookmark).

## Adding URLs - chrome.history.addUrl

Manually add a URL to the browsing history. Useful for tracking external links or programmatic history entries.

```javascript
// Add a URL to history
chrome.history.addUrl({
  url: 'https://example.com/'
}, () => {
  console.log('URL added to history');
});

Note: This won’t duplicate entries if the URL already exists—it will update the last visit time instead.

Deleting History

Deleting a Specific URL - chrome.history.deleteUrl

Removes all visits for a specific URL from history.

// Remove a specific URL from history
chrome.history.deleteUrl({ url: 'https://example.com/' }, () => {
  console.log('URL removed from history');
});

Deleting by Time Range - chrome.history.deleteRange

Remove history entries within a specific time period.

// Delete all history from the past week
const now = Date.now();
const oneWeekAgo = now - 7 * 24 * 60 * 60 * 1000;

chrome.history.deleteRange({
  startTime: oneWeekAgo,
  endTime: now
}, () => {
  console.log('Deleted history from the last 7 days');
});

Clearing All History - chrome.history.deleteUrl

Remove all browsing history (use with caution!).

// Clear all browsing history
chrome.history.deleteAll(() => {
  console.log('All history cleared');
});

Event Listeners

chrome.history.onVisited

Fires whenever a page is visited (user navigates to a URL).

chrome.history.onVisited.addListener((result) => {
  console.log('Page visited:', result.url);
  console.log('Title:', result.title);
  console.log('Visit time:', new Date(result.lastVisitTime));
  console.log('Total visits:', result.visitCount);
});

This event fires for every page load, so be mindful of performance when processing.

chrome.history.onVisitRemoved

Fires when one or more URLs are removed from history.

chrome.history.onVisitRemoved.addListener((removed) => {
  console.log('Removed items:', removed.allHistory, removed.urls);
  if (removed.allHistory) {
    console.log('All history was cleared');
  } else {
    console.log('Removed URLs:', removed.urls);
  }
});

Privacy Considerations

When working with the History API, developers must handle sensitive user data responsibly.

Data Sensitivity

Browser history contains deeply personal information about user behavior, including:

Best Practices

  1. Minimize permission scope: Only request history access when absolutely necessary
  2. Local processing: Process history data locally rather than transmitting to external servers
  3. Clear data promptly: Delete any cached history data when no longer needed
  4. User transparency: Clearly explain in your extension’s description why you need history access
  5. Provide controls: Give users options to exclude certain sites or time periods

User Trust

History permissions trigger significant privacy warnings in Chrome. Users are likely to be skeptical of extensions requesting this permission. Consider whether alternative approaches could achieve your goals without accessing history:

Compliance

Be aware that accessing browser history may subject your extension to additional scrutiny during the Chrome Web Store review process. Ensure your extension’s privacy policy accurately describes history data usage.

Common Mistakes

Practical Patterns


The removed object contains:

Building a History Analytics Dashboard

Here’s a practical example of building a simple history analytics extension:

// popup.js - Display recent browsing statistics

document.addEventListener('DOMContentLoaded', () => {
  const statsDiv = document.getElementById('stats');
  
  // Get today's visits
  const startOfDay = new Date();
  startOfDay.setHours(0, 0, 0, 0);
  
  chrome.history.search({
    text: '',
    startTime: startOfDay.getTime(),
    maxResults: 100
  }, (results) => {
    const uniqueDomains = new Set();
    results.forEach(item => {
      try {
        const url = new URL(item.url);
        uniqueDomains.add(url.hostname);
      } catch (e) {}
    });
    
    statsDiv.innerHTML = `
      <p>Today's visits: ${results.length}</p>
      <p>Unique domains: ${uniqueDomains.size}</p>
    `;
  });
});

Most Visited Sites Widget

// background.js - Track most visited sites

function getTopSites(callback, limit = 10) {
  chrome.history.search({ text: '' }, (results) => {
    const urlCounts = {};
    
    results.forEach(item => {
      if (item.url) {
        try {
          const domain = new URL(item.url).hostname;
          urlCounts[domain] = (urlCounts[domain] || 0) + 1;
        } catch (e) {}
      }
    });
    
    const sorted = Object.entries(urlCounts)
      .sort((a, b) => b[1] - a[1])
      .slice(0, limit);
    
    callback(sorted);
  });
}

chrome.runtime.onInstalled.addListener(() => {
  getTopSites((topSites) => {
    console.log('Top visited sites:', topSites);
  });
});

Daily History Summary

// Track daily browsing patterns
function getDailySummary() {
  const now = new Date();
  const startOfDay = new Date(now.getFullYear(), now.getMonth(), now.getDate());
  
  chrome.history.search({
    text: '',
    startTime: startOfDay.getTime(),
    maxResults: 500
  }, (results) => {
    const summary = {
      totalVisits: results.length,
      uniqueURLs: new Set(results.map(r => r.url)).size,
      topDomains: {}
    };
    
    results.forEach(item => {
      try {
        const domain = new URL(item.url).hostname;
        summary.topDomains[domain] = (summary.topDomains[domain] || 0) + 1;
      } catch (e) {}
    });
    
    // Sort and display top 5
    const top5 = Object.entries(summary.topDomains)
      .sort((a, b) => b[1] - a[1])
      .slice(0, 5);
    
    console.table(top5);
  });
}

Privacy Considerations

User Trust

Best Practices

// Always handle errors gracefully
chrome.history.search({ text: 'test' }, (results) => {
  if (chrome.runtime.lastError) {
    console.error('History API error:', chrome.runtime.lastError);
    return;
  }
  // Process results
});

// Clear sensitive data when done processing
function processHistory() {
  // Process data...
  
  // Clear sensitive information from memory
  sensitiveData = null;
}

Common Use Cases

  1. Reading List / History Manager: Allow users to save and organize interesting pages
  2. Productivity Analytics: Show users their browsing patterns (time spent, frequent sites)
  3. Bookmark Sync: Use history events to help manage bookmarks
  4. Tab Manager: Show recently visited pages to help users find lost tabs
  5. Search Enhancement: Provide quick access to frequently visited sites

Reference

For complete API documentation, see: developer.chrome.com/docs/extensions/reference/api/history


Turn Your Extension Into a Business

Ready to monetize? The Extension Monetization Playbook covers freemium models, Stripe integration, subscription architecture, and growth strategies for Chrome extension developers. —

Part of the Chrome Extension Guide by theluckystrike. Built at zovo.one.