Install the SDK
Install the Composite Analytics SDK using your preferred package manager:
npm install @composite-inc/composite-js
Manifest Configuration
Your Chrome Extension’s manifest.json needs specific permissions to enable analytics and session recording.
Required Permissions
{
"manifest_version": 3,
"name": "Your Extension",
"version": "1.0.0",
"permissions": [
"storage",
"tabs"
],
"host_permissions": [
"https://prod.alb.us.api.composite.com/*"
],
"background": {
"service_worker": "background.js",
"type": "module"
},
"content_scripts": [
{
"matches": ["<all_urls>"],
"js": ["content.js"]
}
]
}
Permission Breakdown
| Permission | Purpose |
|---|
storage | Persist user identity and session data |
tabs | Access tab information for session context |
host_permissions | Allow API requests to Composite servers |
Adding a new host permission will trigger a permission request for all existing users. If your extension doesn’t already have <all_urls> in your host_permissions or content script matches, adding prod.alb.us.api.composite.com will prompt users to re-approve permissions on update.To avoid this, you can route analytics through a domain you already have permission for. See Custom Proxy for configuration options.
Alternative: Programmatic Injection
If you don’t want to declare content scripts in your manifest (to avoid permission changes for existing users), you can use the chrome.scripting API to inject scripts programmatically:
{
"manifest_version": 3,
"name": "Your Extension",
"version": "1.0.0",
"permissions": [
"storage",
"scripting",
"activeTab"
],
"host_permissions": [
"https://prod.alb.us.api.composite.com/*"
],
"background": {
"service_worker": "background.js",
"type": "module"
}
}
Then inject the content script from your background script:
// background.js - Inject content script programmatically
import { HttpTransport, createBackgroundHandler } from '@composite-inc/composite-js';
const transport = new HttpTransport({
apiKey: 'pk_your_api_key',
apiHost: 'https://prod.alb.us.api.composite.com',
});
createBackgroundHandler(transport);
// Inject when user clicks extension icon
chrome.action.onClicked.addListener(async (tab) => {
if (tab.id) {
await chrome.scripting.executeScript({
target: { tabId: tab.id },
files: ['content.js']
});
}
});
// Or inject on specific URLs
chrome.tabs.onUpdated.addListener(async (tabId, changeInfo, tab) => {
if (changeInfo.status === 'complete' && tab.url?.includes('your-app.com')) {
await chrome.scripting.executeScript({
target: { tabId },
files: ['content.js']
});
}
});
Using chrome.scripting with activeTab only grants access when the user interacts with your extension. This avoids broad permission warnings but means recording only starts after user interaction.
Content Security Policy
For some extensions, you may need to adjust the Content Security Policy:
{
"content_security_policy": {
"extension_pages": "script-src 'self'; object-src 'self'"
}
}
What’s Next?