[{"data":1,"prerenderedAt":924},["ShallowReactive",2],{"navigation":3,"blog":111},[4,38,77,97,104],{"title":5,"path":6,"stem":7,"children":8,"icon":37},"Getting Started","\u002Fgetting-started","1.getting-started\u002F1.index",[9,12,17,22,27,32],{"title":10,"path":6,"stem":7,"icon":11},"Introduction","i-lucide-house",{"title":13,"path":14,"stem":15,"icon":16},"Installation","\u002Fgetting-started\u002Finstallation","1.getting-started\u002F2.installation","i-lucide-download",{"title":18,"path":19,"stem":20,"icon":21},"Configuration","\u002Fgetting-started\u002Fconfiguration","1.getting-started\u002F3.configuration","i-lucide-settings",{"title":23,"path":24,"stem":25,"icon":26},"Usage","\u002Fgetting-started\u002Fusage","1.getting-started\u002F4.usage","i-lucide-code",{"title":28,"path":29,"stem":30,"icon":31},"Authentication","\u002Fgetting-started\u002Fauthentication","1.getting-started\u002F5.authentication","i-lucide-lock",{"title":33,"path":34,"stem":35,"icon":36},"DevTools","\u002Fgetting-started\u002Fdevtools","1.getting-started\u002F6.devtools","i-lucide-radio-tower",false,{"title":39,"icon":26,"path":40,"stem":41,"children":42,"page":37},"Composables","\u002Fcomposables","2.composables",[43,48,53,58,63,67,72],{"title":44,"path":45,"stem":46,"icon":47},"useRealtimeState","\u002Fcomposables\u002Fuserealtimestate","2.composables\u002F1.useRealtimeState","i-lucide-refresh-cw",{"title":49,"path":50,"stem":51,"icon":52},"useRealtimeEvents","\u002Fcomposables\u002Fuserealtimeevents","2.composables\u002F2.useRealtimeEvents","i-lucide-radio",{"title":54,"path":55,"stem":56,"icon":57},"useRealtimeConnection","\u002Fcomposables\u002Fuserealtimeconnection","2.composables\u002F3.useRealtimeConnection","i-lucide-wifi",{"title":59,"path":60,"stem":61,"icon":62},"useRealtimePresence","\u002Fcomposables\u002Fuserealtimepresence","2.composables\u002F4.useRealtimePresence","i-lucide-users",{"title":64,"path":65,"stem":66,"icon":31},"useRealtimeLock","\u002Fcomposables\u002Fuserealtimelock","2.composables\u002F5.useRealtimeLock",{"title":68,"path":69,"stem":70,"icon":71},"useRealtimeLockRoom","\u002Fcomposables\u002Fuserealtimelockroom","2.composables\u002F6.useRealtimeLockRoom","i-lucide-list-checks",{"title":73,"path":74,"stem":75,"icon":76},"useRealtimeRoom","\u002Fcomposables\u002Fuserealtimeroom","2.composables\u002F7.useRealtimeRoom","i-lucide-door-open",{"title":78,"icon":79,"path":80,"stem":81,"children":82,"page":37},"Technical","i-lucide-cpu","\u002Ftechnical","3.technical",[83,88,92],{"title":84,"path":85,"stem":86,"icon":87},"Architecture","\u002Ftechnical\u002Farchitecture","3.technical\u002F1.architecture","i-lucide-network",{"title":89,"path":90,"stem":91,"icon":52},"Notification Layer","\u002Ftechnical\u002Fpubsub","3.technical\u002F2.pubsub",{"title":93,"path":94,"stem":95,"icon":96},"Multi-Server Sync","\u002Ftechnical\u002Fcross-server-sync","3.technical\u002F3.cross-server-sync","i-lucide-server",{"title":98,"path":99,"stem":100,"children":101,"icon":103},"Blocks","\u002Fblocks","4.blocks\u002F1.index",[102],{"title":98,"path":99,"stem":100,"icon":103},"i-lucide-layout-grid",{"title":105,"path":106,"stem":107,"children":108,"icon":110},"Components","\u002Fcomponents","5.components\u002F1.index",[109],{"title":105,"path":106,"stem":107,"icon":110},"i-lucide-component",[112,901],{"id":113,"title":114,"authors":115,"body":121,"category":889,"date":890,"description":891,"extension":892,"image":893,"meta":894,"navigation":221,"path":895,"seo":896,"stem":897,"tags":898,"__hash__":900},"blog\u002Fblog\u002Fversion-2.md","Nuxt Realtime 0.2",[116],{"name":117,"avatar":118,"to":120},"Daan van Geloven",{"src":119},"https:\u002F\u002Fgithub.com\u002Fdaanvangeloven.png","https:\u002F\u002Fgithub.com\u002Fdaanvangeloven",{"type":122,"value":123,"toc":879},"minimark",[124,128,133,142,368,375,379,386,458,465,471,476,479,486,600,605,610,614,621,631,636,640,659,664,668,679,841,846,850,860,864,875],[125,126,127],"p",{},"Nuxt Realtime 0.2 is out. Here's what's new since the last release.",[129,130,132],"h2",{"id":131},"rooms","Rooms",[125,134,135,141],{},[136,137,138],"a",{"href":74},[139,140,73],"code",{}," ties state, events, presence, and locks together under one room id, with server-side lifecycle hooks and a single auth checkpoint instead of gating every handler individually.",[143,144,149],"pre",{"className":145,"code":146,"language":147,"meta":148,"style":148},"language-vue shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","\u003Cscript setup lang=\"ts\">\nconst room = useRealtimeRoom('document:123')\n\nconst doc = room.state('content', '')\nconst { members } = room.presence({ info: { name: 'Alice' } })\nconst { claim, release, ownedByMe } = room.lock('editing')\n\u003C\u002Fscript>\n","vue","",[139,150,151,186,216,223,259,316,358],{"__ignoreMap":148},[152,153,156,160,164,168,171,174,177,181,183],"span",{"class":154,"line":155},"line",1,[152,157,159],{"class":158},"sMK4o","\u003C",[152,161,163],{"class":162},"swJcz","script",[152,165,167],{"class":166},"spNyl"," setup",[152,169,170],{"class":166}," lang",[152,172,173],{"class":158},"=",[152,175,176],{"class":158},"\"",[152,178,180],{"class":179},"sfazB","ts",[152,182,176],{"class":158},[152,184,185],{"class":158},">\n",[152,187,189,192,196,198,202,205,208,211,213],{"class":154,"line":188},2,[152,190,191],{"class":166},"const",[152,193,195],{"class":194},"sTEyZ"," room ",[152,197,173],{"class":158},[152,199,201],{"class":200},"s2Zo4"," useRealtimeRoom",[152,203,204],{"class":194},"(",[152,206,207],{"class":158},"'",[152,209,210],{"class":179},"document:123",[152,212,207],{"class":158},[152,214,215],{"class":194},")\n",[152,217,219],{"class":154,"line":218},3,[152,220,222],{"emptyLinePlaceholder":221},true,"\n",[152,224,226,228,231,233,236,239,242,244,246,249,251,254,257],{"class":154,"line":225},4,[152,227,191],{"class":166},[152,229,230],{"class":194}," doc ",[152,232,173],{"class":158},[152,234,235],{"class":194}," room",[152,237,238],{"class":158},".",[152,240,241],{"class":200},"state",[152,243,204],{"class":194},[152,245,207],{"class":158},[152,247,248],{"class":179},"content",[152,250,207],{"class":158},[152,252,253],{"class":158},",",[152,255,256],{"class":158}," ''",[152,258,215],{"class":194},[152,260,262,264,267,270,273,276,278,280,283,285,288,291,294,296,299,301,304,307,309,312,314],{"class":154,"line":261},5,[152,263,191],{"class":166},[152,265,266],{"class":158}," {",[152,268,269],{"class":194}," members ",[152,271,272],{"class":158},"}",[152,274,275],{"class":158}," =",[152,277,235],{"class":194},[152,279,238],{"class":158},[152,281,282],{"class":200},"presence",[152,284,204],{"class":194},[152,286,287],{"class":158},"{",[152,289,290],{"class":162}," info",[152,292,293],{"class":158},":",[152,295,266],{"class":158},[152,297,298],{"class":162}," name",[152,300,293],{"class":158},[152,302,303],{"class":158}," '",[152,305,306],{"class":179},"Alice",[152,308,207],{"class":158},[152,310,311],{"class":158}," }",[152,313,311],{"class":158},[152,315,215],{"class":194},[152,317,319,321,323,326,328,331,333,336,338,340,342,344,347,349,351,354,356],{"class":154,"line":318},6,[152,320,191],{"class":166},[152,322,266],{"class":158},[152,324,325],{"class":194}," claim",[152,327,253],{"class":158},[152,329,330],{"class":194}," release",[152,332,253],{"class":158},[152,334,335],{"class":194}," ownedByMe ",[152,337,272],{"class":158},[152,339,275],{"class":158},[152,341,235],{"class":194},[152,343,238],{"class":158},[152,345,346],{"class":200},"lock",[152,348,204],{"class":194},[152,350,207],{"class":158},[152,352,353],{"class":179},"editing",[152,355,207],{"class":158},[152,357,215],{"class":194},[152,359,361,364,366],{"class":154,"line":360},7,[152,362,363],{"class":158},"\u003C\u002F",[152,365,163],{"class":162},[152,367,185],{"class":158},[125,369,370,371,374],{},"See the ",[136,372,373],{"href":74},"rooms docs"," for details.",[129,376,378],{"id":377},"locking","Locking",[125,380,381,385],{},[136,382,383],{"href":65},[139,384,64],{}," claims exclusive ownership of a key across all connected clients, so only one user edits a record or drags a card at a time.",[143,387,389],{"className":145,"code":388,"language":147,"meta":148,"style":148},"\u003Cscript setup lang=\"ts\">\nconst { claim, release, ownedByMe, locked } = useRealtimeLock('document:123')\n\u003C\u002Fscript>\n",[139,390,391,411,450],{"__ignoreMap":148},[152,392,393,395,397,399,401,403,405,407,409],{"class":154,"line":155},[152,394,159],{"class":158},[152,396,163],{"class":162},[152,398,167],{"class":166},[152,400,170],{"class":166},[152,402,173],{"class":158},[152,404,176],{"class":158},[152,406,180],{"class":179},[152,408,176],{"class":158},[152,410,185],{"class":158},[152,412,413,415,417,419,421,423,425,428,430,433,435,437,440,442,444,446,448],{"class":154,"line":188},[152,414,191],{"class":166},[152,416,266],{"class":158},[152,418,325],{"class":194},[152,420,253],{"class":158},[152,422,330],{"class":194},[152,424,253],{"class":158},[152,426,427],{"class":194}," ownedByMe",[152,429,253],{"class":158},[152,431,432],{"class":194}," locked ",[152,434,272],{"class":158},[152,436,275],{"class":158},[152,438,439],{"class":200}," useRealtimeLock",[152,441,204],{"class":194},[152,443,207],{"class":158},[152,445,210],{"class":179},[152,447,207],{"class":158},[152,449,215],{"class":194},[152,451,452,454,456],{"class":154,"line":218},[152,453,363],{"class":158},[152,455,163],{"class":162},[152,457,185],{"class":158},[125,459,460,464],{},[136,461,462],{"href":69},[139,463,68],{}," pairs with it for a bulk, read-only view of every lock tagged with a room, without subscribing to each key individually.",[125,466,467],{},[468,469],"video",{"src":470,"autoPlay":221,"loop":221,"muted":221,"playsInline":221},"\u002Flock-demo.mp4",[125,472,370,473,374],{},[136,474,475],{"href":65},"locking docs",[129,477,478],{"id":282},"Presence",[125,480,481,485],{},[136,482,483],{"href":60},[139,484,59],{}," tracks which clients are currently present in a room, with optional info about each one (a name, avatar, cursor position). Useful for \"who's viewing this page\" indicators and avatar stacks.",[143,487,489],{"className":145,"code":488,"language":147,"meta":148,"style":148},"\u003Cscript setup lang=\"ts\">\nconst { members, join, leave } = useRealtimePresence('document:123', {\n  info: { name: 'Alice', avatarUrl: '\u002Falice.png' },\n})\n\u003C\u002Fscript>\n",[139,490,491,511,550,586,592],{"__ignoreMap":148},[152,492,493,495,497,499,501,503,505,507,509],{"class":154,"line":155},[152,494,159],{"class":158},[152,496,163],{"class":162},[152,498,167],{"class":166},[152,500,170],{"class":166},[152,502,173],{"class":158},[152,504,176],{"class":158},[152,506,180],{"class":179},[152,508,176],{"class":158},[152,510,185],{"class":158},[152,512,513,515,517,520,522,525,527,530,532,534,537,539,541,543,545,547],{"class":154,"line":188},[152,514,191],{"class":166},[152,516,266],{"class":158},[152,518,519],{"class":194}," members",[152,521,253],{"class":158},[152,523,524],{"class":194}," join",[152,526,253],{"class":158},[152,528,529],{"class":194}," leave ",[152,531,272],{"class":158},[152,533,275],{"class":158},[152,535,536],{"class":200}," useRealtimePresence",[152,538,204],{"class":194},[152,540,207],{"class":158},[152,542,210],{"class":179},[152,544,207],{"class":158},[152,546,253],{"class":158},[152,548,549],{"class":158}," {\n",[152,551,552,555,557,559,561,563,565,567,569,571,574,576,578,581,583],{"class":154,"line":218},[152,553,554],{"class":162},"  info",[152,556,293],{"class":158},[152,558,266],{"class":158},[152,560,298],{"class":162},[152,562,293],{"class":158},[152,564,303],{"class":158},[152,566,306],{"class":179},[152,568,207],{"class":158},[152,570,253],{"class":158},[152,572,573],{"class":162}," avatarUrl",[152,575,293],{"class":158},[152,577,303],{"class":158},[152,579,580],{"class":179},"\u002Falice.png",[152,582,207],{"class":158},[152,584,585],{"class":158}," },\n",[152,587,588,590],{"class":154,"line":225},[152,589,272],{"class":158},[152,591,215],{"class":194},[152,593,594,596,598],{"class":154,"line":261},[152,595,363],{"class":158},[152,597,163],{"class":162},[152,599,185],{"class":158},[125,601,602],{},[468,603],{"src":604,"autoPlay":221,"loop":221,"muted":221,"playsInline":221},"\u002Fpresence-demo.mp4",[125,606,370,607,374],{},[136,608,609],{"href":60},"presence docs",[129,611,613],{"id":612},"realtime-devtools","Realtime DevTools",[125,615,616],{},[617,618],"img",{"alt":619,"src":620},"image","\u002Frealtime-devtools.png",[125,622,623,624,630],{},"A \"Realtime\" tab in ",[136,625,629],{"href":626,"rel":627},"https:\u002F\u002Fdevtools.nuxt.com\u002F",[628],"nofollow","Nuxt DevTools"," shows what's happening on the wire while you develop: active connections, subscribed channels and storage keys per socket, live storage values, and a scrolling event log. It's dev-only and never ships in production.",[125,632,370,633,374],{},[136,634,635],{"href":34},"DevTools docs",[129,637,639],{"id":638},"connection-authentication","Connection authentication",[125,641,642,643,646,647,650,651,654,655,658],{},"A new ",[139,644,645],{},"nuxt-realtime:io"," Nitro hook exposes the Socket.IO ",[139,648,649],{},"Server"," before any connections are accepted, so you can register ",[139,652,653],{},"io.use()"," middleware to authenticate or authorize clients — JWT, session cookies, or anything else. A matching ",[139,656,657],{},"nuxt-realtime:auth"," app hook lets the client attach a fresh token on every connection attempt, including reconnects.",[125,660,370,661,374],{},[136,662,663],{"href":29},"Authentication docs",[129,665,667],{"id":666},"redis-cluster-support","Redis Cluster support",[125,669,670,671,674,675,678],{},"The Redis driver now accepts a ",[139,672,673],{},"cluster"," option, so ",[139,676,677],{},"reactiveRedisDriver()"," can talk to a Redis Cluster instead of a single node:",[143,680,683],{"className":681,"code":682,"language":180,"meta":148,"style":148},"language-ts shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","import { reactiveRedisDriver } from 'nuxt-realtime\u002Fdrivers\u002Fredis'\n\nexport default defineNuxtConfig({\n  nuxtRealtime: {\n    storage: reactiveRedisDriver({\n      cluster: [{ host: 'redis-1', port: 6379 }, { host: 'redis-2', port: 6379 }],\n    }),\n  },\n})\n",[139,684,685,709,713,729,738,751,818,828,834],{"__ignoreMap":148},[152,686,687,691,693,696,698,701,703,706],{"class":154,"line":155},[152,688,690],{"class":689},"s7zQu","import",[152,692,266],{"class":158},[152,694,695],{"class":194}," reactiveRedisDriver",[152,697,311],{"class":158},[152,699,700],{"class":689}," from",[152,702,303],{"class":158},[152,704,705],{"class":179},"nuxt-realtime\u002Fdrivers\u002Fredis",[152,707,708],{"class":158},"'\n",[152,710,711],{"class":154,"line":188},[152,712,222],{"emptyLinePlaceholder":221},[152,714,715,718,721,724,726],{"class":154,"line":218},[152,716,717],{"class":689},"export",[152,719,720],{"class":689}," default",[152,722,723],{"class":200}," defineNuxtConfig",[152,725,204],{"class":194},[152,727,728],{"class":158},"{\n",[152,730,731,734,736],{"class":154,"line":225},[152,732,733],{"class":162},"  nuxtRealtime",[152,735,293],{"class":158},[152,737,549],{"class":158},[152,739,740,743,745,747,749],{"class":154,"line":261},[152,741,742],{"class":162},"    storage",[152,744,293],{"class":158},[152,746,695],{"class":200},[152,748,204],{"class":194},[152,750,728],{"class":158},[152,752,753,756,758,761,763,766,768,770,773,775,777,780,782,786,789,791,793,795,797,800,802,804,806,808,810,812,815],{"class":154,"line":318},[152,754,755],{"class":162},"      cluster",[152,757,293],{"class":158},[152,759,760],{"class":194}," [",[152,762,287],{"class":158},[152,764,765],{"class":162}," host",[152,767,293],{"class":158},[152,769,303],{"class":158},[152,771,772],{"class":179},"redis-1",[152,774,207],{"class":158},[152,776,253],{"class":158},[152,778,779],{"class":162}," port",[152,781,293],{"class":158},[152,783,785],{"class":784},"sbssI"," 6379",[152,787,788],{"class":158}," },",[152,790,266],{"class":158},[152,792,765],{"class":162},[152,794,293],{"class":158},[152,796,303],{"class":158},[152,798,799],{"class":179},"redis-2",[152,801,207],{"class":158},[152,803,253],{"class":158},[152,805,779],{"class":162},[152,807,293],{"class":158},[152,809,785],{"class":784},[152,811,311],{"class":158},[152,813,814],{"class":194},"]",[152,816,817],{"class":158},",\n",[152,819,820,823,826],{"class":154,"line":360},[152,821,822],{"class":158},"    }",[152,824,825],{"class":194},")",[152,827,817],{"class":158},[152,829,831],{"class":154,"line":830},8,[152,832,833],{"class":158},"  },\n",[152,835,837,839],{"class":154,"line":836},9,[152,838,272],{"class":158},[152,840,215],{"class":194},[125,842,370,843,374],{},[136,844,845],{"href":19},"configuration docs",[129,847,849],{"id":848},"configurable-socketio-path","Configurable Socket.IO path",[125,851,852,855,856,859],{},[139,853,854],{},"socketio.path"," lets you move the Socket.IO endpoint off the ",[139,857,858],{},"\u002Fsocket.io"," default (useful behind a reverse proxy that already owns that path). The client and server now derive the same path from this single option.",[129,861,863],{"id":862},"fixes","Fixes",[865,866,867],"ul",{},[868,869,870,871,874],"li",{},"Client-supplied storage keys can no longer read or write the internal ",[139,872,873],{},"_lease:"," namespace used for storage expiry.",[876,877,878],"style",{},"html pre.shiki code .sMK4o, html code.shiki .sMK4o{--shiki-light:#39ADB5;--shiki-default:#89DDFF;--shiki-dark:#89DDFF}html pre.shiki code .swJcz, html code.shiki .swJcz{--shiki-light:#E53935;--shiki-default:#F07178;--shiki-dark:#F07178}html pre.shiki code .spNyl, html code.shiki .spNyl{--shiki-light:#9C3EDA;--shiki-default:#C792EA;--shiki-dark:#C792EA}html pre.shiki code .sfazB, html code.shiki .sfazB{--shiki-light:#91B859;--shiki-default:#C3E88D;--shiki-dark:#C3E88D}html pre.shiki code .sTEyZ, html code.shiki .sTEyZ{--shiki-light:#90A4AE;--shiki-default:#EEFFFF;--shiki-dark:#BABED8}html pre.shiki code .s2Zo4, html code.shiki .s2Zo4{--shiki-light:#6182B8;--shiki-default:#82AAFF;--shiki-dark:#82AAFF}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 .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 .sbssI, html code.shiki .sbssI{--shiki-light:#F76D47;--shiki-default:#F78C6C;--shiki-dark:#F78C6C}",{"title":148,"searchDepth":155,"depth":188,"links":880},[881,882,883,884,885,886,887,888],{"id":131,"depth":188,"text":132},{"id":377,"depth":188,"text":378},{"id":282,"depth":188,"text":478},{"id":612,"depth":188,"text":613},{"id":638,"depth":188,"text":639},{"id":666,"depth":188,"text":667},{"id":848,"depth":188,"text":849},{"id":862,"depth":188,"text":863},"Release","2026-07-31T00:00:00.000Z","DevTools, connection auth, and presence\u002Flocking\u002Frooms land in Nuxt Realtime 0.2.","md",null,{},"\u002Fblog\u002Fversion-2",{"title":114,"description":891},"blog\u002Fversion-2",[899],"release","ULNE3Stv56E2HMjCzWUU0Vxpifh5RM5FDUsnUY-WPTA",{"id":902,"title":903,"authors":904,"body":907,"category":914,"date":915,"description":916,"extension":892,"image":893,"meta":917,"navigation":221,"path":918,"seo":919,"stem":920,"tags":921,"__hash__":923},"blog\u002Fblog\u002Fwelcome-to-the-blog.md","Welcome to the Nuxt Realtime blog",[905],{"name":117,"avatar":906,"to":120},{"src":119},{"type":122,"value":908,"toc":912},[909],[125,910,911],{},"We're using this space to share release notes and articles about building realtime experiences with Nuxt Realtime.",{"title":148,"searchDepth":155,"depth":188,"links":913},[],"Announcement","2026-07-30T00:00:00.000Z","Articles, release notes, and updates about Nuxt Realtime.",{},"\u002Fblog\u002Fwelcome-to-the-blog",{"title":903,"description":916},"blog\u002Fwelcome-to-the-blog",[922],"announcement","CRn_u2a0DCfS8nQ79ZEL8NR2KHpxPG4XQkNQS4zqCAU",1787657972301]