Browse by type
The Fingerprint injector is a sparse javascript library built for stealth override of browser signatures or so-called fingerprints. Overriding browser fingerprints help simulate real user browsers.
This library can inject fingerprints to playwright and puppeteer controlled browsers through a unified interface.
It is recommended to use this library with the Apify fingerprint-generator to achieve the best results and meet the necessary fingerprint structure.
npm install fingerprint-injector
This example shows how to use fingerprint injector with browser-pool plugin system, playwright firefox browser, and the Apify fingerprint-generator
const { PlaywrightPlugin } = require('browser-pool');
const FingerprintGenerator = require('fingerprint-generator');
const { FingerprintInjector } = require('fingerprint-injector');
// An asynchronous IIFE (immediately invoked function expression)
// allows us to use the 'await' keyword.
(async () => {
const playwrightPlugin = new PlaywrightPlugin(playwright.firefox, pluginOptions);
const fingerprintGenerator = new FingerprintGenerator({
devices: ['desktop'],
browsers: [{ name: 'firefox', minVersion: 88 }],
});
const { fingerprint } = fingerprintGenerator.getFingerprint();
const fingerprintInjector = new FingerprintInjector();
const launchContext = playwrightPlugin.createLaunchContext();
const browser = await playwrightPlugin.launch(launchContext);
// Forward properties to the browserContext
const context = await browser.newContext({
userAgent: fingerprint.userAgent,
locale: fingerprint.navigator.language,
});
// Attach fingerprint
await fingerprintInjector.attachFingerprintToPlaywright(context, fingerprint);
const page = await context.newPage();
})();
This example demonstrates, how to use the fingerprint injector library with puppeteer.
const FingerprintGenerator = require('fingerprint-generator');
const { FingerprintInjector } = require('fingerprint-injector');
const puppeteer = require('puppeteer')
// An asynchronous IIFE (immediately invoked function expression)
// allows us to use the 'await' keyword.
(async () => {
const fingerprintInjector = new FingerprintInjector();
const fingerprintGenerator = new FingerprintGenerator({
devices: ['desktop'],
browsers: [{ name: 'chrome', minVersion: 88 }],
});
const { fingerprint } = fingerprintGenerator.getFingerprint();
const browser = await puppeteer.launch({headless: false})
const page = await browser.newPage();
// Attach fingerprint to page
await fingerprintInjector.attachFingerprintToPuppeteer(page, fingerprint);
// Now you can use the page
await page.goto('https://google.com')
})();
This approach handles injection for both incognito context and persistent context. It is also prepared for usage with both playwright nad puppeteer.
const { BrowserPool, PlaywrightPlugin, PuppeteerPlugin } = require('browser-pool');
const FingerprintGenerator = require('fingerprint-generator');
const { FingerprintInjector } = require('fingerprint-injector');
const playwright = require('playwright');
// An asynchronous IIFE (immediately invoked function expression)
// allows us to use the 'await' keyword.
(async () => {
const pluginOptions = {
launchOptions: {
headless: false,
channel: 'chrome',
},
};
const playwrightPlugin = new PlaywrightPlugin(playwright.chromium, pluginOptions);
const fingerprintGenerator = new FingerprintGenerator({
devices: ['desktop'],
browsers: [{ name: 'chrome', minVersion: 90 }],
operatingSystems: ['linux'],
});
const { fingerprint } = fingerprintGenerator.getFingerprint();
const fingerprintInjector = new FingerprintInjector({ fingerprint });
const browserPool = new BrowserPool({
browserPlugins: [playwrightPlugin],
preLaunchHooks: [(pageId, launchContext) => {
const { useIncognitoPages, launchOptions } = launchContext;
if (useIncognitoPages) {
return;
}
launchContext.launchOptions = {
...launchOptions,
userAgent: fingerprint.userAgent,
viewport: {
width: fingerprint.screen.width,
height: fingerprint.screen.height,
},
};
}],
prePageCreateHooks: [
(pageId, browserController, pageOptions) => {
const { launchContext } = browserController;
if (launchContext.useIncognitoPages && pageOptions) {
pageOptions.userAgent = fingerprint.userAgent;
pageOptions.viewport = {
width: fingerprint.screen.width,
height: fingerprint.screen.height,
};
}
},
],
postPageCreateHooks: [
async (page, browserController) => {
const { browserPlugin, launchContext } = browserController;
if (browserPlugin instanceof PlaywrightPlugin) {
const { useIncognitoPages, isFingerprintInjected } = launchContext;
if (isFingerprintInjected) {
// If not incognitoPages are used we would add the injection script over and over which could cause memory leaks.
return;
}
console.log('Injecting fingerprint to playwright');
const context = page.context();
await fingerprintInjector.attachFingerprintToPlaywright(context, fingerprint);
if (!useIncognitoPages) {
// If not incognitoPages are used we would add the injection script over and over which could cause memory leaks.
launchContext.extend({ isFingerprintInjected: true });
}
} else if (browserPlugin instanceof PuppeteerPlugin) {
console.log('Injecting fingerprint to puppeteer');
await fingerprintInjector.attachFingerprintToPuppeteer(page, fingerprint);
}
},
],
});
const page = await browserPool.newPage();
await page.goto('https://google.com');
})();
All public classes, methods and their parameters can be inspected in this API reference.
Fingerprint injector class.
fingerprintInjector.attachFingerprintToPlaywright(browserContext, fingerprint)Adds init script to the browser context, so the fingerprint is changed before every document creation. DISCLAIMER: Since the playwright does not support changing viewport and User-agent after the context is created, you have to set it manually when the context is created. Check the playwright usage example.
| Param | Description |
|---|---|
| browserContext | playwright browser context |
| fingerprint | fingerprint from fingerprint-generator |
fingerprintInjector.attachFingerprintToPuppeteer(page, fingerprint)Adds script that is evaluated before every document creation. Sets User-Agent and viewport using native puppeteer interface
| Param | Description |
|---|---|
| page | puppeteer page |
| fingerprint | fingerprint from fingerprint-generator |
$ claude mcp add fingerprint-injector \
-- python -m otcore.mcp_server <graph>