[{"data":1,"prerenderedAt":971},["ShallowReactive",2],{"docs-\u002Fdocs\u002Fjavascript-reference":3,"docs-nav":952},{"id":4,"title":5,"body":6,"description":944,"extension":945,"meta":946,"navigation":698,"order":199,"path":947,"section":948,"seo":949,"stem":950,"__hash__":951},"docs\u002Fdocs\u002Fjavascript-reference.md","JavaScript SDK – Reference",{"type":7,"value":8,"toc":924},"minimark",[9,14,31,36,163,203,206,210,216,228,241,250,253,297,307,309,315,318,337,339,345,359,378,380,386,394,423,426,456,458,469,472,481,483,487,497,499,503,506,606,608,612,619,669,671,675,679,751,827,831,920],[10,11,13],"h2",{"id":12},"constructor","Constructor",[15,16,21],"pre",{"className":17,"code":18,"language":19,"meta":20,"style":20},"language-javascript shiki shiki-themes github-light github-dark","const bb = new BlockBots(options)\n","javascript","",[22,23,24],"code",{"__ignoreMap":20},[25,26,29],"span",{"class":27,"line":28},"line",1,[25,30,18],{},[32,33,35],"h3",{"id":34},"options","Options",[37,38,39,58],"table",{},[40,41,42],"thead",{},[43,44,45,49,52,55],"tr",{},[46,47,48],"th",{},"Option",[46,50,51],{},"Type",[46,53,54],{},"Default",[46,56,57],{},"Description",[59,60,61,84,104,123,143],"tbody",{},[43,62,63,69,74,77],{},[64,65,66],"td",{},[22,67,68],{},"apiKey",[64,70,71],{},[22,72,73],{},"string",[64,75,76],{},"—",[64,78,79,83],{},[80,81,82],"strong",{},"Required."," Your site API key from the dashboard. Throws if missing",[43,85,86,91,96,101],{},[64,87,88],{},[22,89,90],{},"retries",[64,92,93],{},[22,94,95],{},"number",[64,97,98],{},[22,99,100],{},"3",[64,102,103],{},"Number of verification attempts before the visitor is blocked",[43,105,106,111,115,120],{},[64,107,108],{},[22,109,110],{},"delay",[64,112,113],{},[22,114,95],{},[64,116,117],{},[22,118,119],{},"1000",[64,121,122],{},"Delay in milliseconds between attempts",[43,124,125,130,135,140],{},[64,126,127],{},[22,128,129],{},"challengeToken",[64,131,132],{},[22,133,134],{},"string | false",[64,136,137],{},[22,138,139],{},"false",[64,141,142],{},"Optional token issued by your backend, sent along with the fingerprints",[43,144,145,150,155,160],{},[64,146,147],{},[22,148,149],{},"ui",[64,151,152],{},[22,153,154],{},"boolean",[64,156,157],{},[22,158,159],{},"true",[64,161,162],{},"Show the built-in loading \u002F captcha \u002F blocked overlay",[15,164,166],{"className":17,"code":165,"language":19,"meta":20,"style":20},"const bb = new BlockBots({\n  apiKey: 'YOUR_API_KEY',\n  retries: 2,\n  delay: 1500,\n  ui: false  \u002F\u002F disable the overlay, handle the UI yourself\n})\n",[22,167,168,173,179,185,191,197],{"__ignoreMap":20},[25,169,170],{"class":27,"line":28},[25,171,172],{},"const bb = new BlockBots({\n",[25,174,176],{"class":27,"line":175},2,[25,177,178],{},"  apiKey: 'YOUR_API_KEY',\n",[25,180,182],{"class":27,"line":181},3,[25,183,184],{},"  retries: 2,\n",[25,186,188],{"class":27,"line":187},4,[25,189,190],{},"  delay: 1500,\n",[25,192,194],{"class":27,"line":193},5,[25,195,196],{},"  ui: false  \u002F\u002F disable the overlay, handle the UI yourself\n",[25,198,200],{"class":27,"line":199},6,[25,201,202],{},"})\n",[204,205],"hr",{},[10,207,209],{"id":208},"methods","Methods",[32,211,213],{"id":212},"bbverify",[22,214,215],{},"bb.verify()",[217,218,219,220,223,224,227],"p",{},"Runs the verification flow and fires either ",[22,221,222],{},"onVerified"," or ",[22,225,226],{},"onBlocked",".",[217,229,230,231,234,235,237,238,240],{},"Returns ",[22,232,233],{},"Promise\u003Cboolean>"," — ",[22,236,159],{}," if verified as human, ",[22,239,139],{}," if blocked or on error.",[15,242,244],{"className":17,"code":243,"language":19,"meta":20,"style":20},"await bb.verify()\n",[22,245,246],{"__ignoreMap":20},[25,247,248],{"class":27,"line":28},[25,249,243],{},[217,251,252],{},"Flow:",[254,255,256,264,278,285,288],"ol",{},[257,258,259,260,263],"li",{},"If the ",[22,261,262],{},"__bb_decision"," cookie is present, the visitor is already blocked — stop",[257,265,266,267,270,271,274,275],{},"If the session cookies ",[22,268,269],{},"__bbst"," \u002F ",[22,272,273],{},"__bbts"," are missing, collect signals and ",[22,276,277],{},"POST \u002Fv1\u002Fjs",[257,279,280,281,284],{},"If the API returns ",[22,282,283],{},"status: 'challenge'",", show the captcha, submit the solution, and re-send the signals with the resulting captcha token",[257,286,287],{},"Wait for the session cookies (up to 3 s), then validate them against the API",[257,289,290,291,293,294,296],{},"On failure, retry from step 2 up to ",[22,292,90],{}," times, waiting ",[22,295,110],{}," ms between attempts",[298,299,300],"blockquote",{},[217,301,302,303,306],{},"Call ",[22,304,305],{},"verify()"," once per page load. Visitors with valid session cookies are verified without re-fingerprinting.",[204,308],{},[32,310,312],{"id":311},"bbonverifiedcallback",[22,313,314],{},"bb.onVerified(callback)",[217,316,317],{},"Fires when the visitor is verified as human.",[15,319,321],{"className":17,"code":320,"language":19,"meta":20,"style":20},"bb.onVerified(() => {\n  document.getElementById('app').style.display = 'block'\n})\n",[22,322,323,328,333],{"__ignoreMap":20},[25,324,325],{"class":27,"line":28},[25,326,327],{},"bb.onVerified(() => {\n",[25,329,330],{"class":27,"line":175},[25,331,332],{},"  document.getElementById('app').style.display = 'block'\n",[25,334,335],{"class":27,"line":181},[25,336,202],{},[204,338],{},[32,340,342],{"id":341},"bbonblockedcallback",[22,343,344],{},"bb.onBlocked(callback)",[217,346,347,348,350,351,354,355,358],{},"Fires when the visitor is identified as a bot or verification does not succeed within ",[22,349,90],{},". The callback receives a ",[22,352,353],{},"reason"," string (currently ",[22,356,357],{},"'validation_failed'",").",[15,360,362],{"className":17,"code":361,"language":19,"meta":20,"style":20},"bb.onBlocked((reason) => {\n  console.log('Blocked reason:', reason)\n})\n",[22,363,364,369,374],{"__ignoreMap":20},[25,365,366],{"class":27,"line":28},[25,367,368],{},"bb.onBlocked((reason) => {\n",[25,370,371],{"class":27,"line":175},[25,372,373],{},"  console.log('Blocked reason:', reason)\n",[25,375,376],{"class":27,"line":181},[25,377,202],{},[204,379],{},[32,381,383],{"id":382},"bbonerrorcallback",[22,384,385],{},"bb.onError(callback)",[217,387,388,389,391,392,227],{},"Fires on an unexpected failure inside the flow (network error, invalid API key, bad server response). ",[22,390,305],{}," then resolves to ",[22,393,139],{},[15,395,397],{"className":17,"code":396,"language":19,"meta":20,"style":20},"bb.onError((error) => {\n  console.error('Verification error:', error)\n  \u002F\u002F Recommended: fail open so legitimate users are not blocked\n  showApp()\n})\n",[22,398,399,404,409,414,419],{"__ignoreMap":20},[25,400,401],{"class":27,"line":28},[25,402,403],{},"bb.onError((error) => {\n",[25,405,406],{"class":27,"line":175},[25,407,408],{},"  console.error('Verification error:', error)\n",[25,410,411],{"class":27,"line":181},[25,412,413],{},"  \u002F\u002F Recommended: fail open so legitimate users are not blocked\n",[25,415,416],{"class":27,"line":187},[25,417,418],{},"  showApp()\n",[25,420,421],{"class":27,"line":193},[25,422,202],{},[217,424,425],{},"All three event methods return the instance, so the setup can be chained:",[15,427,429],{"className":17,"code":428,"language":19,"meta":20,"style":20},"new BlockBots({ apiKey: 'YOUR_API_KEY', retries: 1 })\n  .onVerified(() => document.getElementById('app').style.display = 'block')\n  .onBlocked((reason) => console.log('Blocked:', reason))\n  .onError((e) => console.error(e))\n  .verify()\n",[22,430,431,436,441,446,451],{"__ignoreMap":20},[25,432,433],{"class":27,"line":28},[25,434,435],{},"new BlockBots({ apiKey: 'YOUR_API_KEY', retries: 1 })\n",[25,437,438],{"class":27,"line":175},[25,439,440],{},"  .onVerified(() => document.getElementById('app').style.display = 'block')\n",[25,442,443],{"class":27,"line":181},[25,444,445],{},"  .onBlocked((reason) => console.log('Blocked:', reason))\n",[25,447,448],{"class":27,"line":187},[25,449,450],{},"  .onError((e) => console.error(e))\n",[25,452,453],{"class":27,"line":193},[25,454,455],{},"  .verify()\n",[204,457],{},[32,459,461,464,465],{"id":460},"blockbotssetloaderblocked-static",[22,462,463],{},"BlockBots.setLoaderBlocked()"," ",[466,467,468],"em",{},"(static)",[217,470,471],{},"Shows the built-in overlay in its blocked state, independently of the verification flow.",[15,473,475],{"className":17,"code":474,"language":19,"meta":20,"style":20},"BlockBots.setLoaderBlocked()\n",[22,476,477],{"__ignoreMap":20},[25,478,479],{"class":27,"line":28},[25,480,474],{},[204,482],{},[10,484,486],{"id":485},"captcha-challenge","Captcha challenge",[217,488,489,490,492,493,496],{},"When the API is not confident about the visitor's IP (VPN, proxy, datacenter ranges) it responds with ",[22,491,283],{}," instead of a decision. The SDK then renders a proof-of-work captcha, submits the solution to the API, and retries the verification automatically with the returned captcha token. No integration work is required on your side — but keep the overlay enabled (",[22,494,495],{},"ui: true",") or provide your own visible container, otherwise the visitor cannot solve it.",[204,498],{},[10,500,502],{"id":501},"data-collected","Data collected",[217,504,505],{},"The SDK collects the following signals and sends them to the BlockBots API for analysis. No data is sold or shared with third parties.",[37,507,508,517],{},[40,509,510],{},[43,511,512,515],{},[46,513,514],{},"Signal",[46,516,57],{},[59,518,519,527,535,543,551,561,569,577,585,593],{},[43,520,521,524],{},[64,522,523],{},"Canvas fingerprint",[64,525,526],{},"Rendering signature of the browser's canvas",[43,528,529,532],{},[64,530,531],{},"Browser leaks fingerprint",[64,533,534],{},"Secondary canvas fingerprint using the BrowserLeaks technique",[43,536,537,540],{},[64,538,539],{},"User agent",[64,541,542],{},"Full browser user agent string",[43,544,545,548],{},[64,546,547],{},"Operating system",[64,549,550],{},"Parsed from the user agent",[43,552,553,556],{},[64,554,555],{},"Browser language",[64,557,558],{},[22,559,560],{},"navigator.language",[43,562,563,566],{},[64,564,565],{},"Timezone",[64,567,568],{},"IANA timezone name and UTC offset",[43,570,571,574],{},[64,572,573],{},"Automation signals",[64,575,576],{},"Headless \u002F automation markers exposed by the browser",[43,578,579,582],{},[64,580,581],{},"Pointer activity",[64,583,584],{},"Aggregated mouse and touch movement features",[43,586,587,590],{},[64,588,589],{},"IP address",[64,591,592],{},"Resolved server-side from the request",[43,594,595,598],{},[64,596,597],{},"Session tokens",[64,599,600,601,270,603,605],{},"Current ",[22,602,269],{},[22,604,273],{}," cookie values",[204,607],{},[10,609,611],{"id":610},"session-cookies","Session cookies",[217,613,614,615,618],{},"After a successful verification the SDK stores session cookies so the visitor is not re-fingerprinted on the next page load. All cookies are set client-side with ",[22,616,617],{},"Secure"," and a 240-second lifetime.",[37,620,621,630],{},[40,622,623],{},[43,624,625,628],{},[46,626,627],{},"Cookie",[46,629,57],{},[59,631,632,641,650,660],{},[43,633,634,638],{},[64,635,636],{},[22,637,269],{},[64,639,640],{},"Session token",[43,642,643,647],{},[64,644,645],{},[22,646,273],{},[64,648,649],{},"Timestamp token",[43,651,652,657],{},[64,653,654],{},[22,655,656],{},"__bbjwt",[64,658,659],{},"JWT issued by the BlockBots API (when enabled for your site)",[43,661,662,666],{},[64,663,664],{},[22,665,262],{},[64,667,668],{},"Set when the visitor is blocked; short-circuits further checks",[204,670],{},[10,672,674],{"id":673},"framework-integration","Framework integration",[32,676,678],{"id":677},"vue-3","Vue 3",[15,680,682],{"className":17,"code":681,"language":19,"meta":20,"style":20},"\u002F\u002F botcheck.js\nimport { BlockBots } from 'https:\u002F\u002Fcdn.jsdelivr.net\u002Fgh\u002Fblockbots-org\u002Fblockbots-js@main\u002Fblockbots.esm.js'\n\nexport function runBotCheck() {\n  return new Promise((resolve) => {\n    const bb = new BlockBots({ apiKey: import.meta.env.VITE_BLOCKBOTS_KEY })\n    bb.onVerified(() => resolve(true))\n    bb.onBlocked(() => resolve(false))\n    bb.onError(() => resolve(true)) \u002F\u002F fail open\n    bb.verify()\n  })\n}\n",[22,683,684,689,694,700,705,710,715,721,727,733,739,745],{"__ignoreMap":20},[25,685,686],{"class":27,"line":28},[25,687,688],{},"\u002F\u002F botcheck.js\n",[25,690,691],{"class":27,"line":175},[25,692,693],{},"import { BlockBots } from 'https:\u002F\u002Fcdn.jsdelivr.net\u002Fgh\u002Fblockbots-org\u002Fblockbots-js@main\u002Fblockbots.esm.js'\n",[25,695,696],{"class":27,"line":181},[25,697,699],{"emptyLinePlaceholder":698},true,"\n",[25,701,702],{"class":27,"line":187},[25,703,704],{},"export function runBotCheck() {\n",[25,706,707],{"class":27,"line":193},[25,708,709],{},"  return new Promise((resolve) => {\n",[25,711,712],{"class":27,"line":199},[25,713,714],{},"    const bb = new BlockBots({ apiKey: import.meta.env.VITE_BLOCKBOTS_KEY })\n",[25,716,718],{"class":27,"line":717},7,[25,719,720],{},"    bb.onVerified(() => resolve(true))\n",[25,722,724],{"class":27,"line":723},8,[25,725,726],{},"    bb.onBlocked(() => resolve(false))\n",[25,728,730],{"class":27,"line":729},9,[25,731,732],{},"    bb.onError(() => resolve(true)) \u002F\u002F fail open\n",[25,734,736],{"class":27,"line":735},10,[25,737,738],{},"    bb.verify()\n",[25,740,742],{"class":27,"line":741},11,[25,743,744],{},"  })\n",[25,746,748],{"class":27,"line":747},12,[25,749,750],{},"}\n",[15,752,756],{"className":753,"code":754,"language":755,"meta":20,"style":20},"language-vue shiki shiki-themes github-light github-dark","\u003C!-- App.vue -->\n\u003Cscript setup>\nimport { runBotCheck } from '.\u002Fbotcheck'\nconst allowed = await runBotCheck()\n\u003C\u002Fscript>\n","vue",[22,757,758,764,781,797,818],{"__ignoreMap":20},[25,759,760],{"class":27,"line":28},[25,761,763],{"class":762},"sJ8bj","\u003C!-- App.vue -->\n",[25,765,766,770,774,778],{"class":27,"line":175},[25,767,769],{"class":768},"sVt8B","\u003C",[25,771,773],{"class":772},"s9eBZ","script",[25,775,777],{"class":776},"sScJk"," setup",[25,779,780],{"class":768},">\n",[25,782,783,787,790,793],{"class":27,"line":181},[25,784,786],{"class":785},"szBVR","import",[25,788,789],{"class":768}," { runBotCheck } ",[25,791,792],{"class":785},"from",[25,794,796],{"class":795},"sZZnC"," '.\u002Fbotcheck'\n",[25,798,799,802,806,809,812,815],{"class":27,"line":187},[25,800,801],{"class":785},"const",[25,803,805],{"class":804},"sj4cs"," allowed",[25,807,808],{"class":785}," =",[25,810,811],{"class":785}," await",[25,813,814],{"class":776}," runBotCheck",[25,816,817],{"class":768},"()\n",[25,819,820,823,825],{"class":27,"line":193},[25,821,822],{"class":768},"\u003C\u002F",[25,824,773],{"class":772},[25,826,780],{"class":768},[32,828,830],{"id":829},"react","React",[15,832,834],{"className":17,"code":833,"language":19,"meta":20,"style":20},"\u002F\u002F useBotCheck.js\nimport { useEffect, useState } from 'react'\nimport { BlockBots } from 'https:\u002F\u002Fcdn.jsdelivr.net\u002Fgh\u002Fblockbots-org\u002Fblockbots-js@main\u002Fblockbots.esm.js'\n\nexport function useBotCheck(apiKey) {\n  const [status, setStatus] = useState('pending') \u002F\u002F 'pending' | 'verified' | 'blocked'\n\n  useEffect(() => {\n    const bb = new BlockBots({ apiKey })\n    bb.onVerified(() => setStatus('verified'))\n    bb.onBlocked(() => setStatus('blocked'))\n    bb.onError(() => setStatus('verified')) \u002F\u002F fail open\n    bb.verify()\n  }, [])\n\n  return status\n}\n",[22,835,836,841,846,850,854,859,864,868,873,878,883,888,893,898,904,909,915],{"__ignoreMap":20},[25,837,838],{"class":27,"line":28},[25,839,840],{},"\u002F\u002F useBotCheck.js\n",[25,842,843],{"class":27,"line":175},[25,844,845],{},"import { useEffect, useState } from 'react'\n",[25,847,848],{"class":27,"line":181},[25,849,693],{},[25,851,852],{"class":27,"line":187},[25,853,699],{"emptyLinePlaceholder":698},[25,855,856],{"class":27,"line":193},[25,857,858],{},"export function useBotCheck(apiKey) {\n",[25,860,861],{"class":27,"line":199},[25,862,863],{},"  const [status, setStatus] = useState('pending') \u002F\u002F 'pending' | 'verified' | 'blocked'\n",[25,865,866],{"class":27,"line":717},[25,867,699],{"emptyLinePlaceholder":698},[25,869,870],{"class":27,"line":723},[25,871,872],{},"  useEffect(() => {\n",[25,874,875],{"class":27,"line":729},[25,876,877],{},"    const bb = new BlockBots({ apiKey })\n",[25,879,880],{"class":27,"line":735},[25,881,882],{},"    bb.onVerified(() => setStatus('verified'))\n",[25,884,885],{"class":27,"line":741},[25,886,887],{},"    bb.onBlocked(() => setStatus('blocked'))\n",[25,889,890],{"class":27,"line":747},[25,891,892],{},"    bb.onError(() => setStatus('verified')) \u002F\u002F fail open\n",[25,894,896],{"class":27,"line":895},13,[25,897,738],{},[25,899,901],{"class":27,"line":900},14,[25,902,903],{},"  }, [])\n",[25,905,907],{"class":27,"line":906},15,[25,908,699],{"emptyLinePlaceholder":698},[25,910,912],{"class":27,"line":911},16,[25,913,914],{},"  return status\n",[25,916,918],{"class":27,"line":917},17,[25,919,750],{},[921,922,923],"style",{},"html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .sJ8bj, html code.shiki .sJ8bj{--shiki-default:#6A737D;--shiki-dark:#6A737D}html pre.shiki code .sVt8B, html code.shiki .sVt8B{--shiki-default:#24292E;--shiki-dark:#E1E4E8}html pre.shiki code .s9eBZ, html code.shiki .s9eBZ{--shiki-default:#22863A;--shiki-dark:#85E89D}html pre.shiki code .sScJk, html code.shiki .sScJk{--shiki-default:#6F42C1;--shiki-dark:#B392F0}html pre.shiki code .szBVR, html code.shiki .szBVR{--shiki-default:#D73A49;--shiki-dark:#F97583}html pre.shiki code .sZZnC, html code.shiki .sZZnC{--shiki-default:#032F62;--shiki-dark:#9ECBFF}html pre.shiki code .sj4cs, html code.shiki .sj4cs{--shiki-default:#005CC5;--shiki-dark:#79B8FF}",{"title":20,"searchDepth":175,"depth":175,"links":925},[926,929,937,938,939,940],{"id":12,"depth":175,"text":13,"children":927},[928],{"id":34,"depth":181,"text":35},{"id":208,"depth":175,"text":209,"children":930},[931,932,933,934,935],{"id":212,"depth":181,"text":215},{"id":311,"depth":181,"text":314},{"id":341,"depth":181,"text":344},{"id":382,"depth":181,"text":385},{"id":460,"depth":181,"text":936},"BlockBots.setLoaderBlocked() (static)",{"id":485,"depth":175,"text":486},{"id":501,"depth":175,"text":502},{"id":610,"depth":175,"text":611},{"id":673,"depth":175,"text":674,"children":941},[942,943],{"id":677,"depth":181,"text":678},{"id":829,"depth":181,"text":830},"Complete reference for the BlockBots JavaScript SDK — constructor options, methods, and events.","md",{},"\u002Fdocs\u002Fjavascript-reference","JavaScript SDK",{"title":5,"description":944},"docs\u002Fjavascript-reference","0u7OuP3ieYzmCcefw-WOZdy01MXk2dmMHVhDOzsooaw",[953,957,961,964,965,968],{"title":954,"path":955,"order":28,"section":956},"Getting Started","\u002Fdocs\u002Fgetting-started","Introduction",{"title":958,"path":959,"order":181,"section":960},"PHP – Quick Start","\u002Fdocs\u002Fphp-quickstart","PHP Integration",{"title":962,"path":963,"order":193,"section":948},"JavaScript SDK – Quick Start","\u002Fdocs\u002Fjavascript-quickstart",{"title":5,"path":947,"order":199,"section":948},{"title":966,"path":967,"order":717,"section":966},"WordPress Plugin","\u002Fdocs\u002Fwordpress-plugin",{"title":969,"path":970,"order":723,"section":966},"WordPress Plugin – Settings Guide","\u002Fdocs\u002Fwordpress-reference",1790770390587]