[{"data":1,"prerenderedAt":1954},["ShallowReactive",2],{"navigation_docs":3,"-adapters-browser":122,"-adapters-browser-surround":1949},[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":1939,"extension":1940,"links":1941,"meta":1945,"navigation":1946,"path":102,"seo":1947,"stem":103,"__hash__":1948},"docs/3.adapters/9.browser.md","Browser Drain",{"type":126,"value":127,"toc":1919},"minimark",[128,132,136,342,346,403,407,414,428,616,622,625,830,834,840,936,942,1005,1009,1023,1028,1032,1035,1129,1153,1157,1163,1167,1318,1322,1466,1470,1480,1879,1892,1896,1915],[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,902,917],"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,888],{},[865,882,883],{},[145,884,885],{},"headers",[865,887,872],{},[865,889,890,891,893,894,897,898,901],{},"Custom headers sent with each ",[145,892,379],{}," request (e.g. ",[145,895,896],{},"Authorization",", ",[145,899,900],{},"X-API-Key",")",[847,903,904,909,914],{},[865,905,906],{},[145,907,908],{},"timeout",[865,910,911],{},[145,912,913],{},"5000",[865,915,916],{},"Request timeout in milliseconds",[847,918,919,924,929],{},[865,920,921],{},[145,922,923],{},"useBeacon",[865,925,926],{},[145,927,928],{},"true",[865,930,931,932,935],{},"Use ",[145,933,934],{},"sendBeacon"," when the page is hidden",[408,937,939],{"id":938},"browserlogdrainoptions",[145,940,941],{},"BrowserLogDrainOptions",[841,943,944,954],{},[844,945,946],{},[847,947,948,950,952],{},[850,949,852],{},[850,951,855],{},[850,953,858],{},[860,955,956,973,988],{},[847,957,958,963,965],{},[865,959,960],{},[145,961,962],{},"drain",[865,964,872],{},[865,966,967,969,970,972],{},[364,968,877],{}," ",[145,971,839],{}," object",[847,974,975,980,985],{},[865,976,977],{},[145,978,979],{},"pipeline",[865,981,982],{},[145,983,984],{},"{ batch: { size: 25, intervalMs: 2000 }, retry: { maxAttempts: 2 } }",[865,986,987],{},"Pipeline configuration overrides",[847,989,990,995,999],{},[865,991,992],{},[145,993,994],{},"autoFlush",[865,996,997],{},[145,998,928],{},[865,1000,1001,1002,1004],{},"Auto-register ",[145,1003,419],{}," flush listener",[133,1006,1008],{"id":1007},"sendbeacon-fallback","sendBeacon Fallback",[1010,1011,1013,1014,1016,1017,1019,1020,1022],"callout",{"color":306,"icon":1012},"i-lucide-radio","When ",[145,1015,923],{}," is enabled (the default) and the page becomes hidden, the drain automatically switches from ",[145,1018,379],{}," to ",[145,1021,390],{},". This ensures logs are delivered even when the user closes the tab or navigates away — no data loss on page exit.",[129,1024,1025,1027],{},[145,1026,934],{}," 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,1029,1031],{"id":1030},"authentication","Authentication",[129,1033,1034],{},"Pass custom headers to protect your ingest endpoint:",[137,1036,1038],{"className":139,"code":1037,"language":142,"meta":143,"style":143},"const drain = createBrowserLogDrain({\n  drain: {\n    endpoint: 'https://logs.example.com/v1/ingest',\n    headers: {\n      'Authorization': 'Bearer ' + token,\n    },\n  },\n})\n",[145,1039,1040,1054,1063,1078,1087,1113,1118,1123],{"__ignoreMap":143},[148,1041,1042,1044,1046,1048,1050,1052],{"class":150,"line":151},[148,1043,220],{"class":219},[148,1045,223],{"class":162},[148,1047,226],{"class":158},[148,1049,195],{"class":229},[148,1051,232],{"class":162},[148,1053,235],{"class":158},[148,1055,1056,1058,1060],{"class":150,"line":188},[148,1057,242],{"class":241},[148,1059,245],{"class":158},[148,1061,1062],{"class":158}," {\n",[148,1064,1065,1068,1070,1072,1074,1076],{"class":150,"line":209},[148,1066,1067],{"class":241},"    endpoint",[148,1069,245],{"class":158},[148,1071,178],{"class":158},[148,1073,257],{"class":181},[148,1075,260],{"class":158},[148,1077,725],{"class":158},[148,1079,1080,1083,1085],{"class":150,"line":216},[148,1081,1082],{"class":241},"    headers",[148,1084,245],{"class":158},[148,1086,1062],{"class":158},[148,1088,1089,1092,1094,1096,1098,1100,1103,1105,1108,1111],{"class":150,"line":238},[148,1090,1091],{"class":158},"      '",[148,1093,896],{"class":241},[148,1095,260],{"class":158},[148,1097,245],{"class":158},[148,1099,178],{"class":158},[148,1101,1102],{"class":181},"Bearer ",[148,1104,260],{"class":158},[148,1106,1107],{"class":158}," +",[148,1109,1110],{"class":162}," token",[148,1112,725],{"class":158},[148,1114,1115],{"class":150,"line":266},[148,1116,1117],{"class":158},"    },\n",[148,1119,1120],{"class":150,"line":275},[148,1121,1122],{"class":158},"  },\n",[148,1124,1125,1127],{"class":150,"line":292},[148,1126,269],{"class":158},[148,1128,272],{"class":162},[1010,1130,1132,1134,1135,1137,1138,1140,1141,1143,1144,1147,1148,380,1150,303],{"color":1131,"icon":44},"warning",[145,1133,885],{}," are applied to ",[145,1136,379],{}," requests only. The ",[145,1139,934],{}," API does not support custom headers — when the page is hidden and ",[145,1142,934],{}," is used, headers are not sent. If your endpoint requires authentication, consider validating via a session cookie (",[145,1145,1146],{},"credentials: 'same-origin'"," is set by default) or disable ",[145,1149,934],{},[145,1151,1152],{},"useBeacon: false",[133,1154,1156],{"id":1155},"server-endpoint","Server Endpoint",[129,1158,1159,1160,1162],{},"Your server needs a POST endpoint that accepts a ",[145,1161,401],{}," JSON body. Here are examples for common frameworks:",[408,1164,1166],{"id":1165},"express","Express",[137,1168,1171],{"className":139,"code":1169,"filename":1170,"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,1172,1173,1226,1254,1290,1295,1312],{"__ignoreMap":143},[148,1174,1175,1178,1180,1183,1185,1187,1190,1192,1194,1197,1199,1202,1205,1207,1210,1214,1216,1219,1221,1224],{"class":150,"line":151},[148,1176,1177],{"class":162},"app",[148,1179,303],{"class":158},[148,1181,1182],{"class":229},"post",[148,1184,232],{"class":162},[148,1186,260],{"class":158},[148,1188,1189],{"class":181},"/v1/ingest",[148,1191,260],{"class":158},[148,1193,166],{"class":158},[148,1195,1196],{"class":162}," express",[148,1198,303],{"class":158},[148,1200,1201],{"class":229},"json",[148,1203,1204],{"class":162},"()",[148,1206,166],{"class":158},[148,1208,1209],{"class":158}," (",[148,1211,1213],{"class":1212},"sHdIc","req",[148,1215,166],{"class":158},[148,1217,1218],{"class":1212}," res",[148,1220,901],{"class":158},[148,1222,1223],{"class":219}," =>",[148,1225,1062],{"class":158},[148,1227,1228,1231,1233,1235,1238,1241,1244,1246,1249,1252],{"class":150,"line":188},[148,1229,1230],{"class":154},"  for",[148,1232,1209],{"class":241},[148,1234,220],{"class":219},[148,1236,1237],{"class":162}," entry",[148,1239,1240],{"class":158}," of",[148,1242,1243],{"class":162}," req",[148,1245,303],{"class":158},[148,1247,1248],{"class":162},"body",[148,1250,1251],{"class":241},") ",[148,1253,235],{"class":158},[148,1255,1256,1259,1261,1263,1265,1267,1270,1272,1274,1277,1279,1282,1284,1287],{"class":150,"line":209},[148,1257,1258],{"class":162},"    console",[148,1260,303],{"class":158},[148,1262,300],{"class":229},[148,1264,232],{"class":241},[148,1266,260],{"class":158},[148,1268,1269],{"class":181},"[BROWSER]",[148,1271,260],{"class":158},[148,1273,166],{"class":158},[148,1275,1276],{"class":162}," JSON",[148,1278,303],{"class":158},[148,1280,1281],{"class":229},"stringify",[148,1283,232],{"class":241},[148,1285,1286],{"class":162},"entry",[148,1288,1289],{"class":241},"))\n",[148,1291,1292],{"class":150,"line":216},[148,1293,1294],{"class":158},"  }\n",[148,1296,1297,1300,1302,1305,1307,1310],{"class":150,"line":238},[148,1298,1299],{"class":162},"  res",[148,1301,303],{"class":158},[148,1303,1304],{"class":229},"sendStatus",[148,1306,232],{"class":241},[148,1308,1309],{"class":534},"204",[148,1311,272],{"class":241},[148,1313,1314,1316],{"class":150,"line":266},[148,1315,269],{"class":158},[148,1317,272],{"class":162},[408,1319,1321],{"id":1320},"hono","Hono",[137,1323,1325],{"className":139,"code":1324,"filename":1170,"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,1326,1327,1359,1387,1405,1435,1439,1460],{"__ignoreMap":143},[148,1328,1329,1331,1333,1335,1337,1339,1341,1343,1345,1348,1350,1353,1355,1357],{"class":150,"line":151},[148,1330,1177],{"class":162},[148,1332,303],{"class":158},[148,1334,1182],{"class":229},[148,1336,232],{"class":162},[148,1338,260],{"class":158},[148,1340,1189],{"class":181},[148,1342,260],{"class":158},[148,1344,166],{"class":158},[148,1346,1347],{"class":219}," async",[148,1349,1209],{"class":158},[148,1351,1352],{"class":1212},"c",[148,1354,901],{"class":158},[148,1356,1223],{"class":219},[148,1358,1062],{"class":158},[148,1360,1361,1364,1367,1370,1373,1376,1378,1380,1382,1384],{"class":150,"line":188},[148,1362,1363],{"class":219},"  const",[148,1365,1366],{"class":162}," body",[148,1368,1369],{"class":158}," =",[148,1371,1372],{"class":154}," await",[148,1374,1375],{"class":162}," c",[148,1377,303],{"class":158},[148,1379,1213],{"class":162},[148,1381,303],{"class":158},[148,1383,1201],{"class":229},[148,1385,1386],{"class":241},"()\n",[148,1388,1389,1391,1393,1395,1397,1399,1401,1403],{"class":150,"line":209},[148,1390,1230],{"class":154},[148,1392,1209],{"class":241},[148,1394,220],{"class":219},[148,1396,1237],{"class":162},[148,1398,1240],{"class":158},[148,1400,1366],{"class":162},[148,1402,1251],{"class":241},[148,1404,235],{"class":158},[148,1406,1407,1409,1411,1413,1415,1417,1419,1421,1423,1425,1427,1429,1431,1433],{"class":150,"line":216},[148,1408,1258],{"class":162},[148,1410,303],{"class":158},[148,1412,300],{"class":229},[148,1414,232],{"class":241},[148,1416,260],{"class":158},[148,1418,1269],{"class":181},[148,1420,260],{"class":158},[148,1422,166],{"class":158},[148,1424,1276],{"class":162},[148,1426,303],{"class":158},[148,1428,1281],{"class":229},[148,1430,232],{"class":241},[148,1432,1286],{"class":162},[148,1434,1289],{"class":241},[148,1436,1437],{"class":150,"line":238},[148,1438,1294],{"class":158},[148,1440,1441,1444,1446,1448,1450,1452,1455,1458],{"class":150,"line":266},[148,1442,1443],{"class":154},"  return",[148,1445,1375],{"class":162},[148,1447,303],{"class":158},[148,1449,1248],{"class":229},[148,1451,232],{"class":241},[148,1453,1454],{"class":158},"null,",[148,1456,1457],{"class":534}," 204",[148,1459,272],{"class":241},[148,1461,1462,1464],{"class":150,"line":275},[148,1463,269],{"class":158},[148,1465,272],{"class":162},[133,1467,1469],{"id":1468},"full-control","Full Control",[129,1471,1472,1473,380,1476,1479],{},"Combine ",[145,1474,1475],{},"createBrowserDrain",[145,1477,1478],{},"createDrainPipeline"," for maximum flexibility:",[137,1481,1483],{"className":139,"code":1482,"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,1484,1485,1507,1527,1545,1563,1567,1587,1611,1641,1653,1671,1707,1711,1717,1722,1741,1756,1769,1776,1781,1796,1801,1829,1834,1841],{"__ignoreMap":143},[148,1486,1487,1489,1491,1493,1495,1497,1499,1501,1503,1505],{"class":150,"line":151},[148,1488,155],{"class":154},[148,1490,159],{"class":158},[148,1492,163],{"class":162},[148,1494,166],{"class":158},[148,1496,169],{"class":162},[148,1498,172],{"class":158},[148,1500,175],{"class":154},[148,1502,178],{"class":158},[148,1504,182],{"class":181},[148,1506,185],{"class":158},[148,1508,1509,1511,1513,1515,1517,1519,1521,1523,1525],{"class":150,"line":188},[148,1510,155],{"class":154},[148,1512,675],{"class":154},[148,1514,159],{"class":158},[148,1516,680],{"class":162},[148,1518,172],{"class":158},[148,1520,175],{"class":154},[148,1522,178],{"class":158},[148,1524,182],{"class":181},[148,1526,185],{"class":158},[148,1528,1529,1531,1533,1535,1537,1539,1541,1543],{"class":150,"line":209},[148,1530,155],{"class":154},[148,1532,159],{"class":158},[148,1534,638],{"class":162},[148,1536,172],{"class":158},[148,1538,175],{"class":154},[148,1540,178],{"class":158},[148,1542,204],{"class":181},[148,1544,185],{"class":158},[148,1546,1547,1549,1551,1553,1555,1557,1559,1561],{"class":150,"line":216},[148,1548,155],{"class":154},[148,1550,159],{"class":158},[148,1552,657],{"class":162},[148,1554,172],{"class":158},[148,1556,175],{"class":154},[148,1558,178],{"class":158},[148,1560,666],{"class":181},[148,1562,185],{"class":158},[148,1564,1565],{"class":150,"line":238},[148,1566,213],{"emptyLinePlaceholder":212},[148,1568,1569,1571,1573,1575,1577,1579,1581,1583,1585],{"class":150,"line":266},[148,1570,220],{"class":219},[148,1572,738],{"class":162},[148,1574,226],{"class":158},[148,1576,657],{"class":229},[148,1578,745],{"class":158},[148,1580,749],{"class":748},[148,1582,752],{"class":158},[148,1584,232],{"class":162},[148,1586,235],{"class":158},[148,1588,1589,1591,1593,1595,1597,1599,1601,1603,1605,1607,1609],{"class":150,"line":275},[148,1590,761],{"class":241},[148,1592,245],{"class":158},[148,1594,159],{"class":158},[148,1596,529],{"class":241},[148,1598,245],{"class":158},[148,1600,772],{"class":534},[148,1602,166],{"class":158},[148,1604,540],{"class":241},[148,1606,245],{"class":158},[148,1608,781],{"class":534},[148,1610,263],{"class":158},[148,1612,1613,1615,1617,1619,1621,1623,1625,1627,1630,1632,1634,1637,1639],{"class":150,"line":292},[148,1614,788],{"class":241},[148,1616,245],{"class":158},[148,1618,159],{"class":158},[148,1620,795],{"class":241},[148,1622,245],{"class":158},[148,1624,800],{"class":534},[148,1626,166],{"class":158},[148,1628,1629],{"class":241}," backoff",[148,1631,245],{"class":158},[148,1633,178],{"class":158},[148,1635,1636],{"class":181},"exponential",[148,1638,260],{"class":158},[148,1640,263],{"class":158},[148,1642,1643,1646,1648,1651],{"class":150,"line":297},[148,1644,1645],{"class":241},"  maxBufferSize",[148,1647,245],{"class":158},[148,1649,1650],{"class":534}," 500",[148,1652,725],{"class":158},[148,1654,1655,1658,1660,1662,1665,1667,1669],{"class":150,"line":576},[148,1656,1657],{"class":229},"  onDropped",[148,1659,245],{"class":158},[148,1661,1209],{"class":158},[148,1663,1664],{"class":1212},"events",[148,1666,901],{"class":158},[148,1668,1223],{"class":219},[148,1670,1062],{"class":158},[148,1672,1673,1675,1677,1680,1682,1685,1688,1691,1693,1695,1698,1700,1703,1705],{"class":150,"line":805},[148,1674,1258],{"class":162},[148,1676,303],{"class":158},[148,1678,1679],{"class":229},"warn",[148,1681,232],{"class":241},[148,1683,1684],{"class":158},"`",[148,1686,1687],{"class":181},"Dropped ",[148,1689,1690],{"class":158},"${",[148,1692,1664],{"class":162},[148,1694,303],{"class":158},[148,1696,1697],{"class":162},"length",[148,1699,269],{"class":158},[148,1701,1702],{"class":181}," browser events",[148,1704,1684],{"class":158},[148,1706,272],{"class":241},[148,1708,1709],{"class":150,"line":812},[148,1710,1122],{"class":158},[148,1712,1713,1715],{"class":150,"line":817},[148,1714,269],{"class":158},[148,1716,272],{"class":162},[148,1718,1720],{"class":150,"line":1719},14,[148,1721,213],{"emptyLinePlaceholder":212},[148,1723,1725,1727,1729,1731,1733,1735,1737,1739],{"class":150,"line":1724},15,[148,1726,220],{"class":219},[148,1728,223],{"class":162},[148,1730,226],{"class":158},[148,1732,826],{"class":229},[148,1734,232],{"class":162},[148,1736,1475],{"class":229},[148,1738,232],{"class":162},[148,1740,235],{"class":158},[148,1742,1744,1746,1748,1750,1752,1754],{"class":150,"line":1743},16,[148,1745,714],{"class":241},[148,1747,245],{"class":158},[148,1749,178],{"class":158},[148,1751,257],{"class":181},[148,1753,260],{"class":158},[148,1755,725],{"class":158},[148,1757,1759,1762,1764,1767],{"class":150,"line":1758},17,[148,1760,1761],{"class":241},"  timeout",[148,1763,245],{"class":158},[148,1765,1766],{"class":534}," 3000",[148,1768,725],{"class":158},[148,1770,1772,1774],{"class":150,"line":1771},18,[148,1773,269],{"class":158},[148,1775,1289],{"class":162},[148,1777,1779],{"class":150,"line":1778},19,[148,1780,213],{"emptyLinePlaceholder":212},[148,1782,1784,1786,1788,1790,1792,1794],{"class":150,"line":1783},20,[148,1785,278],{"class":229},[148,1787,232],{"class":162},[148,1789,283],{"class":158},[148,1791,223],{"class":162},[148,1793,269],{"class":158},[148,1795,272],{"class":162},[148,1797,1799],{"class":150,"line":1798},21,[148,1800,213],{"emptyLinePlaceholder":212},[148,1802,1804,1806,1808,1810,1812,1814,1816,1818,1820,1823,1825,1827],{"class":150,"line":1803},22,[148,1805,300],{"class":162},[148,1807,303],{"class":158},[148,1809,306],{"class":229},[148,1811,232],{"class":162},[148,1813,283],{"class":158},[148,1815,313],{"class":241},[148,1817,245],{"class":158},[148,1819,178],{"class":158},[148,1821,1822],{"class":181},"app_init",[148,1824,260],{"class":158},[148,1826,172],{"class":158},[148,1828,272],{"class":162},[148,1830,1832],{"class":150,"line":1831},23,[148,1833,213],{"emptyLinePlaceholder":212},[148,1835,1837],{"class":150,"line":1836},24,[148,1838,1840],{"class":1839},"sHwdD","// Flush on page unload\n",[148,1842,1844,1847,1849,1852,1854,1856,1859,1861,1863,1866,1868,1871,1873,1876],{"class":150,"line":1843},25,[148,1845,1846],{"class":162},"window",[148,1848,303],{"class":158},[148,1850,1851],{"class":229},"addEventListener",[148,1853,232],{"class":162},[148,1855,260],{"class":158},[148,1857,1858],{"class":181},"beforeunload",[148,1860,260],{"class":158},[148,1862,166],{"class":158},[148,1864,1865],{"class":158}," ()",[148,1867,1223],{"class":219},[148,1869,1870],{"class":162}," drain",[148,1872,303],{"class":158},[148,1874,1875],{"class":229},"flush",[148,1877,1878],{"class":162},"())\n",[1010,1880,1883,1884,1891],{"color":1881,"icon":1882},"neutral","i-lucide-arrow-right","See the full ",[1885,1886,1890],"a",{"href":1887,"rel":1888},"https://github.com/HugoRCD/evlog/tree/main/examples/browser",[1889],"nofollow","browser example"," for a working Hono server + browser page that demonstrates the complete flow end to end.",[133,1893,1895],{"id":1894},"next-steps","Next Steps",[1897,1898,1899,1905,1910],"ul",{},[350,1900,1901,1904],{},[1885,1902,1903],{"href":62},"Adapters Overview"," — Available built-in adapters",[350,1906,1907,1909],{},[1885,1908,96],{"href":97}," — Batching, retry, and buffer overflow handling",[350,1911,1912,1914],{},[1885,1913,91],{"href":92}," — Build your own drain function",[1916,1917,1918],"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":1920},[1921,1922,1923,1927,1931,1932,1933,1937,1938],{"id":135,"depth":188,"text":20},{"id":344,"depth":188,"text":345},{"id":405,"depth":188,"text":406,"children":1924},[1925,1926],{"id":410,"depth":209,"text":413},{"id":618,"depth":209,"text":621},{"id":832,"depth":188,"text":833,"children":1928},[1929,1930],{"id":836,"depth":209,"text":839},{"id":938,"depth":209,"text":941},{"id":1007,"depth":188,"text":1008},{"id":1030,"depth":188,"text":1031},{"id":1155,"depth":188,"text":1156,"children":1934},[1935,1936],{"id":1165,"depth":209,"text":1166},{"id":1320,"depth":209,"text":1321},{"id":1468,"depth":188,"text":1469},{"id":1894,"depth":188,"text":1895},"Framework-agnostic browser log transport — send client-side logs to your server via fetch or sendBeacon.","md",[1942,1944],{"label":1903,"icon":64,"to":62,"color":1881,"variant":1943},"subtle",{"label":96,"icon":99,"to":97,"color":1881,"variant":1943},{},{"title":101,"icon":104},{"title":124,"description":1939},"f1ZLgy9VVD3rtoYrKSDzWlhgOBJ1s5JRxt6MfodhQCk",[1950,1952],{"title":96,"path":97,"stem":98,"description":1951,"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":1953,"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.",1771152856589]