[{"data":1,"prerenderedAt":1808},["ShallowReactive",2],{"navigation_docs":3,"-adapters-browser":122,"-adapters-browser-surround":1803},[4,30,55,105],{"title":5,"path":6,"stem":7,"children":8,"page":29},"Getting Started","/getting-started","1.getting-started",[9,14,19,24],{"title":10,"path":11,"stem":12,"icon":13},"Introduction","/getting-started/introduction","1.getting-started/1.introduction","i-lucide-info",{"title":15,"path":16,"stem":17,"icon":18},"Installation","/getting-started/installation","1.getting-started/2.installation","i-lucide-download",{"title":20,"path":21,"stem":22,"icon":23},"Quick Start","/getting-started/quick-start","1.getting-started/3.quick-start","i-lucide-zap",{"title":25,"path":26,"stem":27,"icon":28},"Agent Skills","/getting-started/agent-skills","1.getting-started/4.agent-skills","i-lucide-sparkles",false,{"title":31,"path":32,"stem":33,"children":34,"page":29},"Core Concepts","/core-concepts","2.core-concepts",[35,40,45,50],{"title":36,"path":37,"stem":38,"icon":39},"Wide Events","/core-concepts/wide-events","2.core-concepts/1.wide-events","i-lucide-layers",{"title":41,"path":42,"stem":43,"icon":44},"Structured Errors","/core-concepts/structured-errors","2.core-concepts/2.structured-errors","i-lucide-shield-alert",{"title":46,"path":47,"stem":48,"icon":49},"Best Practices","/core-concepts/best-practices","2.core-concepts/3.best-practices","i-lucide-shield-check",{"title":51,"path":52,"stem":53,"icon":54},"Typed Fields","/core-concepts/typed-fields","2.core-concepts/4.typed-fields","i-simple-icons-typescript",{"title":56,"path":57,"stem":58,"children":59,"page":29},"Adapters","/adapters","3.adapters",[60,65,70,75,80,85,90,95,100],{"title":61,"path":62,"stem":63,"icon":64},"Overview","/adapters/overview","3.adapters/1.overview","i-custom-plug",{"title":66,"path":67,"stem":68,"icon":69},"Axiom","/adapters/axiom","3.adapters/2.axiom","i-custom-axiom",{"title":71,"path":72,"stem":73,"icon":74},"OTLP","/adapters/otlp","3.adapters/3.otlp","i-simple-icons-opentelemetry",{"title":76,"path":77,"stem":78,"icon":79},"PostHog","/adapters/posthog","3.adapters/4.posthog","i-simple-icons-posthog",{"title":81,"path":82,"stem":83,"icon":84},"Sentry","/adapters/sentry","3.adapters/5.sentry","i-simple-icons-sentry",{"title":86,"path":87,"stem":88,"icon":89},"Better Stack","/adapters/better-stack","3.adapters/6.better-stack","i-simple-icons-betterstack",{"title":91,"path":92,"stem":93,"icon":94},"Custom Adapters","/adapters/custom","3.adapters/7.custom","i-lucide-code",{"title":96,"path":97,"stem":98,"icon":99},"Pipeline","/adapters/pipeline","3.adapters/8.pipeline","i-lucide-workflow",{"title":101,"path":102,"stem":103,"icon":104},"Browser","/adapters/browser","3.adapters/9.browser","i-lucide-globe",{"title":106,"path":107,"stem":108,"children":109,"page":29},"Enrichers","/enrichers","4.enrichers",[110,113,118],{"title":61,"path":111,"stem":112,"icon":28},"/enrichers/overview","4.enrichers/1.overview",{"title":114,"path":115,"stem":116,"icon":117},"Built-in","/enrichers/built-in","4.enrichers/2.built-in","i-lucide-puzzle",{"title":119,"path":120,"stem":121,"icon":94},"Custom","/enrichers/custom","4.enrichers/3.custom",{"id":123,"title":124,"body":125,"description":1793,"extension":1794,"links":1795,"meta":1799,"navigation":1800,"path":102,"seo":1801,"stem":103,"__hash__":1802},"docs/3.adapters/9.browser.md","Browser Drain",{"type":126,"value":127,"toc":1774},"minimark",[128,132,136,342,346,403,407,414,428,616,622,625,830,834,840,913,919,982,986,1000,1005,1009,1015,1019,1172,1176,1320,1324,1334,1734,1747,1751,1770],[129,130,131],"p",{},"Most observability tools focus on server-side logs. The browser drain gives you a framework-agnostic way to send structured logs from the browser to any HTTP endpoint — no vendor SDK, no framework coupling.",[133,134,20],"h2",{"id":135},"quick-start",[137,138,144],"pre",{"className":139,"code":140,"filename":141,"language":142,"meta":143,"style":143},"language-typescript shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","import { initLogger, log } from 'evlog'\nimport { createBrowserLogDrain } from 'evlog/browser'\n\nconst drain = createBrowserLogDrain({\n  drain: { endpoint: 'https://logs.example.com/v1/ingest' },\n})\ninitLogger({ drain })\n\nlog.info({ action: 'page_view', path: location.pathname })\n","app.ts","typescript","",[145,146,147,186,207,214,236,264,273,290,295],"code",{"__ignoreMap":143},[148,149,152,156,160,164,167,170,173,176,179,183],"span",{"class":150,"line":151},"line",1,[148,153,155],{"class":154},"s7zQu","import",[148,157,159],{"class":158},"sMK4o"," {",[148,161,163],{"class":162},"sTEyZ"," initLogger",[148,165,166],{"class":158},",",[148,168,169],{"class":162}," log",[148,171,172],{"class":158}," }",[148,174,175],{"class":154}," from",[148,177,178],{"class":158}," '",[148,180,182],{"class":181},"sfazB","evlog",[148,184,185],{"class":158},"'\n",[148,187,189,191,193,196,198,200,202,205],{"class":150,"line":188},2,[148,190,155],{"class":154},[148,192,159],{"class":158},[148,194,195],{"class":162}," createBrowserLogDrain",[148,197,172],{"class":158},[148,199,175],{"class":154},[148,201,178],{"class":158},[148,203,204],{"class":181},"evlog/browser",[148,206,185],{"class":158},[148,208,210],{"class":150,"line":209},3,[148,211,213],{"emptyLinePlaceholder":212},true,"\n",[148,215,217,221,224,227,230,233],{"class":150,"line":216},4,[148,218,220],{"class":219},"spNyl","const",[148,222,223],{"class":162}," drain ",[148,225,226],{"class":158},"=",[148,228,195],{"class":229},"s2Zo4",[148,231,232],{"class":162},"(",[148,234,235],{"class":158},"{\n",[148,237,239,243,246,248,251,253,255,258,261],{"class":150,"line":238},5,[148,240,242],{"class":241},"swJcz","  drain",[148,244,245],{"class":158},":",[148,247,159],{"class":158},[148,249,250],{"class":241}," endpoint",[148,252,245],{"class":158},[148,254,178],{"class":158},[148,256,257],{"class":181},"https://logs.example.com/v1/ingest",[148,259,260],{"class":158},"'",[148,262,263],{"class":158}," },\n",[148,265,267,270],{"class":150,"line":266},6,[148,268,269],{"class":158},"}",[148,271,272],{"class":162},")\n",[148,274,276,279,281,284,286,288],{"class":150,"line":275},7,[148,277,278],{"class":229},"initLogger",[148,280,232],{"class":162},[148,282,283],{"class":158},"{",[148,285,223],{"class":162},[148,287,269],{"class":158},[148,289,272],{"class":162},[148,291,293],{"class":150,"line":292},8,[148,294,213],{"emptyLinePlaceholder":212},[148,296,298,301,304,307,309,311,314,316,318,321,323,325,328,330,333,335,338,340],{"class":150,"line":297},9,[148,299,300],{"class":162},"log",[148,302,303],{"class":158},".",[148,305,306],{"class":229},"info",[148,308,232],{"class":162},[148,310,283],{"class":158},[148,312,313],{"class":241}," action",[148,315,245],{"class":158},[148,317,178],{"class":158},[148,319,320],{"class":181},"page_view",[148,322,260],{"class":158},[148,324,166],{"class":158},[148,326,327],{"class":241}," path",[148,329,245],{"class":158},[148,331,332],{"class":162}," location",[148,334,303],{"class":158},[148,336,337],{"class":162},"pathname ",[148,339,269],{"class":158},[148,341,272],{"class":162},[133,343,345],{"id":344},"how-it-works","How It Works",[347,348,349,367,374,385,392],"ol",{},[350,351,352,355,356,355,359,362,363],"li",{},[145,353,354],{},"log.info()"," / ",[145,357,358],{},"log.warn()",[145,360,361],{},"log.error()"," push events into a ",[364,365,366],"strong",{},"memory buffer",[350,368,369,370,373],{},"Events are ",[364,371,372],{},"batched"," by size (default 25) or time interval (default 2 s)",[350,375,376,377,380,381,384],{},"Batches are sent via ",[145,378,379],{},"fetch"," with ",[145,382,383],{},"keepalive: true"," so requests survive page navigation",[350,386,387,388,391],{},"When the page becomes hidden (tab switch, navigation), buffered events are flushed via ",[145,389,390],{},"navigator.sendBeacon"," as a fallback",[350,393,394,395,398,399,402],{},"Your ",[364,396,397],{},"server endpoint"," receives a ",[145,400,401],{},"DrainContext[]"," JSON array and processes it however you like",[133,404,406],{"id":405},"two-tier-api","Two-Tier API",[408,409,411],"h3",{"id":410},"createbrowserlogdrainoptions",[145,412,413],{},"createBrowserLogDrain(options)",[129,415,416,417,420,421,424,425,303],{},"High-level, pre-composed: creates a pipeline with batching, retry, and auto-flush on ",[145,418,419],{},"visibilitychange",". Returns a ",[145,422,423],{},"PipelineDrainFn\u003CDrainContext>"," directly usable with ",[145,426,427],{},"initLogger({ drain })",[137,429,431],{"className":139,"code":430,"language":142,"meta":143,"style":143},"import { initLogger, log } from 'evlog'\nimport { createBrowserLogDrain } from 'evlog/browser'\n\nconst drain = createBrowserLogDrain({\n  drain: { endpoint: 'https://logs.example.com/v1/ingest' },\n  pipeline: { batch: { size: 50, intervalMs: 5000 } },\n})\n\ninitLogger({ drain })\nlog.info({ action: 'click', target: 'buy-button' })\n",[145,432,433,455,473,477,491,511,550,556,560,574],{"__ignoreMap":143},[148,434,435,437,439,441,443,445,447,449,451,453],{"class":150,"line":151},[148,436,155],{"class":154},[148,438,159],{"class":158},[148,440,163],{"class":162},[148,442,166],{"class":158},[148,444,169],{"class":162},[148,446,172],{"class":158},[148,448,175],{"class":154},[148,450,178],{"class":158},[148,452,182],{"class":181},[148,454,185],{"class":158},[148,456,457,459,461,463,465,467,469,471],{"class":150,"line":188},[148,458,155],{"class":154},[148,460,159],{"class":158},[148,462,195],{"class":162},[148,464,172],{"class":158},[148,466,175],{"class":154},[148,468,178],{"class":158},[148,470,204],{"class":181},[148,472,185],{"class":158},[148,474,475],{"class":150,"line":209},[148,476,213],{"emptyLinePlaceholder":212},[148,478,479,481,483,485,487,489],{"class":150,"line":216},[148,480,220],{"class":219},[148,482,223],{"class":162},[148,484,226],{"class":158},[148,486,195],{"class":229},[148,488,232],{"class":162},[148,490,235],{"class":158},[148,492,493,495,497,499,501,503,505,507,509],{"class":150,"line":238},[148,494,242],{"class":241},[148,496,245],{"class":158},[148,498,159],{"class":158},[148,500,250],{"class":241},[148,502,245],{"class":158},[148,504,178],{"class":158},[148,506,257],{"class":181},[148,508,260],{"class":158},[148,510,263],{"class":158},[148,512,513,516,518,520,523,525,527,530,532,536,538,541,543,546,548],{"class":150,"line":266},[148,514,515],{"class":241},"  pipeline",[148,517,245],{"class":158},[148,519,159],{"class":158},[148,521,522],{"class":241}," batch",[148,524,245],{"class":158},[148,526,159],{"class":158},[148,528,529],{"class":241}," size",[148,531,245],{"class":158},[148,533,535],{"class":534},"sbssI"," 50",[148,537,166],{"class":158},[148,539,540],{"class":241}," intervalMs",[148,542,245],{"class":158},[148,544,545],{"class":534}," 5000",[148,547,172],{"class":158},[148,549,263],{"class":158},[148,551,552,554],{"class":150,"line":275},[148,553,269],{"class":158},[148,555,272],{"class":162},[148,557,558],{"class":150,"line":292},[148,559,213],{"emptyLinePlaceholder":212},[148,561,562,564,566,568,570,572],{"class":150,"line":297},[148,563,278],{"class":229},[148,565,232],{"class":162},[148,567,283],{"class":158},[148,569,223],{"class":162},[148,571,269],{"class":158},[148,573,272],{"class":162},[148,575,577,579,581,583,585,587,589,591,593,596,598,600,603,605,607,610,612,614],{"class":150,"line":576},10,[148,578,300],{"class":162},[148,580,303],{"class":158},[148,582,306],{"class":229},[148,584,232],{"class":162},[148,586,283],{"class":158},[148,588,313],{"class":241},[148,590,245],{"class":158},[148,592,178],{"class":158},[148,594,595],{"class":181},"click",[148,597,260],{"class":158},[148,599,166],{"class":158},[148,601,602],{"class":241}," target",[148,604,245],{"class":158},[148,606,178],{"class":158},[148,608,609],{"class":181},"buy-button",[148,611,260],{"class":158},[148,613,172],{"class":158},[148,615,272],{"class":162},[408,617,619],{"id":618},"createbrowserdrainconfig",[145,620,621],{},"createBrowserDrain(config)",[129,623,624],{},"Low-level transport function. Use this when you want full control over the pipeline configuration:",[137,626,628],{"className":139,"code":627,"language":142,"meta":143,"style":143},"import { createBrowserDrain } from 'evlog/browser'\nimport { createDrainPipeline } from 'evlog/pipeline'\nimport type { DrainContext } from 'evlog'\n\nconst transport = createBrowserDrain({\n  endpoint: 'https://logs.example.com/v1/ingest',\n})\nconst pipeline = createDrainPipeline\u003CDrainContext>({\n  batch: { size: 100, intervalMs: 10000 },\n  retry: { maxAttempts: 5 },\n})\n\nconst drain = pipeline(transport)\n",[145,629,630,649,669,691,695,710,726,732,757,784,803,810,815],{"__ignoreMap":143},[148,631,632,634,636,639,641,643,645,647],{"class":150,"line":151},[148,633,155],{"class":154},[148,635,159],{"class":158},[148,637,638],{"class":162}," createBrowserDrain",[148,640,172],{"class":158},[148,642,175],{"class":154},[148,644,178],{"class":158},[148,646,204],{"class":181},[148,648,185],{"class":158},[148,650,651,653,655,658,660,662,664,667],{"class":150,"line":188},[148,652,155],{"class":154},[148,654,159],{"class":158},[148,656,657],{"class":162}," createDrainPipeline",[148,659,172],{"class":158},[148,661,175],{"class":154},[148,663,178],{"class":158},[148,665,666],{"class":181},"evlog/pipeline",[148,668,185],{"class":158},[148,670,671,673,676,678,681,683,685,687,689],{"class":150,"line":209},[148,672,155],{"class":154},[148,674,675],{"class":154}," type",[148,677,159],{"class":158},[148,679,680],{"class":162}," DrainContext",[148,682,172],{"class":158},[148,684,175],{"class":154},[148,686,178],{"class":158},[148,688,182],{"class":181},[148,690,185],{"class":158},[148,692,693],{"class":150,"line":216},[148,694,213],{"emptyLinePlaceholder":212},[148,696,697,699,702,704,706,708],{"class":150,"line":238},[148,698,220],{"class":219},[148,700,701],{"class":162}," transport ",[148,703,226],{"class":158},[148,705,638],{"class":229},[148,707,232],{"class":162},[148,709,235],{"class":158},[148,711,712,715,717,719,721,723],{"class":150,"line":266},[148,713,714],{"class":241},"  endpoint",[148,716,245],{"class":158},[148,718,178],{"class":158},[148,720,257],{"class":181},[148,722,260],{"class":158},[148,724,725],{"class":158},",\n",[148,727,728,730],{"class":150,"line":275},[148,729,269],{"class":158},[148,731,272],{"class":162},[148,733,734,736,739,741,743,746,750,753,755],{"class":150,"line":292},[148,735,220],{"class":219},[148,737,738],{"class":162}," pipeline ",[148,740,226],{"class":158},[148,742,657],{"class":229},[148,744,745],{"class":158},"\u003C",[148,747,749],{"class":748},"sBMFI","DrainContext",[148,751,752],{"class":158},">",[148,754,232],{"class":162},[148,756,235],{"class":158},[148,758,759,762,764,766,768,770,773,775,777,779,782],{"class":150,"line":297},[148,760,761],{"class":241},"  batch",[148,763,245],{"class":158},[148,765,159],{"class":158},[148,767,529],{"class":241},[148,769,245],{"class":158},[148,771,772],{"class":534}," 100",[148,774,166],{"class":158},[148,776,540],{"class":241},[148,778,245],{"class":158},[148,780,781],{"class":534}," 10000",[148,783,263],{"class":158},[148,785,786,789,791,793,796,798,801],{"class":150,"line":576},[148,787,788],{"class":241},"  retry",[148,790,245],{"class":158},[148,792,159],{"class":158},[148,794,795],{"class":241}," maxAttempts",[148,797,245],{"class":158},[148,799,800],{"class":534}," 5",[148,802,263],{"class":158},[148,804,806,808],{"class":150,"line":805},11,[148,807,269],{"class":158},[148,809,272],{"class":162},[148,811,813],{"class":150,"line":812},12,[148,814,213],{"emptyLinePlaceholder":212},[148,816,818,820,822,824,827],{"class":150,"line":817},13,[148,819,220],{"class":219},[148,821,223],{"class":162},[148,823,226],{"class":158},[148,825,826],{"class":229}," pipeline",[148,828,829],{"class":162},"(transport)\n",[133,831,833],{"id":832},"configuration-reference","Configuration Reference",[408,835,837],{"id":836},"browserdrainconfig",[145,838,839],{},"BrowserDrainConfig",[841,842,843,859],"table",{},[844,845,846],"thead",{},[847,848,849,853,856],"tr",{},[850,851,852],"th",{},"Option",[850,854,855],{},"Default",[850,857,858],{},"Description",[860,861,862,879,894],"tbody",{},[847,863,864,870,873],{},[865,866,867],"td",{},[145,868,869],{},"endpoint",[865,871,872],{},"—",[865,874,875,878],{},[364,876,877],{},"(required)"," Full URL of the server ingest endpoint",[847,880,881,886,891],{},[865,882,883],{},[145,884,885],{},"timeout",[865,887,888],{},[145,889,890],{},"5000",[865,892,893],{},"Request timeout in milliseconds",[847,895,896,901,906],{},[865,897,898],{},[145,899,900],{},"useBeacon",[865,902,903],{},[145,904,905],{},"true",[865,907,908,909,912],{},"Use ",[145,910,911],{},"sendBeacon"," when the page is hidden",[408,914,916],{"id":915},"browserlogdrainoptions",[145,917,918],{},"BrowserLogDrainOptions",[841,920,921,931],{},[844,922,923],{},[847,924,925,927,929],{},[850,926,852],{},[850,928,855],{},[850,930,858],{},[860,932,933,950,965],{},[847,934,935,940,942],{},[865,936,937],{},[145,938,939],{},"drain",[865,941,872],{},[865,943,944,946,947,949],{},[364,945,877],{}," ",[145,948,839],{}," object",[847,951,952,957,962],{},[865,953,954],{},[145,955,956],{},"pipeline",[865,958,959],{},[145,960,961],{},"{ batch: { size: 25, intervalMs: 2000 }, retry: { maxAttempts: 2 } }",[865,963,964],{},"Pipeline configuration overrides",[847,966,967,972,976],{},[865,968,969],{},[145,970,971],{},"autoFlush",[865,973,974],{},[145,975,905],{},[865,977,978,979,981],{},"Auto-register ",[145,980,419],{}," flush listener",[133,983,985],{"id":984},"sendbeacon-fallback","sendBeacon Fallback",[987,988,990,991,993,994,996,997,999],"callout",{"color":306,"icon":989},"i-lucide-radio","When ",[145,992,900],{}," is enabled (the default) and the page becomes hidden, the drain automatically switches from ",[145,995,379],{}," to ",[145,998,390],{},". This ensures logs are delivered even when the user closes the tab or navigates away — no data loss on page exit.",[129,1001,1002,1004],{},[145,1003,911],{}," has a browser-imposed payload limit (~64 KB). If the payload exceeds this, the drain throws an error. Keep batch sizes reasonable (the default of 25 is well within limits).",[133,1006,1008],{"id":1007},"server-endpoint","Server Endpoint",[129,1010,1011,1012,1014],{},"Your server needs a POST endpoint that accepts a ",[145,1013,401],{}," JSON body. Here are examples for common frameworks:",[408,1016,1018],{"id":1017},"express","Express",[137,1020,1023],{"className":139,"code":1021,"filename":1022,"language":142,"meta":143,"style":143},"app.post('/v1/ingest', express.json(), (req, res) => {\n  for (const entry of req.body) {\n    console.log('[BROWSER]', JSON.stringify(entry))\n  }\n  res.sendStatus(204)\n})\n","server.ts",[145,1024,1025,1080,1108,1144,1149,1166],{"__ignoreMap":143},[148,1026,1027,1030,1032,1035,1037,1039,1042,1044,1046,1049,1051,1054,1057,1059,1062,1066,1068,1071,1074,1077],{"class":150,"line":151},[148,1028,1029],{"class":162},"app",[148,1031,303],{"class":158},[148,1033,1034],{"class":229},"post",[148,1036,232],{"class":162},[148,1038,260],{"class":158},[148,1040,1041],{"class":181},"/v1/ingest",[148,1043,260],{"class":158},[148,1045,166],{"class":158},[148,1047,1048],{"class":162}," express",[148,1050,303],{"class":158},[148,1052,1053],{"class":229},"json",[148,1055,1056],{"class":162},"()",[148,1058,166],{"class":158},[148,1060,1061],{"class":158}," (",[148,1063,1065],{"class":1064},"sHdIc","req",[148,1067,166],{"class":158},[148,1069,1070],{"class":1064}," res",[148,1072,1073],{"class":158},")",[148,1075,1076],{"class":219}," =>",[148,1078,1079],{"class":158}," {\n",[148,1081,1082,1085,1087,1089,1092,1095,1098,1100,1103,1106],{"class":150,"line":188},[148,1083,1084],{"class":154},"  for",[148,1086,1061],{"class":241},[148,1088,220],{"class":219},[148,1090,1091],{"class":162}," entry",[148,1093,1094],{"class":158}," of",[148,1096,1097],{"class":162}," req",[148,1099,303],{"class":158},[148,1101,1102],{"class":162},"body",[148,1104,1105],{"class":241},") ",[148,1107,235],{"class":158},[148,1109,1110,1113,1115,1117,1119,1121,1124,1126,1128,1131,1133,1136,1138,1141],{"class":150,"line":209},[148,1111,1112],{"class":162},"    console",[148,1114,303],{"class":158},[148,1116,300],{"class":229},[148,1118,232],{"class":241},[148,1120,260],{"class":158},[148,1122,1123],{"class":181},"[BROWSER]",[148,1125,260],{"class":158},[148,1127,166],{"class":158},[148,1129,1130],{"class":162}," JSON",[148,1132,303],{"class":158},[148,1134,1135],{"class":229},"stringify",[148,1137,232],{"class":241},[148,1139,1140],{"class":162},"entry",[148,1142,1143],{"class":241},"))\n",[148,1145,1146],{"class":150,"line":216},[148,1147,1148],{"class":158},"  }\n",[148,1150,1151,1154,1156,1159,1161,1164],{"class":150,"line":238},[148,1152,1153],{"class":162},"  res",[148,1155,303],{"class":158},[148,1157,1158],{"class":229},"sendStatus",[148,1160,232],{"class":241},[148,1162,1163],{"class":534},"204",[148,1165,272],{"class":241},[148,1167,1168,1170],{"class":150,"line":266},[148,1169,269],{"class":158},[148,1171,272],{"class":162},[408,1173,1175],{"id":1174},"hono","Hono",[137,1177,1179],{"className":139,"code":1178,"filename":1022,"language":142,"meta":143,"style":143},"app.post('/v1/ingest', async (c) => {\n  const body = await c.req.json()\n  for (const entry of body) {\n    console.log('[BROWSER]', JSON.stringify(entry))\n  }\n  return c.body(null, 204)\n})\n",[145,1180,1181,1213,1241,1259,1289,1293,1314],{"__ignoreMap":143},[148,1182,1183,1185,1187,1189,1191,1193,1195,1197,1199,1202,1204,1207,1209,1211],{"class":150,"line":151},[148,1184,1029],{"class":162},[148,1186,303],{"class":158},[148,1188,1034],{"class":229},[148,1190,232],{"class":162},[148,1192,260],{"class":158},[148,1194,1041],{"class":181},[148,1196,260],{"class":158},[148,1198,166],{"class":158},[148,1200,1201],{"class":219}," async",[148,1203,1061],{"class":158},[148,1205,1206],{"class":1064},"c",[148,1208,1073],{"class":158},[148,1210,1076],{"class":219},[148,1212,1079],{"class":158},[148,1214,1215,1218,1221,1224,1227,1230,1232,1234,1236,1238],{"class":150,"line":188},[148,1216,1217],{"class":219},"  const",[148,1219,1220],{"class":162}," body",[148,1222,1223],{"class":158}," =",[148,1225,1226],{"class":154}," await",[148,1228,1229],{"class":162}," c",[148,1231,303],{"class":158},[148,1233,1065],{"class":162},[148,1235,303],{"class":158},[148,1237,1053],{"class":229},[148,1239,1240],{"class":241},"()\n",[148,1242,1243,1245,1247,1249,1251,1253,1255,1257],{"class":150,"line":209},[148,1244,1084],{"class":154},[148,1246,1061],{"class":241},[148,1248,220],{"class":219},[148,1250,1091],{"class":162},[148,1252,1094],{"class":158},[148,1254,1220],{"class":162},[148,1256,1105],{"class":241},[148,1258,235],{"class":158},[148,1260,1261,1263,1265,1267,1269,1271,1273,1275,1277,1279,1281,1283,1285,1287],{"class":150,"line":216},[148,1262,1112],{"class":162},[148,1264,303],{"class":158},[148,1266,300],{"class":229},[148,1268,232],{"class":241},[148,1270,260],{"class":158},[148,1272,1123],{"class":181},[148,1274,260],{"class":158},[148,1276,166],{"class":158},[148,1278,1130],{"class":162},[148,1280,303],{"class":158},[148,1282,1135],{"class":229},[148,1284,232],{"class":241},[148,1286,1140],{"class":162},[148,1288,1143],{"class":241},[148,1290,1291],{"class":150,"line":238},[148,1292,1148],{"class":158},[148,1294,1295,1298,1300,1302,1304,1306,1309,1312],{"class":150,"line":266},[148,1296,1297],{"class":154},"  return",[148,1299,1229],{"class":162},[148,1301,303],{"class":158},[148,1303,1102],{"class":229},[148,1305,232],{"class":241},[148,1307,1308],{"class":158},"null,",[148,1310,1311],{"class":534}," 204",[148,1313,272],{"class":241},[148,1315,1316,1318],{"class":150,"line":275},[148,1317,269],{"class":158},[148,1319,272],{"class":162},[133,1321,1323],{"id":1322},"full-control","Full Control",[129,1325,1326,1327,380,1330,1333],{},"Combine ",[145,1328,1329],{},"createBrowserDrain",[145,1331,1332],{},"createDrainPipeline"," for maximum flexibility:",[137,1335,1337],{"className":139,"code":1336,"filename":141,"language":142,"meta":143,"style":143},"import { initLogger, log } from 'evlog'\nimport type { DrainContext } from 'evlog'\nimport { createBrowserDrain } from 'evlog/browser'\nimport { createDrainPipeline } from 'evlog/pipeline'\n\nconst pipeline = createDrainPipeline\u003CDrainContext>({\n  batch: { size: 100, intervalMs: 10000 },\n  retry: { maxAttempts: 5, backoff: 'exponential' },\n  maxBufferSize: 500,\n  onDropped: (events) => {\n    console.warn(`Dropped ${events.length} browser events`)\n  },\n})\n\nconst drain = pipeline(createBrowserDrain({\n  endpoint: 'https://logs.example.com/v1/ingest',\n  timeout: 3000,\n}))\n\ninitLogger({ drain })\n\nlog.info({ action: 'app_init' })\n\n// Flush on page unload\nwindow.addEventListener('beforeunload', () => drain.flush())\n",[145,1338,1339,1361,1381,1399,1417,1421,1441,1465,1495,1507,1525,1561,1566,1572,1577,1596,1611,1624,1631,1636,1651,1656,1684,1689,1696],{"__ignoreMap":143},[148,1340,1341,1343,1345,1347,1349,1351,1353,1355,1357,1359],{"class":150,"line":151},[148,1342,155],{"class":154},[148,1344,159],{"class":158},[148,1346,163],{"class":162},[148,1348,166],{"class":158},[148,1350,169],{"class":162},[148,1352,172],{"class":158},[148,1354,175],{"class":154},[148,1356,178],{"class":158},[148,1358,182],{"class":181},[148,1360,185],{"class":158},[148,1362,1363,1365,1367,1369,1371,1373,1375,1377,1379],{"class":150,"line":188},[148,1364,155],{"class":154},[148,1366,675],{"class":154},[148,1368,159],{"class":158},[148,1370,680],{"class":162},[148,1372,172],{"class":158},[148,1374,175],{"class":154},[148,1376,178],{"class":158},[148,1378,182],{"class":181},[148,1380,185],{"class":158},[148,1382,1383,1385,1387,1389,1391,1393,1395,1397],{"class":150,"line":209},[148,1384,155],{"class":154},[148,1386,159],{"class":158},[148,1388,638],{"class":162},[148,1390,172],{"class":158},[148,1392,175],{"class":154},[148,1394,178],{"class":158},[148,1396,204],{"class":181},[148,1398,185],{"class":158},[148,1400,1401,1403,1405,1407,1409,1411,1413,1415],{"class":150,"line":216},[148,1402,155],{"class":154},[148,1404,159],{"class":158},[148,1406,657],{"class":162},[148,1408,172],{"class":158},[148,1410,175],{"class":154},[148,1412,178],{"class":158},[148,1414,666],{"class":181},[148,1416,185],{"class":158},[148,1418,1419],{"class":150,"line":238},[148,1420,213],{"emptyLinePlaceholder":212},[148,1422,1423,1425,1427,1429,1431,1433,1435,1437,1439],{"class":150,"line":266},[148,1424,220],{"class":219},[148,1426,738],{"class":162},[148,1428,226],{"class":158},[148,1430,657],{"class":229},[148,1432,745],{"class":158},[148,1434,749],{"class":748},[148,1436,752],{"class":158},[148,1438,232],{"class":162},[148,1440,235],{"class":158},[148,1442,1443,1445,1447,1449,1451,1453,1455,1457,1459,1461,1463],{"class":150,"line":275},[148,1444,761],{"class":241},[148,1446,245],{"class":158},[148,1448,159],{"class":158},[148,1450,529],{"class":241},[148,1452,245],{"class":158},[148,1454,772],{"class":534},[148,1456,166],{"class":158},[148,1458,540],{"class":241},[148,1460,245],{"class":158},[148,1462,781],{"class":534},[148,1464,263],{"class":158},[148,1466,1467,1469,1471,1473,1475,1477,1479,1481,1484,1486,1488,1491,1493],{"class":150,"line":292},[148,1468,788],{"class":241},[148,1470,245],{"class":158},[148,1472,159],{"class":158},[148,1474,795],{"class":241},[148,1476,245],{"class":158},[148,1478,800],{"class":534},[148,1480,166],{"class":158},[148,1482,1483],{"class":241}," backoff",[148,1485,245],{"class":158},[148,1487,178],{"class":158},[148,1489,1490],{"class":181},"exponential",[148,1492,260],{"class":158},[148,1494,263],{"class":158},[148,1496,1497,1500,1502,1505],{"class":150,"line":297},[148,1498,1499],{"class":241},"  maxBufferSize",[148,1501,245],{"class":158},[148,1503,1504],{"class":534}," 500",[148,1506,725],{"class":158},[148,1508,1509,1512,1514,1516,1519,1521,1523],{"class":150,"line":576},[148,1510,1511],{"class":229},"  onDropped",[148,1513,245],{"class":158},[148,1515,1061],{"class":158},[148,1517,1518],{"class":1064},"events",[148,1520,1073],{"class":158},[148,1522,1076],{"class":219},[148,1524,1079],{"class":158},[148,1526,1527,1529,1531,1534,1536,1539,1542,1545,1547,1549,1552,1554,1557,1559],{"class":150,"line":805},[148,1528,1112],{"class":162},[148,1530,303],{"class":158},[148,1532,1533],{"class":229},"warn",[148,1535,232],{"class":241},[148,1537,1538],{"class":158},"`",[148,1540,1541],{"class":181},"Dropped ",[148,1543,1544],{"class":158},"${",[148,1546,1518],{"class":162},[148,1548,303],{"class":158},[148,1550,1551],{"class":162},"length",[148,1553,269],{"class":158},[148,1555,1556],{"class":181}," browser events",[148,1558,1538],{"class":158},[148,1560,272],{"class":241},[148,1562,1563],{"class":150,"line":812},[148,1564,1565],{"class":158},"  },\n",[148,1567,1568,1570],{"class":150,"line":817},[148,1569,269],{"class":158},[148,1571,272],{"class":162},[148,1573,1575],{"class":150,"line":1574},14,[148,1576,213],{"emptyLinePlaceholder":212},[148,1578,1580,1582,1584,1586,1588,1590,1592,1594],{"class":150,"line":1579},15,[148,1581,220],{"class":219},[148,1583,223],{"class":162},[148,1585,226],{"class":158},[148,1587,826],{"class":229},[148,1589,232],{"class":162},[148,1591,1329],{"class":229},[148,1593,232],{"class":162},[148,1595,235],{"class":158},[148,1597,1599,1601,1603,1605,1607,1609],{"class":150,"line":1598},16,[148,1600,714],{"class":241},[148,1602,245],{"class":158},[148,1604,178],{"class":158},[148,1606,257],{"class":181},[148,1608,260],{"class":158},[148,1610,725],{"class":158},[148,1612,1614,1617,1619,1622],{"class":150,"line":1613},17,[148,1615,1616],{"class":241},"  timeout",[148,1618,245],{"class":158},[148,1620,1621],{"class":534}," 3000",[148,1623,725],{"class":158},[148,1625,1627,1629],{"class":150,"line":1626},18,[148,1628,269],{"class":158},[148,1630,1143],{"class":162},[148,1632,1634],{"class":150,"line":1633},19,[148,1635,213],{"emptyLinePlaceholder":212},[148,1637,1639,1641,1643,1645,1647,1649],{"class":150,"line":1638},20,[148,1640,278],{"class":229},[148,1642,232],{"class":162},[148,1644,283],{"class":158},[148,1646,223],{"class":162},[148,1648,269],{"class":158},[148,1650,272],{"class":162},[148,1652,1654],{"class":150,"line":1653},21,[148,1655,213],{"emptyLinePlaceholder":212},[148,1657,1659,1661,1663,1665,1667,1669,1671,1673,1675,1678,1680,1682],{"class":150,"line":1658},22,[148,1660,300],{"class":162},[148,1662,303],{"class":158},[148,1664,306],{"class":229},[148,1666,232],{"class":162},[148,1668,283],{"class":158},[148,1670,313],{"class":241},[148,1672,245],{"class":158},[148,1674,178],{"class":158},[148,1676,1677],{"class":181},"app_init",[148,1679,260],{"class":158},[148,1681,172],{"class":158},[148,1683,272],{"class":162},[148,1685,1687],{"class":150,"line":1686},23,[148,1688,213],{"emptyLinePlaceholder":212},[148,1690,1692],{"class":150,"line":1691},24,[148,1693,1695],{"class":1694},"sHwdD","// Flush on page unload\n",[148,1697,1699,1702,1704,1707,1709,1711,1714,1716,1718,1721,1723,1726,1728,1731],{"class":150,"line":1698},25,[148,1700,1701],{"class":162},"window",[148,1703,303],{"class":158},[148,1705,1706],{"class":229},"addEventListener",[148,1708,232],{"class":162},[148,1710,260],{"class":158},[148,1712,1713],{"class":181},"beforeunload",[148,1715,260],{"class":158},[148,1717,166],{"class":158},[148,1719,1720],{"class":158}," ()",[148,1722,1076],{"class":219},[148,1724,1725],{"class":162}," drain",[148,1727,303],{"class":158},[148,1729,1730],{"class":229},"flush",[148,1732,1733],{"class":162},"())\n",[987,1735,1738,1739,1746],{"color":1736,"icon":1737},"neutral","i-lucide-arrow-right","See the full ",[1740,1741,1745],"a",{"href":1742,"rel":1743},"https://github.com/HugoRCD/evlog/tree/main/examples/browser",[1744],"nofollow","browser example"," for a working Hono server + browser page that demonstrates the complete flow end to end.",[133,1748,1750],{"id":1749},"next-steps","Next Steps",[1752,1753,1754,1760,1765],"ul",{},[350,1755,1756,1759],{},[1740,1757,1758],{"href":62},"Adapters Overview"," — Available built-in adapters",[350,1761,1762,1764],{},[1740,1763,96],{"href":97}," — Batching, retry, and buffer overflow handling",[350,1766,1767,1769],{},[1740,1768,91],{"href":92}," — Build your own drain function",[1771,1772,1773],"style",{},"html pre.shiki code .s7zQu, html code.shiki .s7zQu{--shiki-light:#39ADB5;--shiki-light-font-style:italic;--shiki-default:#89DDFF;--shiki-default-font-style:italic;--shiki-dark:#89DDFF;--shiki-dark-font-style:italic}html pre.shiki code .sMK4o, html code.shiki .sMK4o{--shiki-light:#39ADB5;--shiki-default:#89DDFF;--shiki-dark:#89DDFF}html pre.shiki code .sTEyZ, html code.shiki .sTEyZ{--shiki-light:#90A4AE;--shiki-default:#EEFFFF;--shiki-dark:#BABED8}html pre.shiki code .sfazB, html code.shiki .sfazB{--shiki-light:#91B859;--shiki-default:#C3E88D;--shiki-dark:#C3E88D}html pre.shiki code .spNyl, html code.shiki .spNyl{--shiki-light:#9C3EDA;--shiki-default:#C792EA;--shiki-dark:#C792EA}html pre.shiki code .s2Zo4, html code.shiki .s2Zo4{--shiki-light:#6182B8;--shiki-default:#82AAFF;--shiki-dark:#82AAFF}html pre.shiki code .swJcz, html code.shiki .swJcz{--shiki-light:#E53935;--shiki-default:#F07178;--shiki-dark:#F07178}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}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 .sbssI, html code.shiki .sbssI{--shiki-light:#F76D47;--shiki-default:#F78C6C;--shiki-dark:#F78C6C}html pre.shiki code .sBMFI, html code.shiki .sBMFI{--shiki-light:#E2931D;--shiki-default:#FFCB6B;--shiki-dark:#FFCB6B}html pre.shiki code .sHdIc, html code.shiki .sHdIc{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#EEFFFF;--shiki-default-font-style:italic;--shiki-dark:#BABED8;--shiki-dark-font-style:italic}html pre.shiki code .sHwdD, html code.shiki .sHwdD{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#546E7A;--shiki-default-font-style:italic;--shiki-dark:#676E95;--shiki-dark-font-style:italic}",{"title":143,"searchDepth":188,"depth":188,"links":1775},[1776,1777,1778,1782,1786,1787,1791,1792],{"id":135,"depth":188,"text":20},{"id":344,"depth":188,"text":345},{"id":405,"depth":188,"text":406,"children":1779},[1780,1781],{"id":410,"depth":209,"text":413},{"id":618,"depth":209,"text":621},{"id":832,"depth":188,"text":833,"children":1783},[1784,1785],{"id":836,"depth":209,"text":839},{"id":915,"depth":209,"text":918},{"id":984,"depth":188,"text":985},{"id":1007,"depth":188,"text":1008,"children":1788},[1789,1790],{"id":1017,"depth":209,"text":1018},{"id":1174,"depth":209,"text":1175},{"id":1322,"depth":188,"text":1323},{"id":1749,"depth":188,"text":1750},"Framework-agnostic browser log transport — send client-side logs to your server via fetch or sendBeacon.","md",[1796,1798],{"label":1758,"icon":64,"to":62,"color":1736,"variant":1797},"subtle",{"label":96,"icon":99,"to":97,"color":1736,"variant":1797},{},{"title":101,"icon":104},{"title":124,"description":1793},"q7c_Dfpssz2gzqqn3V2mptsw778navOy2cnPzcgTUHA",[1804,1806],{"title":96,"path":97,"stem":98,"description":1805,"icon":99,"children":-1},"Batch events, retry on failure, and protect against buffer overflow with the shared drain pipeline.",{"title":61,"path":111,"stem":112,"description":1807,"icon":28,"children":-1},"Enrich your wide events with derived context like user agent, geo data, request size, and trace context. Built-in enrichers and custom enricher support.",1771081861224]