-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathmiddleware.ts
More file actions
59 lines (53 loc) · 1.75 KB
/
middleware.ts
File metadata and controls
59 lines (53 loc) · 1.75 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
/**
* Vercel Edge Middleware — tracks AI bot visits
*/
const AI_BOTS: [string, string][] = [
['GPTBot', 'OpenAI'],
['ChatGPT-User', 'ChatGPT'],
['Google-Extended', 'Gemini'],
['ClaudeBot', 'Claude'],
['anthropic-ai', 'Anthropic'],
['PerplexityBot', 'Perplexity'],
['Bytespider', 'ByteDance'],
['Applebot-Extended', 'Apple'],
['cohere-ai', 'Cohere'],
['CCBot', 'CommonCrawl'],
]
export default function middleware(request: Request) {
const ua = request.headers.get('user-agent') || ''
const url = new URL(request.url)
if (url.pathname.startsWith('/assets/') || url.pathname.startsWith('/api/') || url.pathname.includes('.')) {
return
}
// Auto-redirect non-Chinese browsers to /en/ version (only for key pages without /en/ prefix)
if (!url.pathname.startsWith('/en/') && url.pathname !== '/en') {
const lang = request.headers.get('accept-language') || ''
const isZh = lang.startsWith('zh') || lang.includes('zh-TW') || lang.includes('zh-CN')
if (!isZh && (url.pathname === '/probe' || url.pathname === '/probe/')) {
return new Response(null, {
status: 302,
headers: { Location: `/en${url.pathname}${url.search}` },
})
}
}
for (const [sig, name] of AI_BOTS) {
if (ua.includes(sig)) {
try {
fetch(`${url.origin}/api/probe-collect-email`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
action: 'bot-visit',
bot: name,
path: url.pathname,
timestamp: new Date().toISOString(),
}),
}).catch(() => {})
} catch {}
break
}
}
}
export const config = {
matcher: ['/((?!api|_next|assets|favicon|logo|og-|sitemap|robots|llms).*)'],
}