@thumbmarkjs/vue
Vue 3 integration for ThumbmarkJS - the world's best free browser fingerprinting JavaScript library.
Installation
npm install @thumbmarkjs/thumbmarkjs @thumbmarkjs/vue
Quick Start
1. Install the plugin
import { createApp } from 'vue';
import { createThumbmarkPlugin } from '@thumbmarkjs/vue';
import App from './App.vue';
const app = createApp(App);
app.use(createThumbmarkPlugin());
app.mount('#app');
2. Use the composable in your components
<template>
<div>
<div v-if="isLoading">Generating thumbmark...</div>
<div v-else-if="error">Error: {{ error.message }}</div>
<div v-else>
<h3>Your Thumbmark:</h3>
<code>{{ thumbmark }}</code>
</div>
</div>
</template>
<script setup>
import { useThumbmark } from '@thumbmarkjs/vue';
const { thumbmark, isLoading, error } = useThumbmark();
</script>
API Reference
createThumbmarkPlugin
Creates a Vue plugin that provides ThumbmarkJS functionality to your application.
Parameters
options | object | No | Configuration options |
options.apiKey | string | No | Your ThumbmarkJS API key |
options.options | object | No | ThumbmarkJS configuration |
Basic Usage
import { createThumbmarkPlugin } from '@thumbmarkjs/vue';
app.use(createThumbmarkPlugin());
With API Key
app.use(createThumbmarkPlugin({
apiKey: 'your-api-key-here'
}));
With Custom Options
app.use(createThumbmarkPlugin({
apiKey: 'your-api-key',
options: {
timeout: 3000,
exclude: ['webgl'],
logging: false,
cache_api_call: true
}
}));
useThumbmark Composable
The useThumbmark composable provides reactive access to the thumbmark data.
Returns
thumbmark | Ref<string | null> | The generated thumbmark (reactive) |
isLoading | Ref<boolean> | Whether the thumbmark is being generated |
error | Ref<Error | null> | Any error that occurred during generation |
reload | () => Promise<void> | Function to regenerate the thumbmark |
Example Usage
<template>
<div>
<button @click="handleReload" :disabled="isLoading">
{{ isLoading ? 'Generating...' : 'Regenerate Thumbmark' }}
</button>
<div v-if="error" style="color: red;">
Error: {{ error.message }}
</div>
<div v-if="thumbmark">
<h3>Thumbmark:</h3>
<code style="word-break: break-all;">{{ thumbmark }}</code>
</div>
</div>
</template>
<script setup>
import { useThumbmark } from '@thumbmarkjs/vue';
const { thumbmark, isLoading, error, reload } = useThumbmark();
const handleReload = async () => {
try {
await reload();
console.log('Thumbmark regenerated!');
} catch (err) {
console.error('Failed to reload thumbmark:', err);
}
};
</script>
Configuration Options
The plugin accepts all ThumbmarkJS configuration options:
exclude | string[] | [] | Components to exclude from fingerprinting |
include | string[] | [] | Only include specific components |
permissions_to_check | string[] | All | Specific permissions to check |
timeout | number | 5000 | Timeout in milliseconds |
logging | boolean | true | Enable/disable logging |
cache_api_call | boolean | false | Cache API responses for current page load |
performance | boolean | false | Include performance metrics |
For complete documentation of options, see the core ThumbmarkJS documentation.
Usage Examples
Component with Watchers
<template>
<div>
<h2>Thumbmark Monitor</h2>
<p>Thumbmark: {{ thumbmark || 'Not generated yet' }}</p>
<p>Status: {{ status }}</p>
<button @click="reload">Refresh</button>
</div>
</template>
<script setup>
import { computed, watch } from 'vue';
import { useThumbmark } from '@thumbmarkjs/vue';
const { thumbmark, isLoading, error, reload } = useThumbmark();
const status = computed(() => {
if (isLoading.value) return 'Loading...';
if (error.value) return `Error: ${error.value.message}`;
return 'Ready';
});
// Watch for thumbmark changes
watch(thumbmark, (newThumbmark) => {
if (newThumbmark) {
console.log('New thumbmark generated:', newThumbmark);
}
});
// Watch for errors
watch(error, (newError) => {
if (newError) {
console.error('Thumbmark error:', newError);
}
});
</script>
Conditional Rendering
<template>
<div>
<!-- Loading state -->
<div v-if="isLoading" class="loading">
<span>🔄 Generating unique identifier...</span>
</div>
<!-- Error state -->
<div v-else-if="error" class="error">
<p>❌ {{ error.message }}</p>
<button @click="reload" class="retry-btn">
Try Again
</button>
</div>
<!-- Success state -->
<div v-else-if="thumbmark" class="success">
<h3>✅ Browser Identified</h3>
<details>
<summary>View Thumbmark</summary>
<code class="thumbmark">{{ thumbmark }}</code>
</details>
<button @click="reload">Generate New</button>
</div>
</div>
</template>
<script setup>
import { useThumbmark } from '@thumbmarkjs/vue';
const { thumbmark, isLoading, error, reload } = useThumbmark();
</script>
<style scoped>
.loading {
padding: 20px;
text-align: center;
}
.error {
padding: 20px;
color: #d32f2f;
}
.success {
padding: 20px;
}
.thumbmark {
display: block;
background: #f5f5f5;
padding: 10px;
word-break: break-all;
font-family: monospace;
}
.retry-btn {
margin-top: 10px;
padding: 8px 16px;
background: #1976d2;
color: white;
border: none;
border-radius: 4px;
cursor: pointer;
}
</style>
Nuxt.js Usage
Nuxt 3
import { createThumbmarkPlugin } from '@thumbmarkjs/vue';
export default defineNuxtPlugin((nuxtApp) => {
nuxtApp.vueApp.use(createThumbmarkPlugin({
apiKey: process.env.THUMBMARK_API_KEY
}));
});
<!-- pages/index.vue -->
<template>
<div>
<h1>Nuxt 3 + ThumbmarkJS</h1>
<ClientOnly>
<ThumbmarkDisplay />
</ClientOnly>
</div>
</template>
<script setup>
// Component will only render on client-side
</script>
Error Handling
<template>
<div>
<div v-if="error" class="error-container">
<h3>Fingerprinting Failed</h3>
<p>{{ error.message }}</p>
<button @click="handleRetry">Retry</button>
</div>
</div>
</template>
<script setup>
import { useThumbmark } from '@thumbmarkjs/vue';
const { error, reload } = useThumbmark();
const handleRetry = async () => {
try {
await reload();
} catch (retryError) {
console.error('Retry failed:', retryError);
}
};
</script>
TypeScript Support
This package includes full TypeScript support:
<script setup lang="ts">
import { useThumbmark } from '@thumbmarkjs/vue';
import type { UseThumbmarkResult } from '@thumbmarkjs/vue';
const thumbmarkData: UseThumbmarkResult = useThumbmark();
// All properties are properly typed
const { thumbmark, isLoading, error, reload } = thumbmarkData;
</script>
Global Properties (Options API)
If you're using the Options API, the thumbmark instance is available as $thumbmark:
<script>
export default {
async mounted() {
try {
const result = await this.$thumbmark.get();
console.log('Thumbmark:', result.thumbmark);
} catch (error) {
console.error('Failed to get thumbmark:', error);
}
}
}
</script>
License
MIT License - see the LICENSE file for details.