[{"data":1,"prerenderedAt":1516},["ShallowReactive",2],{"navigation":3,"-guide-advanced-websocket":189,"-guide-advanced-websocket-surround":1512},[4,91,138,166,173],{"title":5,"path":6,"stem":7,"children":8,"icon":90},"Guide","/guide","1.guide/0.index",[9,12,53,69],{"title":10,"path":6,"stem":7,"icon":11},"Getting Started","pixel:play",{"title":5,"icon":13,"path":14,"stem":15,"children":16,"page":52},"ph:book-open-duotone","/guide/basics","1.guide/1.basics",[17,22,27,32,37,42,47],{"title":18,"path":19,"stem":20,"icon":21},"Request Lifecycle","/guide/basics/lifecycle","1.guide/1.basics/1.lifecycle","icon-park-outline:handle-round",{"title":23,"path":24,"stem":25,"icon":26},"Routing","/guide/basics/routing","1.guide/1.basics/2.routing","solar:routing-bold",{"title":28,"path":29,"stem":30,"icon":31},"Middleware","/guide/basics/middleware","1.guide/1.basics/3.middleware","mdi:middleware-outline",{"title":33,"path":34,"stem":35,"icon":36},"Event Handlers","/guide/basics/handler","1.guide/1.basics/4.handler","mdi:function",{"title":38,"path":39,"stem":40,"icon":41},"Sending Response","/guide/basics/response","1.guide/1.basics/5.response","tabler:json",{"title":43,"path":44,"stem":45,"icon":46},"Error Handling","/guide/basics/error","1.guide/1.basics/6.error","tabler:error-404",{"title":48,"path":49,"stem":50,"icon":51},"Nested Apps","/guide/basics/nested-apps","1.guide/1.basics/7.nested-apps","material-symbols-light:layers-outline",false,{"title":54,"icon":55,"path":56,"stem":57,"children":58,"page":52},"API","material-symbols-light:api-rounded","/guide/api","1.guide/900.api",[59,64],{"title":60,"path":61,"stem":62,"icon":63},"H3","/guide/api/h3","1.guide/900.api/1.h3","material-symbols:bolt-rounded",{"title":65,"path":66,"stem":67,"icon":68},"H3Event","/guide/api/h3event","1.guide/900.api/2.h3event","material-symbols:data-object-rounded",{"title":70,"icon":71,"path":72,"stem":73,"children":74,"page":52},"Advanced","hugeicons:more-01","/guide/advanced","1.guide/901.advanced",[75,80,85],{"title":76,"path":77,"stem":78,"icon":79},"Plugins","/guide/advanced/plugins","1.guide/901.advanced/1.plugins","clarity:plugin-line",{"title":81,"path":82,"stem":83,"icon":84},"WebSockets","/guide/advanced/websocket","1.guide/901.advanced/2.websocket","hugeicons:live-streaming-02",{"title":86,"path":87,"stem":88,"icon":89},"Nightly Builds","/guide/advanced/nightly","1.guide/901.advanced/9.nightly","game-icons:barn-owl","i-ph:book-open-duotone",{"title":92,"path":93,"stem":94,"children":95,"icon":97},"Utils","/utils","2.utils/0.index",[96,98,103,108,113,118,123,128,133],{"title":92,"path":93,"stem":94,"icon":97},"ph:function-bold",{"title":99,"path":100,"stem":101,"icon":102},"Request","/utils/request","2.utils/1.request","material-symbols-light:input",{"title":104,"path":105,"stem":106,"icon":107},"Response","/utils/response","2.utils/2.response","material-symbols-light:output",{"title":109,"path":110,"stem":111,"icon":112},"Cookie","/utils/cookie","2.utils/3.cookie","material-symbols:cookie-outline",{"title":114,"path":115,"stem":116,"icon":117},"Security","/utils/security","2.utils/4.security","wpf:key-security",{"title":119,"path":120,"stem":121,"icon":122},"Proxy","/utils/proxy","2.utils/5.proxy","arcticons:super-proxy",{"title":124,"path":125,"stem":126,"icon":127},"MCP","/utils/mcp","2.utils/6.mcp","material-symbols:swap-calls",{"title":129,"path":130,"stem":131,"icon":132},"More utils","/utils/more","2.utils/9.more","mingcute:plus-line",{"title":134,"path":135,"stem":136,"icon":137},"Community","/utils/community","2.utils/99.community","lets-icons:external",{"title":139,"path":140,"stem":141,"children":142,"icon":144},"Examples","/examples","4.examples/0.index",[143,145,150,154,158,162],{"title":139,"path":140,"stem":141,"icon":144},"ph:code",{"title":146,"path":147,"stem":148,"icon":149},"Cookies","/examples/handle-cookie","4.examples/handle-cookie","ph:arrow-right",{"title":151,"path":152,"stem":153,"icon":149},"Sessions","/examples/handle-session","4.examples/handle-session",{"title":155,"path":156,"stem":157,"icon":149},"Static Assets","/examples/serve-static-assets","4.examples/serve-static-assets",{"title":159,"path":160,"stem":161,"icon":149},"Stream Response","/examples/stream-response","4.examples/stream-response",{"title":163,"path":164,"stem":165,"icon":149},"Validate Data","/examples/validate-data","4.examples/validate-data",{"title":167,"path":168,"stem":169,"children":170,"icon":172},"Migration","/migration","5.migration/0.index",[171],{"title":167,"path":168,"stem":169,"icon":172},"icons8:up-round",{"title":174,"path":175,"stem":176,"children":177},"Blog","/blog","99.blog",[178,181,185],{"title":174,"path":175,"stem":179,"icon":180},"99.blog/index","i-lucide-file-text",{"title":182,"path":183,"stem":184,"icon":180},"H3 1.8 - Towards the Edge of the Web","/blog/v1.8","99.blog/1.v1.8",{"title":186,"path":187,"stem":188,"icon":180},"H3 v2 beta","/blog/v2-beta","99.blog/2.v2-beta",{"id":190,"title":81,"body":191,"description":1506,"extension":1507,"meta":1508,"navigation":1509,"path":82,"seo":1510,"stem":83,"__hash__":1511},"content/1.guide/901.advanced/2.websocket.md",{"type":192,"value":193,"toc":1498,"icon":84},"minimark",[194,206,212,217,225,236,419,425,1151,1156,1163,1169,1247,1251,1259,1266,1270,1494],[195,196,197,198,205],"p",{},"You can add cross platform WebSocket support to H3 servers using ",[199,200,204],"a",{"href":201,"rel":202},"https://crossws.h3.dev/",[203],"nofollow","🔌 CrossWS",".",[207,208,209],"important",{},[195,210,211],{},"\nBuilt-in support of WebSockets in h3 version is WIP.",[213,214,216],"h2",{"id":215},"usage","Usage",[195,218,219,220,224],{},"WebSocket handlers can be defined using the ",[221,222,223],"code",{},"defineWebSocketHandler()"," utility and registered to any route like event handlers.",[195,226,227,228,231,232,235],{},"You need to register CrossWS as a server plugin in the ",[221,229,230],{},"serve"," function and provide a ",[221,233,234],{},"resolve"," function to resolve the correct hooks from the route.",[237,238,243],"pre",{"className":239,"code":240,"language":241,"meta":242,"style":242},"language-js shiki shiki-themes github-light github-dark github-dark","import { H3, serve, defineWebSocketHandler } from \"h3\";\n\nimport { plugin as ws } from \"crossws/server\";\n\nconst app = new H3();\n\napp.get(\"/_ws\", defineWebSocketHandler({ message: console.log }));\n\nserve(app, {\n  plugins: [ws({ resolve: async (req) => (await app.fetch(req)).crossws })],\n});\n","js","",[221,244,245,268,275,296,301,324,329,353,358,366,413],{"__ignoreMap":242},[246,247,250,254,258,261,265],"span",{"class":248,"line":249},"line",1,[246,251,253],{"class":252},"so5gQ","import",[246,255,257],{"class":256},"slsVL"," { H3, serve, defineWebSocketHandler } ",[246,259,260],{"class":252},"from",[246,262,264],{"class":263},"sfrk1"," \"h3\"",[246,266,267],{"class":256},";\n",[246,269,271],{"class":248,"line":270},2,[246,272,274],{"emptyLinePlaceholder":273},true,"\n",[246,276,278,280,283,286,289,291,294],{"class":248,"line":277},3,[246,279,253],{"class":252},[246,281,282],{"class":256}," { plugin ",[246,284,285],{"class":252},"as",[246,287,288],{"class":256}," ws } ",[246,290,260],{"class":252},[246,292,293],{"class":263}," \"crossws/server\"",[246,295,267],{"class":256},[246,297,299],{"class":248,"line":298},4,[246,300,274],{"emptyLinePlaceholder":273},[246,302,304,307,311,314,317,321],{"class":248,"line":303},5,[246,305,306],{"class":252},"const",[246,308,310],{"class":309},"suiK_"," app",[246,312,313],{"class":252}," =",[246,315,316],{"class":252}," new",[246,318,320],{"class":319},"shcOC"," H3",[246,322,323],{"class":256},"();\n",[246,325,327],{"class":248,"line":326},6,[246,328,274],{"emptyLinePlaceholder":273},[246,330,332,335,338,341,344,347,350],{"class":248,"line":331},7,[246,333,334],{"class":256},"app.",[246,336,337],{"class":319},"get",[246,339,340],{"class":256},"(",[246,342,343],{"class":263},"\"/_ws\"",[246,345,346],{"class":256},", ",[246,348,349],{"class":319},"defineWebSocketHandler",[246,351,352],{"class":256},"({ message: console.log }));\n",[246,354,356],{"class":248,"line":355},8,[246,357,274],{"emptyLinePlaceholder":273},[246,359,361,363],{"class":248,"line":360},9,[246,362,230],{"class":319},[246,364,365],{"class":256},"(app, {\n",[246,367,369,372,375,378,380,383,386,389,393,396,399,401,404,407,410],{"class":248,"line":368},10,[246,370,371],{"class":256},"  plugins: [",[246,373,374],{"class":319},"ws",[246,376,377],{"class":256},"({ ",[246,379,234],{"class":319},[246,381,382],{"class":256},": ",[246,384,385],{"class":252},"async",[246,387,388],{"class":256}," (",[246,390,392],{"class":391},"sQHwn","req",[246,394,395],{"class":256},") ",[246,397,398],{"class":252},"=>",[246,400,388],{"class":256},[246,402,403],{"class":252},"await",[246,405,406],{"class":256}," app.",[246,408,409],{"class":319},"fetch",[246,411,412],{"class":256},"(req)).crossws })],\n",[246,414,416],{"class":248,"line":415},11,[246,417,418],{"class":256},"});\n",[195,420,421],{},[422,423,424],"strong",{},"Full example:",[237,426,429],{"className":239,"code":427,"filename":428,"language":241,"meta":242,"style":242},"import { H3, serve, html, defineWebSocketHandler } from \"h3\";\nimport { plugin as ws } from \"crossws/server\";\n\nexport const app = new H3();\n\n// A minimal self-contained WebSocket playground served for plain HTTP requests.\nconst playground = html`\u003C!doctype html>\n  \u003Ctitle>H3 WebSocket Playground\u003C/title>\n  \u003Ch1>H3 WebSocket Playground\u003C/h1>\n  \u003Cform id=\"form\">\n    \u003Cinput id=\"input\" placeholder=\"Type a message...\" autocomplete=\"off\" autofocus />\n    \u003Cbutton type=\"submit\">Send\u003C/button>\n  \u003C/form>\n  \u003Cdiv id=\"log\">\u003C/div>\n  \u003Cscript type=\"module\">\n    const log = (msg) => {\n      const line = document.createElement(\"div\");\n      line.textContent = msg;\n      document.getElementById(\"log\").append(line);\n    };\n    const url = location.href.replace(/^http/, \"ws\");\n    const ws = new WebSocket(url);\n    ws.addEventListener(\"open\", () => log(\"[open] connected to \" + url));\n    ws.addEventListener(\"message\", (e) => log(\"[message] \" + e.data));\n    ws.addEventListener(\"close\", () => log(\"[close] disconnected\"));\n    document.getElementById(\"form\").addEventListener(\"submit\", (e) => {\n      e.preventDefault();\n      const input = document.getElementById(\"input\");\n      ws.send(input.value);\n      input.value = \"\";\n    });\n  \u003C/script>`;\n\n// A single route serves both the playground page (plain HTTP) and the\n// WebSocket endpoint (upgrade requests). The page connects back to itself.\napp.get(\n  \"/\",\n  defineWebSocketHandler(\n    {\n      open(peer) {\n        console.log(\"[open]\", peer);\n\n        // Send welcome to the new client\n        peer.send(\"Welcome to the server!\");\n\n        // Join new client to the \"chat\" channel\n        peer.subscribe(\"chat\");\n\n        // Notify every other connected client\n        peer.publish(\"chat\", `[system] ${peer} joined!`);\n      },\n\n      message(peer, message) {\n        console.log(\"[message]\", peer);\n\n        if (message.text() === \"ping\") {\n          // Reply to the client with a ping response\n          peer.send(\"pong\");\n          return;\n        }\n\n        // The server re-broadcasts incoming messages to everyone\n        peer.publish(\"chat\", `[${peer}] ${message}`);\n\n        // Echo the message back to the sender\n        peer.send(message);\n      },\n\n      close(peer) {\n        console.log(\"[close]\", peer);\n        peer.publish(\"chat\", `[system] ${peer} has left the chat!`);\n        peer.unsubscribe(\"chat\");\n      },\n    },\n    // Non-upgrade requests get the playground page.\n    () => playground,\n  ),\n);\n\nserve(app, {\n  plugins: [ws({ resolve: async (req) => (await app.fetch(req)).crossws })],\n});\n","websocket.mjs",[221,430,431,444,460,464,482,486,492,507,512,517,522,527,533,539,545,551,557,563,569,575,581,587,593,599,605,611,617,623,629,635,641,647,655,660,666,672,682,691,699,705,719,736,741,747,764,769,775,790,795,801,825,831,836,853,867,872,895,901,916,924,930,935,941,969,974,980,990,995,1000,1012,1026,1048,1062,1067,1073,1079,1090,1096,1101,1106,1113,1146],{"__ignoreMap":242},[246,432,433,435,438,440,442],{"class":248,"line":249},[246,434,253],{"class":252},[246,436,437],{"class":256}," { H3, serve, html, defineWebSocketHandler } ",[246,439,260],{"class":252},[246,441,264],{"class":263},[246,443,267],{"class":256},[246,445,446,448,450,452,454,456,458],{"class":248,"line":270},[246,447,253],{"class":252},[246,449,282],{"class":256},[246,451,285],{"class":252},[246,453,288],{"class":256},[246,455,260],{"class":252},[246,457,293],{"class":263},[246,459,267],{"class":256},[246,461,462],{"class":248,"line":277},[246,463,274],{"emptyLinePlaceholder":273},[246,465,466,469,472,474,476,478,480],{"class":248,"line":298},[246,467,468],{"class":252},"export",[246,470,471],{"class":252}," const",[246,473,310],{"class":309},[246,475,313],{"class":252},[246,477,316],{"class":252},[246,479,320],{"class":319},[246,481,323],{"class":256},[246,483,484],{"class":248,"line":303},[246,485,274],{"emptyLinePlaceholder":273},[246,487,488],{"class":248,"line":326},[246,489,491],{"class":490},"sCsY4","// A minimal self-contained WebSocket playground served for plain HTTP requests.\n",[246,493,494,496,499,501,504],{"class":248,"line":331},[246,495,306],{"class":252},[246,497,498],{"class":309}," playground",[246,500,313],{"class":252},[246,502,503],{"class":319}," html",[246,505,506],{"class":263},"`\u003C!doctype html>\n",[246,508,509],{"class":248,"line":355},[246,510,511],{"class":263},"  \u003Ctitle>H3 WebSocket Playground\u003C/title>\n",[246,513,514],{"class":248,"line":360},[246,515,516],{"class":263},"  \u003Ch1>H3 WebSocket Playground\u003C/h1>\n",[246,518,519],{"class":248,"line":368},[246,520,521],{"class":263},"  \u003Cform id=\"form\">\n",[246,523,524],{"class":248,"line":415},[246,525,526],{"class":263},"    \u003Cinput id=\"input\" placeholder=\"Type a message...\" autocomplete=\"off\" autofocus />\n",[246,528,530],{"class":248,"line":529},12,[246,531,532],{"class":263},"    \u003Cbutton type=\"submit\">Send\u003C/button>\n",[246,534,536],{"class":248,"line":535},13,[246,537,538],{"class":263},"  \u003C/form>\n",[246,540,542],{"class":248,"line":541},14,[246,543,544],{"class":263},"  \u003Cdiv id=\"log\">\u003C/div>\n",[246,546,548],{"class":248,"line":547},15,[246,549,550],{"class":263},"  \u003Cscript type=\"module\">\n",[246,552,554],{"class":248,"line":553},16,[246,555,556],{"class":263},"    const log = (msg) => {\n",[246,558,560],{"class":248,"line":559},17,[246,561,562],{"class":263},"      const line = document.createElement(\"div\");\n",[246,564,566],{"class":248,"line":565},18,[246,567,568],{"class":263},"      line.textContent = msg;\n",[246,570,572],{"class":248,"line":571},19,[246,573,574],{"class":263},"      document.getElementById(\"log\").append(line);\n",[246,576,578],{"class":248,"line":577},20,[246,579,580],{"class":263},"    };\n",[246,582,584],{"class":248,"line":583},21,[246,585,586],{"class":263},"    const url = location.href.replace(/^http/, \"ws\");\n",[246,588,590],{"class":248,"line":589},22,[246,591,592],{"class":263},"    const ws = new WebSocket(url);\n",[246,594,596],{"class":248,"line":595},23,[246,597,598],{"class":263},"    ws.addEventListener(\"open\", () => log(\"[open] connected to \" + url));\n",[246,600,602],{"class":248,"line":601},24,[246,603,604],{"class":263},"    ws.addEventListener(\"message\", (e) => log(\"[message] \" + e.data));\n",[246,606,608],{"class":248,"line":607},25,[246,609,610],{"class":263},"    ws.addEventListener(\"close\", () => log(\"[close] disconnected\"));\n",[246,612,614],{"class":248,"line":613},26,[246,615,616],{"class":263},"    document.getElementById(\"form\").addEventListener(\"submit\", (e) => {\n",[246,618,620],{"class":248,"line":619},27,[246,621,622],{"class":263},"      e.preventDefault();\n",[246,624,626],{"class":248,"line":625},28,[246,627,628],{"class":263},"      const input = document.getElementById(\"input\");\n",[246,630,632],{"class":248,"line":631},29,[246,633,634],{"class":263},"      ws.send(input.value);\n",[246,636,638],{"class":248,"line":637},30,[246,639,640],{"class":263},"      input.value = \"\";\n",[246,642,644],{"class":248,"line":643},31,[246,645,646],{"class":263},"    });\n",[246,648,650,653],{"class":248,"line":649},32,[246,651,652],{"class":263},"  \u003C/script>`",[246,654,267],{"class":256},[246,656,658],{"class":248,"line":657},33,[246,659,274],{"emptyLinePlaceholder":273},[246,661,663],{"class":248,"line":662},34,[246,664,665],{"class":490},"// A single route serves both the playground page (plain HTTP) and the\n",[246,667,669],{"class":248,"line":668},35,[246,670,671],{"class":490},"// WebSocket endpoint (upgrade requests). The page connects back to itself.\n",[246,673,675,677,679],{"class":248,"line":674},36,[246,676,334],{"class":256},[246,678,337],{"class":319},[246,680,681],{"class":256},"(\n",[246,683,685,688],{"class":248,"line":684},37,[246,686,687],{"class":263},"  \"/\"",[246,689,690],{"class":256},",\n",[246,692,694,697],{"class":248,"line":693},38,[246,695,696],{"class":319},"  defineWebSocketHandler",[246,698,681],{"class":256},[246,700,702],{"class":248,"line":701},39,[246,703,704],{"class":256},"    {\n",[246,706,708,711,713,716],{"class":248,"line":707},40,[246,709,710],{"class":319},"      open",[246,712,340],{"class":256},[246,714,715],{"class":391},"peer",[246,717,718],{"class":256},") {\n",[246,720,722,725,728,730,733],{"class":248,"line":721},41,[246,723,724],{"class":256},"        console.",[246,726,727],{"class":319},"log",[246,729,340],{"class":256},[246,731,732],{"class":263},"\"[open]\"",[246,734,735],{"class":256},", peer);\n",[246,737,739],{"class":248,"line":738},42,[246,740,274],{"emptyLinePlaceholder":273},[246,742,744],{"class":248,"line":743},43,[246,745,746],{"class":490},"        // Send welcome to the new client\n",[246,748,750,753,756,758,761],{"class":248,"line":749},44,[246,751,752],{"class":256},"        peer.",[246,754,755],{"class":319},"send",[246,757,340],{"class":256},[246,759,760],{"class":263},"\"Welcome to the server!\"",[246,762,763],{"class":256},");\n",[246,765,767],{"class":248,"line":766},45,[246,768,274],{"emptyLinePlaceholder":273},[246,770,772],{"class":248,"line":771},46,[246,773,774],{"class":490},"        // Join new client to the \"chat\" channel\n",[246,776,778,780,783,785,788],{"class":248,"line":777},47,[246,779,752],{"class":256},[246,781,782],{"class":319},"subscribe",[246,784,340],{"class":256},[246,786,787],{"class":263},"\"chat\"",[246,789,763],{"class":256},[246,791,793],{"class":248,"line":792},48,[246,794,274],{"emptyLinePlaceholder":273},[246,796,798],{"class":248,"line":797},49,[246,799,800],{"class":490},"        // Notify every other connected client\n",[246,802,804,806,809,811,813,815,818,820,823],{"class":248,"line":803},50,[246,805,752],{"class":256},[246,807,808],{"class":319},"publish",[246,810,340],{"class":256},[246,812,787],{"class":263},[246,814,346],{"class":256},[246,816,817],{"class":263},"`[system] ${",[246,819,715],{"class":256},[246,821,822],{"class":263},"} joined!`",[246,824,763],{"class":256},[246,826,828],{"class":248,"line":827},51,[246,829,830],{"class":256},"      },\n",[246,832,834],{"class":248,"line":833},52,[246,835,274],{"emptyLinePlaceholder":273},[246,837,839,842,844,846,848,851],{"class":248,"line":838},53,[246,840,841],{"class":319},"      message",[246,843,340],{"class":256},[246,845,715],{"class":391},[246,847,346],{"class":256},[246,849,850],{"class":391},"message",[246,852,718],{"class":256},[246,854,856,858,860,862,865],{"class":248,"line":855},54,[246,857,724],{"class":256},[246,859,727],{"class":319},[246,861,340],{"class":256},[246,863,864],{"class":263},"\"[message]\"",[246,866,735],{"class":256},[246,868,870],{"class":248,"line":869},55,[246,871,274],{"emptyLinePlaceholder":273},[246,873,875,878,881,884,887,890,893],{"class":248,"line":874},56,[246,876,877],{"class":252},"        if",[246,879,880],{"class":256}," (message.",[246,882,883],{"class":319},"text",[246,885,886],{"class":256},"() ",[246,888,889],{"class":252},"===",[246,891,892],{"class":263}," \"ping\"",[246,894,718],{"class":256},[246,896,898],{"class":248,"line":897},57,[246,899,900],{"class":490},"          // Reply to the client with a ping response\n",[246,902,904,907,909,911,914],{"class":248,"line":903},58,[246,905,906],{"class":256},"          peer.",[246,908,755],{"class":319},[246,910,340],{"class":256},[246,912,913],{"class":263},"\"pong\"",[246,915,763],{"class":256},[246,917,919,922],{"class":248,"line":918},59,[246,920,921],{"class":252},"          return",[246,923,267],{"class":256},[246,925,927],{"class":248,"line":926},60,[246,928,929],{"class":256},"        }\n",[246,931,933],{"class":248,"line":932},61,[246,934,274],{"emptyLinePlaceholder":273},[246,936,938],{"class":248,"line":937},62,[246,939,940],{"class":490},"        // The server re-broadcasts incoming messages to everyone\n",[246,942,944,946,948,950,952,954,957,959,962,964,967],{"class":248,"line":943},63,[246,945,752],{"class":256},[246,947,808],{"class":319},[246,949,340],{"class":256},[246,951,787],{"class":263},[246,953,346],{"class":256},[246,955,956],{"class":263},"`[${",[246,958,715],{"class":256},[246,960,961],{"class":263},"}] ${",[246,963,850],{"class":256},[246,965,966],{"class":263},"}`",[246,968,763],{"class":256},[246,970,972],{"class":248,"line":971},64,[246,973,274],{"emptyLinePlaceholder":273},[246,975,977],{"class":248,"line":976},65,[246,978,979],{"class":490},"        // Echo the message back to the sender\n",[246,981,983,985,987],{"class":248,"line":982},66,[246,984,752],{"class":256},[246,986,755],{"class":319},[246,988,989],{"class":256},"(message);\n",[246,991,993],{"class":248,"line":992},67,[246,994,830],{"class":256},[246,996,998],{"class":248,"line":997},68,[246,999,274],{"emptyLinePlaceholder":273},[246,1001,1003,1006,1008,1010],{"class":248,"line":1002},69,[246,1004,1005],{"class":319},"      close",[246,1007,340],{"class":256},[246,1009,715],{"class":391},[246,1011,718],{"class":256},[246,1013,1015,1017,1019,1021,1024],{"class":248,"line":1014},70,[246,1016,724],{"class":256},[246,1018,727],{"class":319},[246,1020,340],{"class":256},[246,1022,1023],{"class":263},"\"[close]\"",[246,1025,735],{"class":256},[246,1027,1029,1031,1033,1035,1037,1039,1041,1043,1046],{"class":248,"line":1028},71,[246,1030,752],{"class":256},[246,1032,808],{"class":319},[246,1034,340],{"class":256},[246,1036,787],{"class":263},[246,1038,346],{"class":256},[246,1040,817],{"class":263},[246,1042,715],{"class":256},[246,1044,1045],{"class":263},"} has left the chat!`",[246,1047,763],{"class":256},[246,1049,1051,1053,1056,1058,1060],{"class":248,"line":1050},72,[246,1052,752],{"class":256},[246,1054,1055],{"class":319},"unsubscribe",[246,1057,340],{"class":256},[246,1059,787],{"class":263},[246,1061,763],{"class":256},[246,1063,1065],{"class":248,"line":1064},73,[246,1066,830],{"class":256},[246,1068,1070],{"class":248,"line":1069},74,[246,1071,1072],{"class":256},"    },\n",[246,1074,1076],{"class":248,"line":1075},75,[246,1077,1078],{"class":490},"    // Non-upgrade requests get the playground page.\n",[246,1080,1082,1085,1087],{"class":248,"line":1081},76,[246,1083,1084],{"class":256},"    () ",[246,1086,398],{"class":252},[246,1088,1089],{"class":256}," playground,\n",[246,1091,1093],{"class":248,"line":1092},77,[246,1094,1095],{"class":256},"  ),\n",[246,1097,1099],{"class":248,"line":1098},78,[246,1100,763],{"class":256},[246,1102,1104],{"class":248,"line":1103},79,[246,1105,274],{"emptyLinePlaceholder":273},[246,1107,1109,1111],{"class":248,"line":1108},80,[246,1110,230],{"class":319},[246,1112,365],{"class":256},[246,1114,1116,1118,1120,1122,1124,1126,1128,1130,1132,1134,1136,1138,1140,1142,1144],{"class":248,"line":1115},81,[246,1117,371],{"class":256},[246,1119,374],{"class":319},[246,1121,377],{"class":256},[246,1123,234],{"class":319},[246,1125,382],{"class":256},[246,1127,385],{"class":252},[246,1129,388],{"class":256},[246,1131,392],{"class":391},[246,1133,395],{"class":256},[246,1135,398],{"class":252},[246,1137,388],{"class":256},[246,1139,403],{"class":252},[246,1141,406],{"class":256},[246,1143,409],{"class":319},[246,1145,412],{"class":256},[246,1147,1149],{"class":248,"line":1148},82,[246,1150,418],{"class":256},[1152,1153,1155],"h3",{"id":1154},"handling-http-requests","Handling HTTP requests",[195,1157,1158,1159,1162],{},"By default, a WebSocket route responds with ",[221,1160,1161],{},"426 Upgrade Required"," to any request that is not a WebSocket upgrade.",[195,1164,1165,1166,1168],{},"You can pass an optional HTTP handler as the second argument to ",[221,1167,223],{}," to serve regular (non-upgrade) requests on the same route. WebSocket upgrade requests still go to the hooks.",[237,1170,1172],{"className":239,"code":1171,"language":241,"meta":242,"style":242},"app.get(\n  \"/_ws\",\n  defineWebSocketHandler(\n    { message: (peer, message) => peer.send(message.text()) },\n    () => \"Send a WebSocket upgrade request to connect.\",\n  ),\n);\n",[221,1173,1174,1182,1189,1195,1228,1239,1243],{"__ignoreMap":242},[246,1175,1176,1178,1180],{"class":248,"line":249},[246,1177,334],{"class":256},[246,1179,337],{"class":319},[246,1181,681],{"class":256},[246,1183,1184,1187],{"class":248,"line":270},[246,1185,1186],{"class":263},"  \"/_ws\"",[246,1188,690],{"class":256},[246,1190,1191,1193],{"class":248,"line":277},[246,1192,696],{"class":319},[246,1194,681],{"class":256},[246,1196,1197,1200,1202,1205,1207,1209,1211,1213,1215,1218,1220,1223,1225],{"class":248,"line":298},[246,1198,1199],{"class":256},"    { ",[246,1201,850],{"class":319},[246,1203,1204],{"class":256},": (",[246,1206,715],{"class":391},[246,1208,346],{"class":256},[246,1210,850],{"class":391},[246,1212,395],{"class":256},[246,1214,398],{"class":252},[246,1216,1217],{"class":256}," peer.",[246,1219,755],{"class":319},[246,1221,1222],{"class":256},"(message.",[246,1224,883],{"class":319},[246,1226,1227],{"class":256},"()) },\n",[246,1229,1230,1232,1234,1237],{"class":248,"line":303},[246,1231,1084],{"class":256},[246,1233,398],{"class":252},[246,1235,1236],{"class":263}," \"Send a WebSocket upgrade request to connect.\"",[246,1238,690],{"class":256},[246,1240,1241],{"class":248,"line":326},[246,1242,1095],{"class":256},[246,1244,1245],{"class":248,"line":331},[246,1246,763],{"class":256},[213,1248,1250],{"id":1249},"server-sent-events-sse","Server-Sent Events (SSE)",[195,1252,1253,1254,205],{},"As an alternative to WebSockets, you can use ",[199,1255,1258],{"href":1256,"rel":1257},"https://developer.mozilla.org/en-US/docs/Web/API/Server-sent_events",[203],"Server-sent events",[195,1260,1261,1262,1265],{},"H3 has a built-in API to create server-sent events using ",[221,1263,1264],{},"createEventStream(event)"," utility.",[1152,1267,1269],{"id":1268},"example","Example",[237,1271,1274],{"className":239,"code":1272,"filename":1273,"language":241,"meta":242,"style":242},"import { H3, serve, createEventStream } from \"h3\";\n\nexport const app = new H3();\n\napp.get(\"/\", (event) => {\n  const eventStream = createEventStream(event);\n\n  // Send a message every second\n  const interval = setInterval(async () => {\n    await eventStream.push(\"Hello world\");\n  }, 1000);\n\n  // cleanup the interval when the connection is terminated or the writer is closed\n  eventStream.onClosed(() => {\n    console.log(\"Connection closed\");\n    clearInterval(interval);\n  });\n\n  return eventStream.send();\n});\n\nserve(app);\n","server-sent-events.mjs",[221,1275,1276,1289,1293,1309,1313,1337,1353,1357,1362,1385,1403,1413,1417,1422,1437,1451,1459,1464,1468,1479,1483,1487],{"__ignoreMap":242},[246,1277,1278,1280,1283,1285,1287],{"class":248,"line":249},[246,1279,253],{"class":252},[246,1281,1282],{"class":256}," { H3, serve, createEventStream } ",[246,1284,260],{"class":252},[246,1286,264],{"class":263},[246,1288,267],{"class":256},[246,1290,1291],{"class":248,"line":270},[246,1292,274],{"emptyLinePlaceholder":273},[246,1294,1295,1297,1299,1301,1303,1305,1307],{"class":248,"line":277},[246,1296,468],{"class":252},[246,1298,471],{"class":252},[246,1300,310],{"class":309},[246,1302,313],{"class":252},[246,1304,316],{"class":252},[246,1306,320],{"class":319},[246,1308,323],{"class":256},[246,1310,1311],{"class":248,"line":298},[246,1312,274],{"emptyLinePlaceholder":273},[246,1314,1315,1317,1319,1321,1324,1327,1330,1332,1334],{"class":248,"line":303},[246,1316,334],{"class":256},[246,1318,337],{"class":319},[246,1320,340],{"class":256},[246,1322,1323],{"class":263},"\"/\"",[246,1325,1326],{"class":256},", (",[246,1328,1329],{"class":391},"event",[246,1331,395],{"class":256},[246,1333,398],{"class":252},[246,1335,1336],{"class":256}," {\n",[246,1338,1339,1342,1345,1347,1350],{"class":248,"line":326},[246,1340,1341],{"class":252},"  const",[246,1343,1344],{"class":309}," eventStream",[246,1346,313],{"class":252},[246,1348,1349],{"class":319}," createEventStream",[246,1351,1352],{"class":256},"(event);\n",[246,1354,1355],{"class":248,"line":331},[246,1356,274],{"emptyLinePlaceholder":273},[246,1358,1359],{"class":248,"line":355},[246,1360,1361],{"class":490},"  // Send a message every second\n",[246,1363,1364,1366,1369,1371,1374,1376,1378,1381,1383],{"class":248,"line":360},[246,1365,1341],{"class":252},[246,1367,1368],{"class":309}," interval",[246,1370,313],{"class":252},[246,1372,1373],{"class":319}," setInterval",[246,1375,340],{"class":256},[246,1377,385],{"class":252},[246,1379,1380],{"class":256}," () ",[246,1382,398],{"class":252},[246,1384,1336],{"class":256},[246,1386,1387,1390,1393,1396,1398,1401],{"class":248,"line":368},[246,1388,1389],{"class":252},"    await",[246,1391,1392],{"class":256}," eventStream.",[246,1394,1395],{"class":319},"push",[246,1397,340],{"class":256},[246,1399,1400],{"class":263},"\"Hello world\"",[246,1402,763],{"class":256},[246,1404,1405,1408,1411],{"class":248,"line":415},[246,1406,1407],{"class":256},"  }, ",[246,1409,1410],{"class":309},"1000",[246,1412,763],{"class":256},[246,1414,1415],{"class":248,"line":529},[246,1416,274],{"emptyLinePlaceholder":273},[246,1418,1419],{"class":248,"line":535},[246,1420,1421],{"class":490},"  // cleanup the interval when the connection is terminated or the writer is closed\n",[246,1423,1424,1427,1430,1433,1435],{"class":248,"line":541},[246,1425,1426],{"class":256},"  eventStream.",[246,1428,1429],{"class":319},"onClosed",[246,1431,1432],{"class":256},"(() ",[246,1434,398],{"class":252},[246,1436,1336],{"class":256},[246,1438,1439,1442,1444,1446,1449],{"class":248,"line":547},[246,1440,1441],{"class":256},"    console.",[246,1443,727],{"class":319},[246,1445,340],{"class":256},[246,1447,1448],{"class":263},"\"Connection closed\"",[246,1450,763],{"class":256},[246,1452,1453,1456],{"class":248,"line":553},[246,1454,1455],{"class":319},"    clearInterval",[246,1457,1458],{"class":256},"(interval);\n",[246,1460,1461],{"class":248,"line":559},[246,1462,1463],{"class":256},"  });\n",[246,1465,1466],{"class":248,"line":565},[246,1467,274],{"emptyLinePlaceholder":273},[246,1469,1470,1473,1475,1477],{"class":248,"line":571},[246,1471,1472],{"class":252},"  return",[246,1474,1392],{"class":256},[246,1476,755],{"class":319},[246,1478,323],{"class":256},[246,1480,1481],{"class":248,"line":577},[246,1482,418],{"class":256},[246,1484,1485],{"class":248,"line":583},[246,1486,274],{"emptyLinePlaceholder":273},[246,1488,1489,1491],{"class":248,"line":589},[246,1490,230],{"class":319},[246,1492,1493],{"class":256},"(app);\n",[1495,1496,1497],"style",{},"html pre.shiki code .so5gQ, html code.shiki .so5gQ{--shiki-light:#D73A49;--shiki-default:#F97583;--shiki-dark:#F97583}html pre.shiki code .slsVL, html code.shiki .slsVL{--shiki-light:#24292E;--shiki-default:#E1E4E8;--shiki-dark:#E1E4E8}html pre.shiki code .sfrk1, html code.shiki .sfrk1{--shiki-light:#032F62;--shiki-default:#9ECBFF;--shiki-dark:#9ECBFF}html pre.shiki code .suiK_, html code.shiki .suiK_{--shiki-light:#005CC5;--shiki-default:#79B8FF;--shiki-dark:#79B8FF}html pre.shiki code .shcOC, html code.shiki .shcOC{--shiki-light:#6F42C1;--shiki-default:#B392F0;--shiki-dark:#B392F0}html pre.shiki code .sQHwn, html code.shiki .sQHwn{--shiki-light:#E36209;--shiki-default:#FFAB70;--shiki-dark:#FFAB70}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 .sCsY4, html code.shiki .sCsY4{--shiki-light:#6A737D;--shiki-default:#6A737D;--shiki-dark:#6A737D}",{"title":242,"searchDepth":270,"depth":270,"links":1499},[1500,1503],{"id":215,"depth":270,"text":216,"children":1501},[1502],{"id":1154,"depth":277,"text":1155},{"id":1249,"depth":270,"text":1250,"children":1504},[1505],{"id":1268,"depth":277,"text":1269},"H3 has built-in utilities for cross platform WebSocket and Server-Sent Events.","md",{"automd":273,"icon":84},{"icon":84},{"title":81,"description":1506},"9EKq6wgcNdeljMixiRlexSJ1k3CHGHUXbfsx45VVjRA",[1513,1515],{"title":76,"path":77,"stem":78,"description":1514,"icon":79,"children":-1},"H3 plugins allow you to extend an H3 app instance with reusable logic.",{"title":86,"path":87,"stem":88,"description":242,"icon":89,"children":-1},1783079139033]