pageCapture Permission

5 min read

pageCapture Permission

What It Grants

Access to the chrome.pageCapture API for saving complete web pages as MHTML files.

Manifest

{
  "permissions": ["pageCapture"]
}

User Warning

None — this permission does not trigger a warning at install time.

API Access

Single method:

chrome.pageCapture.saveAsMHTML({ tabId: number }, (mhtmlData: Blob | undefined) => {
  // mhtmlData is a Blob containing the complete page as MHTML
});

Promise-based (MV3)

const mhtmlBlob = await chrome.pageCapture.saveAsMHTML({ tabId: tab.id! });

Basic Usage

How to Use pageCapture API

// Save current tab as MHTML
const [tab] = await chrome.tabs.query({ active: true, currentWindow: true });
const mhtmlBlob = await chrome.pageCapture.saveAsMHTML({ tabId: tab.id! });

// Create download link
const url = URL.createObjectURL(mhtmlBlob);
await chrome.downloads.download({
  url,
  filename: `${tab.title || 'page'}.mhtml`,
  saveAs: true
});

Web Clipper Pattern

import { createMessenger } from '@theluckystrike/webext-messaging';
import { createStorage, defineSchema } from '@theluckystrike/webext-storage';

const schema = defineSchema({ savedPages: 'string' }); // JSON array of metadata
const storage = createStorage(schema, 'sync');

type Messages = {
  SAVE_PAGE: { request: { tabId: number }; response: { success: boolean; filename: string } };
  LIST_SAVED: { request: {}; response: { pages: Array<{ title: string; url: string; date: number }> } };
};
const m = createMessenger<Messages>();

m.onMessage('SAVE_PAGE', async ({ tabId }) => {
  const tab = await chrome.tabs.get(tabId);
  const blob = await chrome.pageCapture.saveAsMHTML({ tabId });

  const filename = `saved/${Date.now()}-${(tab.title || 'page').replace(/[^a-z0-9]/gi, '_')}.mhtml`;
  const url = URL.createObjectURL(blob);
  await chrome.downloads.download({ url, filename });

  // Save metadata
  const pages = JSON.parse(await storage.get('savedPages') || '[]');
  pages.push({ title: tab.title || '', url: tab.url || '', date: Date.now() });
  await storage.set('savedPages', JSON.stringify(pages));

  return { success: true, filename };
});

Context Menu Save

chrome.runtime.onInstalled.addListener(() => {
  chrome.contextMenus.create({
    id: 'save-page-mhtml',
    title: 'Save page as MHTML',
    contexts: ['page']
  });
});

chrome.contextMenus.onClicked.addListener(async (info, tab) => {
  if (info.menuItemId === 'save-page-mhtml' && tab?.id) {
    const blob = await chrome.pageCapture.saveAsMHTML({ tabId: tab.id });
    const url = URL.createObjectURL(blob);
    await chrome.downloads.download({
      url,
      filename: `${tab.title || 'page'}.mhtml`,
      saveAs: false
    });
  }
});

What MHTML Contains

Key Characteristics

When to Use

When NOT to Use

Permission Check

import { checkPermission } from '@theluckystrike/webext-permissions';
const granted = await checkPermission('pageCapture');

Cross-References

Frequently Asked Questions

How do I save a page as MHTML?

Use chrome.pageCapture.saveAsMHTML() to save the current page as MHTML format, which preserves the complete page content.

Can I capture specific elements only?

No, pageCapture captures the entire page. For specific elements, consider using the scripting API to extract HTML. —

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

No previous article
No next article