Low-level utilities for working with entropy components and generating custom fingerprints from collected browser characteristics.
Converts a dictionary of entropy components into a short hash string (visitor identifier).
/**
* Converts a dictionary of components into a short hash string
* Designed for extending the library with custom components
* @param components - Dictionary of entropy components
* @returns Hashed visitor identifier string
*/
function hashComponents(components: UnknownComponents): string;Usage Examples:
import { hashComponents } from '@fingerprintjs/fingerprintjs';
// Hash standard components from get() result
const fp = await FingerprintJS.load();
const result = await fp.get();
const customHash = hashComponents(result.components);
// Hash custom component set
const customComponents = {
userAgent: { value: navigator.userAgent, duration: 1 },
language: { value: navigator.language, duration: 0 },
timezone: { value: Intl.DateTimeFormat().resolvedOptions().timeZone, duration: 2 }
};
const customFingerprint = hashComponents(customComponents);
// Create fingerprints from filtered components
const filteredComponents = Object.fromEntries(
Object.entries(result.components).filter(([name]) =>
['canvas', 'webgl', 'audio'].includes(name)
)
);
const filteredHash = hashComponents(filteredComponents);Converts a dictionary of components into a human-readable debug format.
/**
* Converts a dictionary of components into human-friendly debug format
* Useful for debugging and development purposes
* @param components - Dictionary of entropy components
* @returns Human-readable string representation
*/
function componentsToDebugString(components: UnknownComponents): string;Usage Examples:
import { componentsToDebugString } from '@fingerprintjs/fingerprintjs';
const fp = await FingerprintJS.load();
const result = await fp.get();
// Generate debug output for all components
const debugString = componentsToDebugString(result.components);
console.log('Fingerprint components:');
console.log(debugString);
// Debug specific component subset
const audioComponents = {
audio: result.components.audio,
audioBaseLatency: result.components.audioBaseLatency
};
const audioDebug = componentsToDebugString(audioComponents);
console.log('Audio components:', audioDebug);Advanced patterns for creating custom fingerprinting workflows using component utilities.
Component Filtering:
import { hashComponents, componentsToDebugString } from '@fingerprintjs/fingerprintjs';
const fp = await FingerprintJS.load();
const result = await fp.get();
// Create privacy-focused fingerprint (exclude fonts, canvas)
const privacyComponents = Object.fromEntries(
Object.entries(result.components).filter(([name]) =>
!['fonts', 'canvas', 'domBlockers'].includes(name)
)
);
const privacyFingerprint = hashComponents(privacyComponents);
// Create performance-focused fingerprint (only fast components)
const fastComponents = Object.fromEntries(
Object.entries(result.components).filter(([_, component]) =>
component.duration < 10 // Under 10ms
)
);
const fastFingerprint = hashComponents(fastComponents);Component Analysis:
// Analyze component reliability
const result = await fp.get();
const componentStats = Object.entries(result.components).map(([name, component]) => ({
name,
success: 'value' in component,
duration: component.duration,
hasError: 'error' in component
}));
// Find most reliable components
const reliableComponents = componentStats
.filter(stat => stat.success && stat.duration < 50)
.sort((a, b) => a.duration - b.duration);
console.log('Most reliable components:', reliableComponents);
// Debug failed components
const failedComponents = componentStats.filter(stat => !stat.success);
if (failedComponents.length > 0) {
console.warn('Failed components:',
componentsToDebugString(
Object.fromEntries(
failedComponents.map(stat => [stat.name, result.components[stat.name]])
)
)
);
}Custom Hash Generation:
// Generate multiple fingerprint variants
const result = await fp.get();
// Stable fingerprint (hardware-focused)
const stableComponents = ['hardwareConcurrency', 'deviceMemory', 'colorDepth', 'screenResolution'];
const stableHash = hashComponents(
Object.fromEntries(
stableComponents.map(name => [name, result.components[name]])
)
);
// Dynamic fingerprint (behavior-focused)
const dynamicComponents = ['timezone', 'languages', 'platform', 'cookiesEnabled'];
const dynamicHash = hashComponents(
Object.fromEntries(
dynamicComponents.map(name => [name, result.components[name]])
)
);
// Combined approach
const combinedHash = hashComponents({
stable: { value: stableHash, duration: 0 },
dynamic: { value: dynamicHash, duration: 0 },
timestamp: { value: Date.now(), duration: 0 }
});Common patterns for integrating component analysis into applications.
Development and Debugging:
// Development fingerprint analysis
if (process.env.NODE_ENV === 'development') {
const result = await fp.get();
console.group('Fingerprint Analysis');
console.log('Visitor ID:', result.visitorId);
console.log('Confidence:', result.confidence);
console.log('Components:', componentsToDebugString(result.components));
// Component performance analysis
const slowComponents = Object.entries(result.components)
.filter(([_, component]) => component.duration > 100)
.map(([name, component]) => ({ name, duration: component.duration }));
if (slowComponents.length > 0) {
console.warn('Slow components:', slowComponents);
}
console.groupEnd();
}A/B Testing Fingerprints:
// Test different fingerprinting strategies
const result = await fp.get();
const strategies = {
full: result.visitorId,
minimal: hashComponents({
platform: result.components.platform,
userAgent: result.components.languages,
screenResolution: result.components.screenResolution
}),
canvas: hashComponents({
canvas: result.components.canvas,
webglBasics: result.components.webglBasics,
fonts: result.components.fonts
})
};
// Use different strategies based on use case
const fingerprintStrategy = getFingerprintStrategy(); // Your logic
const selectedFingerprint = strategies[fingerprintStrategy];