{"id":18710752,"url":"https://github.com/apify/fingerprint-injector","last_synced_at":"2025-11-03T16:30:56.974Z","repository":{"id":43210442,"uuid":"378844617","full_name":"apify/fingerprint-injector","owner":"apify","description":"Home of fingerprint injector.","archived":false,"fork":false,"pushed_at":"2022-07-25T12:52:50.000Z","size":93,"stargazers_count":68,"open_issues_count":0,"forks_count":8,"subscribers_count":10,"default_branch":"master","last_synced_at":"2025-04-11T22:11:26.323Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/apify.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2021-06-21T07:31:14.000Z","updated_at":"2025-03-14T12:32:48.000Z","dependencies_parsed_at":"2022-09-12T23:41:55.350Z","dependency_job_id":null,"html_url":"https://github.com/apify/fingerprint-injector","commit_stats":null,"previous_names":[],"tags_count":4,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/apify%2Ffingerprint-injector","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/apify%2Ffingerprint-injector/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/apify%2Ffingerprint-injector/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/apify%2Ffingerprint-injector/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/apify","download_url":"https://codeload.github.com/apify/fingerprint-injector/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248560145,"owners_count":21124601,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-11-07T12:35:34.443Z","updated_at":"2025-11-03T16:30:56.937Z","avatar_url":"https://github.com/apify.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# (DEPRECATED) Fingerprint injector\n---\n\n**DEPRECATED** The `fingerprint-injector` package now lives in the [fingerprint-suite](https://github.com/apify/fingerprint-suite) repository. This repository is no longer actively maintained.\n\n---\nThe 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.\nThis library can inject fingerprints to `playwright` and `puppeteer` controlled browsers through a unified interface.\nIt is recommended to use this library with the Apify [`fingerprint-generator`](https://github.com/apify/fingerprint-generator) to achieve the best results and meet the necessary fingerprint structure.\n\n\u003c!-- toc --\u003e\n\n- [Installation](#installation)\n- [Usage with the playwright](#usage-with-the-playwright)\n- [Usage with the puppeteer](#usage-with-the-puppeteer)\n- [Advanced usage with the Browser pool hooks system](#advanced-usage-with-the-browser-pool-hooks-system)\n- [API Reference](#api-reference)\n\n\u003c!-- tocstop --\u003e\n\n## Installation\n\n```bash\nnpm install fingerprint-injector\n```\n\n## Usage with the playwright\nThis example shows how to use fingerprint injector with `browser-pool` plugin system, `playwright` firefox browser, and the Apify [`fingerprint-generator`](https://github.com/apify/fingerprint-generator)\n\n```js\nconst { PlaywrightPlugin } = require('browser-pool');\nconst FingerprintGenerator = require('fingerprint-generator');\nconst { FingerprintInjector }  = require('fingerprint-injector');\n\n// An asynchronous IIFE (immediately invoked function expression)\n// allows us to use the 'await' keyword.\n(async () =\u003e {\n    const playwrightPlugin = new PlaywrightPlugin(playwright.firefox, pluginOptions);\n    \n    const fingerprintGenerator = new FingerprintGenerator({\n        devices: ['desktop'],\n        browsers: [{ name: 'firefox', minVersion: 88 }],\n    });\n\n    const { fingerprint } = fingerprintGenerator.getFingerprint();\n\n    const fingerprintInjector = new FingerprintInjector();\n\n    const launchContext = playwrightPlugin.createLaunchContext();\n    const browser = await playwrightPlugin.launch(launchContext);\n    // Forward properties to the browserContext\n    const context = await browser.newContext({\n        userAgent: fingerprint.userAgent,\n        locale: fingerprint.navigator.language,\n    });\n   // Attach fingerprint\n   await fingerprintInjector.attachFingerprintToPlaywright(context, fingerprint);\n\n   const page = await context.newPage();\n})();\n```\n\n## Usage with the puppeteer\nThis example demonstrates, how to use the fingerprint injector library with puppeteer.\n```js\nconst FingerprintGenerator = require('fingerprint-generator');\nconst { FingerprintInjector } = require('fingerprint-injector');\nconst puppeteer = require('puppeteer')\n\n// An asynchronous IIFE (immediately invoked function expression)\n// allows us to use the 'await' keyword.\n(async () =\u003e {\n    const fingerprintInjector = new FingerprintInjector();\n\n    const fingerprintGenerator = new FingerprintGenerator({\n        devices: ['desktop'],\n        browsers: [{ name: 'chrome', minVersion: 88 }],\n    });\n\n    const { fingerprint } = fingerprintGenerator.getFingerprint();\n    const browser = await puppeteer.launch({headless: false})\n    const page = await browser.newPage();\n    // Attach fingerprint to page\n    await fingerprintInjector.attachFingerprintToPuppeteer(page, fingerprint);\n    // Now you can use the page\n    await page.goto('https://google.com')\n\n})();\n```\n## Advanced usage with the Browser pool hooks system\nThis approach handles injection for both incognito context and persistent context. It is also prepared for usage with both playwright nad puppeteer.\n\n```js\nconst { BrowserPool, PlaywrightPlugin, PuppeteerPlugin } = require('browser-pool');\nconst FingerprintGenerator = require('fingerprint-generator');\nconst { FingerprintInjector } = require('fingerprint-injector');\nconst playwright = require('playwright');\n\n// An asynchronous IIFE (immediately invoked function expression)\n// allows us to use the 'await' keyword.\n(async () =\u003e {\n    const pluginOptions = {\n        launchOptions: {\n            headless: false,\n            channel: 'chrome',\n        },\n    };\n\n    const playwrightPlugin = new PlaywrightPlugin(playwright.chromium, pluginOptions);\n    const fingerprintGenerator = new FingerprintGenerator({\n        devices: ['desktop'],\n        browsers: [{ name: 'chrome', minVersion: 90 }],\n        operatingSystems: ['linux'],\n    });\n\n    const { fingerprint } = fingerprintGenerator.getFingerprint();\n    const fingerprintInjector = new FingerprintInjector({ fingerprint });\n\n    const browserPool = new BrowserPool({\n        browserPlugins: [playwrightPlugin],\n        preLaunchHooks: [(pageId, launchContext) =\u003e {\n            const { useIncognitoPages, launchOptions } = launchContext;\n\n            if (useIncognitoPages) {\n                return;\n            }\n\n            launchContext.launchOptions = {\n                ...launchOptions,\n                userAgent: fingerprint.userAgent,\n                viewport: {\n                    width: fingerprint.screen.width,\n                    height: fingerprint.screen.height,\n                },\n\n            };\n        }],\n        prePageCreateHooks: [\n            (pageId, browserController, pageOptions) =\u003e {\n                const { launchContext } = browserController;\n\n                if (launchContext.useIncognitoPages \u0026\u0026 pageOptions) {\n                    pageOptions.userAgent = fingerprint.userAgent;\n                    pageOptions.viewport = {\n                        width: fingerprint.screen.width,\n                        height: fingerprint.screen.height,\n                    };\n                }\n            },\n        ],\n        postPageCreateHooks: [\n            async (page, browserController) =\u003e {\n                const { browserPlugin, launchContext } = browserController;\n\n                if (browserPlugin instanceof PlaywrightPlugin) {\n                    const { useIncognitoPages, isFingerprintInjected } = launchContext;\n\n                    if (isFingerprintInjected) {\n                        // If not incognitoPages are used we would add the injection script over and over which could cause memory leaks.\n                        return;\n                    }\n                    console.log('Injecting fingerprint to playwright');\n\n                    const context = page.context();\n                    await fingerprintInjector.attachFingerprintToPlaywright(context, fingerprint);\n\n                    if (!useIncognitoPages) {\n                        // If not incognitoPages are used we would add the injection script over and over which could cause memory leaks.\n                        launchContext.extend({ isFingerprintInjected: true });\n                    }\n                } else if (browserPlugin instanceof PuppeteerPlugin) {\n                    console.log('Injecting fingerprint to puppeteer');\n                    await fingerprintInjector.attachFingerprintToPuppeteer(page, fingerprint);\n                }\n            },\n        ],\n    });\n\n    const page = await browserPool.newPage();\n    await page.goto('https://google.com');\n})();\n\n```\n## API Reference\nAll public classes, methods and their parameters can be inspected in this API reference.\n\n\u003ca name=\"FingerprintInjector\"\u003e\u003c/a\u003e\n\n### FingerprintInjector\nFingerprint injector class.\n\n\n* [FingerprintInjector](#FingerprintInjector)\n    * [`.attachFingerprintToPlaywright(browserContext, fingerprint)`](#FingerprintInjector+attachFingerprintToPlaywright)\n    * [`.attachFingerprintToPuppeteer(page, fingerprint)`](#FingerprintInjector+attachFingerprintToPuppeteer)\n\n\n* * *\n\n\u003ca name=\"FingerprintInjector+attachFingerprintToPlaywright\"\u003e\u003c/a\u003e\n\n#### `fingerprintInjector.attachFingerprintToPlaywright(browserContext, fingerprint)`\nAdds init script to the browser context, so the fingerprint is changed before every document creation.\nDISCLAIMER: Since the playwright does not support changing viewport and User-agent after the context is created,\nyou have to set it manually when the context is created. Check the playwright usage example.\n\n\n| Param | Description |\n| --- | --- |\n| browserContext | playwright browser context |\n| fingerprint | fingerprint from [`fingerprint-generator`](https://github.com/apify/fingerprint-generator) |\n\n\n* * *\n\n\u003ca name=\"FingerprintInjector+attachFingerprintToPuppeteer\"\u003e\u003c/a\u003e\n\n#### `fingerprintInjector.attachFingerprintToPuppeteer(page, fingerprint)`\nAdds script that is evaluated before every document creation.\nSets User-Agent and viewport using native puppeteer interface\n\n\n| Param | Description |\n| --- | --- |\n| page | puppeteer page |\n| fingerprint | fingerprint from [`fingerprint-generator`](https://github.com/apify/fingerprint-generator) |\n\n\n* * *\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fapify%2Ffingerprint-injector","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fapify%2Ffingerprint-injector","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fapify%2Ffingerprint-injector/lists"}