三行代码完成集成
面向任意框架的即插即用设备智能。数分钟即可投入生产。
index.js
import { Tracio } from '@tracio/sdk'
const tracio = Tracio.init({ publicKey: '5ca175fc...' })
const { visitorId } = await tracio.getResult()选择你的框架
React
用于设备识别的第一方 React Hook
import { useVisitorId } from '@tracio/react'
function App() {
const { data: visitorId } = useVisitorId()
return <div>Visitor: {visitorId}</div>
}Next.js
面向 Next.js 的全栈设备识别集成(App Router + Pages Router)
// app/layout.tsx
import { TracioProvider } from '@tracio/react'
export default function Layout({ children }) {
return (
<TracioProvider publicKey={process.env.NEXT_PUBLIC_TRACIO_KEY!}>
{children}
</TracioProvider>
)
}Vue
用于设备识别的 Vue 3 组合式函数
<script setup>
import { useVisitorId } from '@tracio/vue'
const { data: visitorId } = useVisitorId()
</script>
<template>
<div>Visitor: {{ visitorId }}</div>
</template>Angular
用于设备识别的 Angular 可注入服务
import { Component, inject, effect } from '@angular/core'
import { TracioService } from '@tracio/angular'
@Component({ ... })
export class AppComponent {
private tracio = inject(TracioService)
constructor() {
// visitorId() is a signal — read it reactively
effect(() => console.log(this.tracio.visitorId()))
}
}Cloudflare
通过 Cloudflare Workers 实现的代理集成,用于第一方路由
// Cloudflare Worker
export default {
async fetch(request, env) {
const url = new URL(request.url)
if (url.pathname.startsWith('/tracio/')) {
return fetch('https://edge.tracio.ai' + url.pathname)
}
return fetch(request)
}
}AWS CloudFront
通过 CloudFront Lambda@Edge origin-request 函数实现的代理集成
// Lambda@Edge function
exports.handler = async (event) => {
const request = event.Records[0].cf.request
if (request.uri.startsWith('/tracio/')) {
request.origin = {
custom: {
domainName: 'edge.tracio.ai',
protocol: 'https',
}
}
}
return request
}Google Tag Manager
通过 GTM 自定义 HTML 代码加载设备识别代理
<!-- GTM Custom HTML Tag -->
<script>
(function() {
var script = document.createElement('script');
// Public key travels in the s.js query string (?k=...)
script.src = 'https://edge.tracio.ai/s.js?k=your-public-key';
script.onload = function() {
window.Tracio.load()
.then(function(tc) { return tc.get(); })
.then(function(result) {
dataLayer.push({
event: 'tracio_loaded',
visitorId: result.visitorId
});
});
};
document.head.appendChild(script);
})();
</script>Go
在 Go 中接收并验证识别 webhook(标准库)
package main
import (
"fmt"
"io"
"net/http"
)
func main() {
http.HandleFunc("/webhook/tracio", func(w http.ResponseWriter, r *http.Request) {
body, _ := io.ReadAll(r.Body)
// verify r.Header.Get("X-Tracio-Signature") against body, then act
fmt.Println(string(body))
w.WriteHeader(http.StatusOK)
})
http.ListenAndServe(":8080", nil)
}Rust
在 Rust 中使用 Axum 实现的高性能 webhook 验证
use axum::{body::Bytes, http::HeaderMap, routing::post, Router};
async fn webhook(headers: HeaderMap, body: Bytes) -> &'static str {
// verify headers["x-tracio-signature"] against body, then act
println!("{}", String::from_utf8_lossy(&body));
"OK"
}
#[tokio::main]
async fn main() {
let app = Router::new().route("/webhook/tracio", post(webhook));
let listener = tokio::net::TcpListener::bind("0.0.0.0:3000").await.unwrap();
axum::serve(listener, app).await.unwrap();
}Node.js
在 Node.js 与 Express 中接收并验证识别 webhook
import express from 'express'
const app = express()
// Capture the raw body so the signature can be verified byte-for-byte.
app.use(express.json({ verify: (req, _res, buf) => ((req as any).rawBody = buf) }))
// Identification events are pushed here in real time
app.post('/webhook/tracio', (req, res) => {
const event = req.body
console.log(event.visitorId, event.bot.result)
res.status(200).send('OK')
})
app.listen(3000)