[{"data":1,"prerenderedAt":1796},["ShallowReactive",2],{"docs:/docs/getting-started":3},{"id":4,"title":5,"body":6,"description":1789,"extension":1790,"meta":1791,"navigation":264,"path":1792,"seo":1793,"stem":1794,"__hash__":1795},"docs/docs/getting-started.md","Getting Started",{"type":7,"value":8,"toc":1778},"minimark",[9,13,17,22,40,43,47,50,110,114,117,140,145,169,180,369,379,403,427,435,439,446,827,831,834,837,1045,1049,1052,1179,1183,1186,1702,1706,1725,1737,1744,1748,1774],[10,11,5],"h1",{"id":12},"getting-started",[14,15,16],"p",{},"Get up and running with NoLag in under 5 minutes.",[18,19,21],"h2",{"id":20},"prerequisites","Prerequisites",[23,24,25,37],"ul",{},[26,27,28,29,36],"li",{},"A NoLag account (",[30,31,35],"a",{"href":32,"rel":33},"https://portal.nolag.app",[34],"nofollow","sign up free",")",[26,38,39],{},"Node.js 18+ (for the JavaScript SDK)",[14,41,42],{},"You create your app and access token in Step 2, so nothing else is needed up front.",[18,44,46],{"id":45},"step-1-install-the-sdk","Step 1: Install the SDK",[14,48,49],{},"Install the NoLag SDK for your preferred language:",[51,52,53,86,98],"code-tabs",{},[54,55,61],"pre",{"className":56,"code":57,"filename":58,"language":59,"meta":60,"style":60},"language-typescript shiki shiki-themes github-light github-dark","npm install @nolag/js-sdk\n","npm","typescript","",[62,63,64],"code",{"__ignoreMap":60},[65,66,69,73,77,80,83],"span",{"class":67,"line":68},"line",1,[65,70,72],{"class":71},"sVt8B","npm install @nolag",[65,74,76],{"class":75},"szBVR","/",[65,78,79],{"class":71},"js",[65,81,82],{"class":75},"-",[65,84,85],{"class":71},"sdk\n",[54,87,92],{"className":88,"code":89,"filename":90,"language":91,"meta":60,"style":60},"language-python shiki shiki-themes github-light github-dark","pip install nolag\n","pip","python",[62,93,94],{"__ignoreMap":60},[65,95,96],{"class":67,"line":68},[65,97,89],{},[54,99,104],{"className":100,"code":101,"filename":102,"language":103,"meta":60,"style":60},"language-go shiki shiki-themes github-light github-dark","go get github.com/NoLagApp/go-sdk\n","go get","go",[62,105,106],{"__ignoreMap":60},[65,107,108],{"class":67,"line":68},[65,109,101],{},[18,111,113],{"id":112},"step-2-create-an-app-a-room-and-an-access-token","Step 2: Create an App, a Room, and an Access Token",[14,115,116],{},"You need three things:",[23,118,119,127,134],{},[26,120,121,122,126],{},"an ",[123,124,125],"strong",{},"app",", a container for your rooms and topics",[26,128,129,130,133],{},"a ",[123,131,132],{},"room"," inside that app, the namespace your topics live in",[26,135,121,136,139],{},[123,137,138],{},"actor",", a client identity whose access token authenticates the connection",[14,141,142],{},[123,143,144],{},"In the dashboard:",[146,147,148,156,159,162],"ol",{},[26,149,150,151,155],{},"Log in to the ",[30,152,154],{"href":32,"rel":153},[34],"NoLag Dashboard"," and create a project.",[26,157,158],{},"Create an app inside the project.",[26,160,161],{},"Add a room to the app, and note its slug.",[26,163,164,165,168],{},"Open the ",[123,166,167],{},"Actors"," section, create an actor, and copy its access token.",[14,170,171,174,175,179],{},[123,172,173],{},"Or over the REST API."," This is the path to use from a script or an AI agent\nthat sets everything up on its own. The only bootstrap secret is a project-scoped\n",[30,176,178],{"href":177},"/docs/authentication#api-keys","API key",", created once in the dashboard;\neverything else is an API call:",[51,181,182],{},[54,183,188],{"className":184,"code":185,"filename":186,"language":187,"meta":60,"style":60},"language-bash shiki shiki-themes github-light github-dark","# 1. Create an app. Read appId and slug back out of the response:\n#    the returned slug is not the one you sent (see the note below).\ncurl -X POST https://api.nolag.app/v1/apps \\\n  -H \"Authorization: Bearer nlg_live_xxx.secret\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\"name\":\"My App\",\"slug\":\"my-app\",\"topics\":[\"messages\"]}'\n# => {\"appId\":\"019fd987-9dee-75cb-97a7-39d71957ca23\",\"slug\":\"my-app-a3f9\",...}\n\n# 2. Create a room in that app, using the appId from step 1.\n#    Clients cannot subscribe to a room that does not exist yet.\ncurl -X POST https://api.nolag.app/v1/apps/019fd987-9dee-75cb-97a7-39d71957ca23/rooms \\\n  -H \"Authorization: Bearer nlg_live_xxx.secret\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\"name\":\"General\",\"slug\":\"general\",\"topics\":[\"messages\"]}'\n\n# 3. Create an actor, then copy accessToken from the response\ncurl -X POST https://api.nolag.app/v1/actors \\\n  -H \"Authorization: Bearer nlg_live_xxx.secret\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\"name\":\"Web Client\",\"actorType\":\"device\"}'\n","Terminal","bash",[62,189,190,196,202,223,234,244,253,259,266,272,278,292,301,310,318,323,329,343,352,361],{"__ignoreMap":60},[65,191,192],{"class":67,"line":68},[65,193,195],{"class":194},"sJ8bj","# 1. Create an app. Read appId and slug back out of the response:\n",[65,197,199],{"class":67,"line":198},2,[65,200,201],{"class":194},"#    the returned slug is not the one you sent (see the note below).\n",[65,203,205,209,213,217,220],{"class":67,"line":204},3,[65,206,208],{"class":207},"sScJk","curl",[65,210,212],{"class":211},"sj4cs"," -X",[65,214,216],{"class":215},"sZZnC"," POST",[65,218,219],{"class":215}," https://api.nolag.app/v1/apps",[65,221,222],{"class":211}," \\\n",[65,224,226,229,232],{"class":67,"line":225},4,[65,227,228],{"class":211},"  -H",[65,230,231],{"class":215}," \"Authorization: Bearer nlg_live_xxx.secret\"",[65,233,222],{"class":211},[65,235,237,239,242],{"class":67,"line":236},5,[65,238,228],{"class":211},[65,240,241],{"class":215}," \"Content-Type: application/json\"",[65,243,222],{"class":211},[65,245,247,250],{"class":67,"line":246},6,[65,248,249],{"class":211},"  -d",[65,251,252],{"class":215}," '{\"name\":\"My App\",\"slug\":\"my-app\",\"topics\":[\"messages\"]}'\n",[65,254,256],{"class":67,"line":255},7,[65,257,258],{"class":194},"# => {\"appId\":\"019fd987-9dee-75cb-97a7-39d71957ca23\",\"slug\":\"my-app-a3f9\",...}\n",[65,260,262],{"class":67,"line":261},8,[65,263,265],{"emptyLinePlaceholder":264},true,"\n",[65,267,269],{"class":67,"line":268},9,[65,270,271],{"class":194},"# 2. Create a room in that app, using the appId from step 1.\n",[65,273,275],{"class":67,"line":274},10,[65,276,277],{"class":194},"#    Clients cannot subscribe to a room that does not exist yet.\n",[65,279,281,283,285,287,290],{"class":67,"line":280},11,[65,282,208],{"class":207},[65,284,212],{"class":211},[65,286,216],{"class":215},[65,288,289],{"class":215}," https://api.nolag.app/v1/apps/019fd987-9dee-75cb-97a7-39d71957ca23/rooms",[65,291,222],{"class":211},[65,293,295,297,299],{"class":67,"line":294},12,[65,296,228],{"class":211},[65,298,231],{"class":215},[65,300,222],{"class":211},[65,302,304,306,308],{"class":67,"line":303},13,[65,305,228],{"class":211},[65,307,241],{"class":215},[65,309,222],{"class":211},[65,311,313,315],{"class":67,"line":312},14,[65,314,249],{"class":211},[65,316,317],{"class":215}," '{\"name\":\"General\",\"slug\":\"general\",\"topics\":[\"messages\"]}'\n",[65,319,321],{"class":67,"line":320},15,[65,322,265],{"emptyLinePlaceholder":264},[65,324,326],{"class":67,"line":325},16,[65,327,328],{"class":194},"# 3. Create an actor, then copy accessToken from the response\n",[65,330,332,334,336,338,341],{"class":67,"line":331},17,[65,333,208],{"class":207},[65,335,212],{"class":211},[65,337,216],{"class":215},[65,339,340],{"class":215}," https://api.nolag.app/v1/actors",[65,342,222],{"class":211},[65,344,346,348,350],{"class":67,"line":345},18,[65,347,228],{"class":211},[65,349,231],{"class":215},[65,351,222],{"class":211},[65,353,355,357,359],{"class":67,"line":354},19,[65,356,228],{"class":211},[65,358,241],{"class":215},[65,360,222],{"class":211},[65,362,364,366],{"class":67,"line":363},20,[65,365,249],{"class":211},[65,367,368],{"class":215}," '{\"name\":\"Web Client\",\"actorType\":\"device\"}'\n",[370,371,373],"callout",{"type":372},"warning",[14,374,375,378],{},[123,376,377],{},"Save the token now."," An actor's access token is only returned when the actor is\ncreated. It is never shown again.",[370,380,381],{"type":372},[14,382,383,386,387,390,391,394,395,398,399,402],{},[123,384,385],{},"App slugs always get a random suffix."," NoLag appends four random characters to\nevery app slug to keep it unique within the project, so a requested slug of\n",[62,388,389],{},"my-app"," comes back as something like ",[62,392,393],{},"my-app-a3f9",". Read the ",[62,396,397],{},"slug"," field from the\ncreate response and pass that value to ",[62,400,401],{},"setApp()",". Room slugs are different: they\nare stored exactly as you supply them.",[370,404,405],{"type":372},[14,406,407,410,411,414,415,418,419,422,423,426],{},[123,408,409],{},"Rooms must exist before you connect."," Subscribing to a room that has not been\ncreated returns an ",[62,412,413],{},"unknown_topic"," error instead of delivering messages. If you\nskip the error handler in Step 3, this looks like total silence: ",[62,416,417],{},"connect()",",\n",[62,420,421],{},"subscribe()",", and ",[62,424,425],{},"emit()"," all appear to succeed and no message ever arrives.",[14,428,429,430,434],{},"See the ",[30,431,433],{"href":432},"/docs/api-reference","REST API Reference"," for the full app, room, and actor endpoints.",[18,436,438],{"id":437},"step-3-connect-to-nolag","Step 3: Connect to NoLag",[14,440,441,442,445],{},"Attach an error handler before you connect. Subscribe and publish calls do not\nthrow: the broker reports problems such as an unknown topic or a permission\nrefusal on the ",[62,443,444],{},"error"," event, so without a handler a misconfigured app simply\ngoes quiet.",[51,447,448,633,704],{},[54,449,452],{"className":56,"code":450,"filename":451,"language":59,"meta":60,"style":60},"import { NoLag } from '@nolag/js-sdk'\n\n// Create client and connect\nconst client = NoLag('your_access_token')\n\n// Attach this first: server-side errors arrive here, not as thrown exceptions\nclient.on('error', (err) => {\n  console.error(`NoLag ${err.error} (${err.code}) on ${err.topic}: ${err.hint}`)\n})\n\nawait client.connect()\n\nconsole.log('Connected to NoLag!')\n","TypeScript",[62,453,454,468,472,477,500,504,509,538,591,596,600,614,618],{"__ignoreMap":60},[65,455,456,459,462,465],{"class":67,"line":68},[65,457,458],{"class":75},"import",[65,460,461],{"class":71}," { NoLag } ",[65,463,464],{"class":75},"from",[65,466,467],{"class":215}," '@nolag/js-sdk'\n",[65,469,470],{"class":67,"line":198},[65,471,265],{"emptyLinePlaceholder":264},[65,473,474],{"class":67,"line":204},[65,475,476],{"class":194},"// Create client and connect\n",[65,478,479,482,485,488,491,494,497],{"class":67,"line":225},[65,480,481],{"class":75},"const",[65,483,484],{"class":211}," client",[65,486,487],{"class":75}," =",[65,489,490],{"class":207}," NoLag",[65,492,493],{"class":71},"(",[65,495,496],{"class":215},"'your_access_token'",[65,498,499],{"class":71},")\n",[65,501,502],{"class":67,"line":236},[65,503,265],{"emptyLinePlaceholder":264},[65,505,506],{"class":67,"line":246},[65,507,508],{"class":194},"// Attach this first: server-side errors arrive here, not as thrown exceptions\n",[65,510,511,514,517,519,522,525,529,532,535],{"class":67,"line":255},[65,512,513],{"class":71},"client.",[65,515,516],{"class":207},"on",[65,518,493],{"class":71},[65,520,521],{"class":215},"'error'",[65,523,524],{"class":71},", (",[65,526,528],{"class":527},"s4XuR","err",[65,530,531],{"class":71},") ",[65,533,534],{"class":75},"=>",[65,536,537],{"class":71}," {\n",[65,539,540,543,545,547,550,552,555,557,560,562,564,566,569,571,573,576,579,581,583,586,589],{"class":67,"line":261},[65,541,542],{"class":71},"  console.",[65,544,444],{"class":207},[65,546,493],{"class":71},[65,548,549],{"class":215},"`NoLag ${",[65,551,528],{"class":71},[65,553,554],{"class":215},".",[65,556,444],{"class":71},[65,558,559],{"class":215},"} (${",[65,561,528],{"class":71},[65,563,554],{"class":215},[65,565,62],{"class":71},[65,567,568],{"class":215},"}) on ${",[65,570,528],{"class":71},[65,572,554],{"class":215},[65,574,575],{"class":71},"topic",[65,577,578],{"class":215},"}: ${",[65,580,528],{"class":71},[65,582,554],{"class":215},[65,584,585],{"class":71},"hint",[65,587,588],{"class":215},"}`",[65,590,499],{"class":71},[65,592,593],{"class":67,"line":268},[65,594,595],{"class":71},"})\n",[65,597,598],{"class":67,"line":274},[65,599,265],{"emptyLinePlaceholder":264},[65,601,602,605,608,611],{"class":67,"line":280},[65,603,604],{"class":75},"await",[65,606,607],{"class":71}," client.",[65,609,610],{"class":207},"connect",[65,612,613],{"class":71},"()\n",[65,615,616],{"class":67,"line":294},[65,617,265],{"emptyLinePlaceholder":264},[65,619,620,623,626,628,631],{"class":67,"line":303},[65,621,622],{"class":71},"console.",[65,624,625],{"class":207},"log",[65,627,493],{"class":71},[65,629,630],{"class":215},"'Connected to NoLag!'",[65,632,499],{"class":71},[54,634,637],{"className":88,"code":635,"filename":636,"language":91,"meta":60,"style":60},"from nolag import NoLag\n\n# Create client and connect\nclient = NoLag('your_access_token')\n\n# Attach this first: server-side errors arrive here, not as raised exceptions\ndef handle_error(err):\n    print(f'NoLag error: {err}')\n\nclient.on('error', handle_error)\n\nawait client.connect()\n\nprint('Connected to NoLag!')\n","Python",[62,638,639,644,648,653,658,662,667,672,677,681,686,690,695,699],{"__ignoreMap":60},[65,640,641],{"class":67,"line":68},[65,642,643],{},"from nolag import NoLag\n",[65,645,646],{"class":67,"line":198},[65,647,265],{"emptyLinePlaceholder":264},[65,649,650],{"class":67,"line":204},[65,651,652],{},"# Create client and connect\n",[65,654,655],{"class":67,"line":225},[65,656,657],{},"client = NoLag('your_access_token')\n",[65,659,660],{"class":67,"line":236},[65,661,265],{"emptyLinePlaceholder":264},[65,663,664],{"class":67,"line":246},[65,665,666],{},"# Attach this first: server-side errors arrive here, not as raised exceptions\n",[65,668,669],{"class":67,"line":255},[65,670,671],{},"def handle_error(err):\n",[65,673,674],{"class":67,"line":261},[65,675,676],{},"    print(f'NoLag error: {err}')\n",[65,678,679],{"class":67,"line":268},[65,680,265],{"emptyLinePlaceholder":264},[65,682,683],{"class":67,"line":274},[65,684,685],{},"client.on('error', handle_error)\n",[65,687,688],{"class":67,"line":280},[65,689,265],{"emptyLinePlaceholder":264},[65,691,692],{"class":67,"line":294},[65,693,694],{},"await client.connect()\n",[65,696,697],{"class":67,"line":303},[65,698,265],{"emptyLinePlaceholder":264},[65,700,701],{"class":67,"line":312},[65,702,703],{},"print('Connected to NoLag!')\n",[54,705,708],{"className":100,"code":706,"filename":707,"language":103,"meta":60,"style":60},"package main\n\nimport (\n    \"fmt\"\n    \"log\"\n\n    nolag \"github.com/NoLagApp/go-sdk\"\n)\n\nfunc main() {\n    // Create client and connect\n    client := nolag.New(\"your_access_token\")\n\n    // Attach this first: server-side errors arrive here, not as returned errors\n    client.OnError(func(err *nolag.ServerError) {\n        log.Printf(\"NoLag %s (%d) on %s: %s\", err.Name, err.Code, err.Topic, err.Hint)\n    })\n\n    if err := client.Connect(); err != nil {\n        log.Fatal(err)\n    }\n\n    fmt.Println(\"Connected to NoLag!\")\n}\n","Go",[62,709,710,715,719,724,729,734,738,743,747,751,756,761,766,770,775,780,785,790,794,799,804,810,815,821],{"__ignoreMap":60},[65,711,712],{"class":67,"line":68},[65,713,714],{},"package main\n",[65,716,717],{"class":67,"line":198},[65,718,265],{"emptyLinePlaceholder":264},[65,720,721],{"class":67,"line":204},[65,722,723],{},"import (\n",[65,725,726],{"class":67,"line":225},[65,727,728],{},"    \"fmt\"\n",[65,730,731],{"class":67,"line":236},[65,732,733],{},"    \"log\"\n",[65,735,736],{"class":67,"line":246},[65,737,265],{"emptyLinePlaceholder":264},[65,739,740],{"class":67,"line":255},[65,741,742],{},"    nolag \"github.com/NoLagApp/go-sdk\"\n",[65,744,745],{"class":67,"line":261},[65,746,499],{},[65,748,749],{"class":67,"line":268},[65,750,265],{"emptyLinePlaceholder":264},[65,752,753],{"class":67,"line":274},[65,754,755],{},"func main() {\n",[65,757,758],{"class":67,"line":280},[65,759,760],{},"    // Create client and connect\n",[65,762,763],{"class":67,"line":294},[65,764,765],{},"    client := nolag.New(\"your_access_token\")\n",[65,767,768],{"class":67,"line":303},[65,769,265],{"emptyLinePlaceholder":264},[65,771,772],{"class":67,"line":312},[65,773,774],{},"    // Attach this first: server-side errors arrive here, not as returned errors\n",[65,776,777],{"class":67,"line":320},[65,778,779],{},"    client.OnError(func(err *nolag.ServerError) {\n",[65,781,782],{"class":67,"line":325},[65,783,784],{},"        log.Printf(\"NoLag %s (%d) on %s: %s\", err.Name, err.Code, err.Topic, err.Hint)\n",[65,786,787],{"class":67,"line":331},[65,788,789],{},"    })\n",[65,791,792],{"class":67,"line":345},[65,793,265],{"emptyLinePlaceholder":264},[65,795,796],{"class":67,"line":354},[65,797,798],{},"    if err := client.Connect(); err != nil {\n",[65,800,801],{"class":67,"line":363},[65,802,803],{},"        log.Fatal(err)\n",[65,805,807],{"class":67,"line":806},21,[65,808,809],{},"    }\n",[65,811,813],{"class":67,"line":812},22,[65,814,265],{"emptyLinePlaceholder":264},[65,816,818],{"class":67,"line":817},23,[65,819,820],{},"    fmt.Println(\"Connected to NoLag!\")\n",[65,822,824],{"class":67,"line":823},24,[65,825,826],{},"}\n",[18,828,830],{"id":829},"step-4-subscribe-to-a-topic","Step 4: Subscribe to a Topic",[14,832,833],{},"Topics are channels for messages. Subscribe to receive messages published to a topic.",[14,835,836],{},"Pass the app slug exactly as the create response returned it, suffix included, and\nthe slug of a room that already exists:",[51,838,839,949,1002],{},[54,840,842],{"className":56,"code":841,"filename":451,"language":59,"meta":60,"style":60},"// Set up app and room, then subscribe.\n// 'my-app-a3f9' is the slug returned when the app was created.\nconst room = client.setApp('my-app-a3f9').setRoom('general')\nroom.subscribe('messages')\n\n// Listen for messages\nroom.on('messages', (data) => {\n  console.log('Received:', data)\n})\n",[62,843,844,849,854,886,901,905,910,931,945],{"__ignoreMap":60},[65,845,846],{"class":67,"line":68},[65,847,848],{"class":194},"// Set up app and room, then subscribe.\n",[65,850,851],{"class":67,"line":198},[65,852,853],{"class":194},"// 'my-app-a3f9' is the slug returned when the app was created.\n",[65,855,856,858,861,863,865,868,870,873,876,879,881,884],{"class":67,"line":204},[65,857,481],{"class":75},[65,859,860],{"class":211}," room",[65,862,487],{"class":75},[65,864,607],{"class":71},[65,866,867],{"class":207},"setApp",[65,869,493],{"class":71},[65,871,872],{"class":215},"'my-app-a3f9'",[65,874,875],{"class":71},").",[65,877,878],{"class":207},"setRoom",[65,880,493],{"class":71},[65,882,883],{"class":215},"'general'",[65,885,499],{"class":71},[65,887,888,891,894,896,899],{"class":67,"line":225},[65,889,890],{"class":71},"room.",[65,892,893],{"class":207},"subscribe",[65,895,493],{"class":71},[65,897,898],{"class":215},"'messages'",[65,900,499],{"class":71},[65,902,903],{"class":67,"line":236},[65,904,265],{"emptyLinePlaceholder":264},[65,906,907],{"class":67,"line":246},[65,908,909],{"class":194},"// Listen for messages\n",[65,911,912,914,916,918,920,922,925,927,929],{"class":67,"line":255},[65,913,890],{"class":71},[65,915,516],{"class":207},[65,917,493],{"class":71},[65,919,898],{"class":215},[65,921,524],{"class":71},[65,923,924],{"class":527},"data",[65,926,531],{"class":71},[65,928,534],{"class":75},[65,930,537],{"class":71},[65,932,933,935,937,939,942],{"class":67,"line":261},[65,934,542],{"class":71},[65,936,625],{"class":207},[65,938,493],{"class":71},[65,940,941],{"class":215},"'Received:'",[65,943,944],{"class":71},", data)\n",[65,946,947],{"class":67,"line":268},[65,948,595],{"class":71},[54,950,952],{"className":88,"code":951,"filename":636,"language":91,"meta":60,"style":60},"# Set up app and room, then subscribe.\n# 'my-app-a3f9' is the slug returned when the app was created.\nroom = client.set_app('my-app-a3f9').set_room('general')\nawait room.subscribe('messages')\n\n# Listen for messages\ndef handle_message(data, meta):\n    print('Received:', data)\n\nroom.on('messages', handle_message)\n",[62,953,954,959,964,969,974,978,983,988,993,997],{"__ignoreMap":60},[65,955,956],{"class":67,"line":68},[65,957,958],{},"# Set up app and room, then subscribe.\n",[65,960,961],{"class":67,"line":198},[65,962,963],{},"# 'my-app-a3f9' is the slug returned when the app was created.\n",[65,965,966],{"class":67,"line":204},[65,967,968],{},"room = client.set_app('my-app-a3f9').set_room('general')\n",[65,970,971],{"class":67,"line":225},[65,972,973],{},"await room.subscribe('messages')\n",[65,975,976],{"class":67,"line":236},[65,977,265],{"emptyLinePlaceholder":264},[65,979,980],{"class":67,"line":246},[65,981,982],{},"# Listen for messages\n",[65,984,985],{"class":67,"line":255},[65,986,987],{},"def handle_message(data, meta):\n",[65,989,990],{"class":67,"line":261},[65,991,992],{},"    print('Received:', data)\n",[65,994,995],{"class":67,"line":268},[65,996,265],{"emptyLinePlaceholder":264},[65,998,999],{"class":67,"line":274},[65,1000,1001],{},"room.on('messages', handle_message)\n",[54,1003,1005],{"className":100,"code":1004,"filename":707,"language":103,"meta":60,"style":60},"import \"fmt\"\n\n// Set up app and room, then subscribe with handler.\n// \"my-app-a3f9\" is the slug returned when the app was created.\nroom := client.SetApp(\"my-app-a3f9\").SetRoom(\"general\")\nroom.Subscribe(\"messages\", func(data any, meta nolag.MessageMeta) {\n    fmt.Println(\"Received:\", data)\n})\n",[62,1006,1007,1012,1016,1021,1026,1031,1036,1041],{"__ignoreMap":60},[65,1008,1009],{"class":67,"line":68},[65,1010,1011],{},"import \"fmt\"\n",[65,1013,1014],{"class":67,"line":198},[65,1015,265],{"emptyLinePlaceholder":264},[65,1017,1018],{"class":67,"line":204},[65,1019,1020],{},"// Set up app and room, then subscribe with handler.\n",[65,1022,1023],{"class":67,"line":225},[65,1024,1025],{},"// \"my-app-a3f9\" is the slug returned when the app was created.\n",[65,1027,1028],{"class":67,"line":236},[65,1029,1030],{},"room := client.SetApp(\"my-app-a3f9\").SetRoom(\"general\")\n",[65,1032,1033],{"class":67,"line":246},[65,1034,1035],{},"room.Subscribe(\"messages\", func(data any, meta nolag.MessageMeta) {\n",[65,1037,1038],{"class":67,"line":255},[65,1039,1040],{},"    fmt.Println(\"Received:\", data)\n",[65,1042,1043],{"class":67,"line":261},[65,1044,595],{},[18,1046,1048],{"id":1047},"step-5-publish-a-message","Step 5: Publish a Message",[14,1050,1051],{},"Publish messages to a topic for all subscribers to receive:",[51,1053,1054,1112,1146],{},[54,1055,1057],{"className":56,"code":1056,"filename":451,"language":59,"meta":60,"style":60},"// Publish a message\nroom.emit('messages', {\n  text: 'Hello, World!',\n  sender: 'user-123',\n  timestamp: Date.now()\n})\n",[62,1058,1059,1064,1078,1088,1098,1108],{"__ignoreMap":60},[65,1060,1061],{"class":67,"line":68},[65,1062,1063],{"class":194},"// Publish a message\n",[65,1065,1066,1068,1071,1073,1075],{"class":67,"line":198},[65,1067,890],{"class":71},[65,1069,1070],{"class":207},"emit",[65,1072,493],{"class":71},[65,1074,898],{"class":215},[65,1076,1077],{"class":71},", {\n",[65,1079,1080,1083,1086],{"class":67,"line":204},[65,1081,1082],{"class":71},"  text: ",[65,1084,1085],{"class":215},"'Hello, World!'",[65,1087,418],{"class":71},[65,1089,1090,1093,1096],{"class":67,"line":225},[65,1091,1092],{"class":71},"  sender: ",[65,1094,1095],{"class":215},"'user-123'",[65,1097,418],{"class":71},[65,1099,1100,1103,1106],{"class":67,"line":236},[65,1101,1102],{"class":71},"  timestamp: Date.",[65,1104,1105],{"class":207},"now",[65,1107,613],{"class":71},[65,1109,1110],{"class":67,"line":246},[65,1111,595],{"class":71},[54,1113,1115],{"className":88,"code":1114,"filename":636,"language":91,"meta":60,"style":60},"# Publish a message\nawait room.emit('messages', {\n    'text': 'Hello, World!',\n    'sender': 'user-123',\n    'timestamp': time.time()\n})\n",[62,1116,1117,1122,1127,1132,1137,1142],{"__ignoreMap":60},[65,1118,1119],{"class":67,"line":68},[65,1120,1121],{},"# Publish a message\n",[65,1123,1124],{"class":67,"line":198},[65,1125,1126],{},"await room.emit('messages', {\n",[65,1128,1129],{"class":67,"line":204},[65,1130,1131],{},"    'text': 'Hello, World!',\n",[65,1133,1134],{"class":67,"line":225},[65,1135,1136],{},"    'sender': 'user-123',\n",[65,1138,1139],{"class":67,"line":236},[65,1140,1141],{},"    'timestamp': time.time()\n",[65,1143,1144],{"class":67,"line":246},[65,1145,595],{},[54,1147,1149],{"className":100,"code":1148,"filename":707,"language":103,"meta":60,"style":60},"// Publish a message\nroom.Emit(\"messages\", map[string]any{\n    \"text\":      \"Hello, World!\",\n    \"sender\":    \"user-123\",\n    \"timestamp\": time.Now().Unix(),\n})\n",[62,1150,1151,1155,1160,1165,1170,1175],{"__ignoreMap":60},[65,1152,1153],{"class":67,"line":68},[65,1154,1063],{},[65,1156,1157],{"class":67,"line":198},[65,1158,1159],{},"room.Emit(\"messages\", map[string]any{\n",[65,1161,1162],{"class":67,"line":204},[65,1163,1164],{},"    \"text\":      \"Hello, World!\",\n",[65,1166,1167],{"class":67,"line":225},[65,1168,1169],{},"    \"sender\":    \"user-123\",\n",[65,1171,1172],{"class":67,"line":236},[65,1173,1174],{},"    \"timestamp\": time.Now().Unix(),\n",[65,1176,1177],{"class":67,"line":246},[65,1178,595],{},[18,1180,1182],{"id":1181},"complete-example","Complete Example",[14,1184,1185],{},"Here's a complete example in your preferred language. It assumes the app, room, and\nactor from Step 2 already exist.",[51,1187,1188,1440,1555],{},[54,1189,1191],{"className":56,"code":1190,"filename":451,"language":59,"meta":60,"style":60},"import { NoLag } from '@nolag/js-sdk'\n\nconst client = NoLag('your_access_token')\n\n// Surface broker errors: subscribe and emit never throw\nclient.on('error', (err) => {\n  console.error(`NoLag ${err.error} (${err.code}) on ${err.topic}: ${err.hint}`)\n})\n\nawait client.connect()\n\n// Use the app slug returned by the create call, and a room that exists\nconst room = client.setApp('my-app-a3f9').setRoom('general')\n\n// Subscribe to a topic\nroom.subscribe('messages')\n\n// Listen for messages\nroom.on('messages', (data) => {\n  console.log('Received:', data)\n})\n\n// Publish a message\nroom.emit('messages', { text: 'Hello, World!' })\n",[62,1192,1193,1203,1207,1223,1227,1232,1252,1296,1300,1304,1314,1318,1323,1349,1353,1358,1370,1374,1378,1398,1410,1414,1418,1422],{"__ignoreMap":60},[65,1194,1195,1197,1199,1201],{"class":67,"line":68},[65,1196,458],{"class":75},[65,1198,461],{"class":71},[65,1200,464],{"class":75},[65,1202,467],{"class":215},[65,1204,1205],{"class":67,"line":198},[65,1206,265],{"emptyLinePlaceholder":264},[65,1208,1209,1211,1213,1215,1217,1219,1221],{"class":67,"line":204},[65,1210,481],{"class":75},[65,1212,484],{"class":211},[65,1214,487],{"class":75},[65,1216,490],{"class":207},[65,1218,493],{"class":71},[65,1220,496],{"class":215},[65,1222,499],{"class":71},[65,1224,1225],{"class":67,"line":225},[65,1226,265],{"emptyLinePlaceholder":264},[65,1228,1229],{"class":67,"line":236},[65,1230,1231],{"class":194},"// Surface broker errors: subscribe and emit never throw\n",[65,1233,1234,1236,1238,1240,1242,1244,1246,1248,1250],{"class":67,"line":246},[65,1235,513],{"class":71},[65,1237,516],{"class":207},[65,1239,493],{"class":71},[65,1241,521],{"class":215},[65,1243,524],{"class":71},[65,1245,528],{"class":527},[65,1247,531],{"class":71},[65,1249,534],{"class":75},[65,1251,537],{"class":71},[65,1253,1254,1256,1258,1260,1262,1264,1266,1268,1270,1272,1274,1276,1278,1280,1282,1284,1286,1288,1290,1292,1294],{"class":67,"line":255},[65,1255,542],{"class":71},[65,1257,444],{"class":207},[65,1259,493],{"class":71},[65,1261,549],{"class":215},[65,1263,528],{"class":71},[65,1265,554],{"class":215},[65,1267,444],{"class":71},[65,1269,559],{"class":215},[65,1271,528],{"class":71},[65,1273,554],{"class":215},[65,1275,62],{"class":71},[65,1277,568],{"class":215},[65,1279,528],{"class":71},[65,1281,554],{"class":215},[65,1283,575],{"class":71},[65,1285,578],{"class":215},[65,1287,528],{"class":71},[65,1289,554],{"class":215},[65,1291,585],{"class":71},[65,1293,588],{"class":215},[65,1295,499],{"class":71},[65,1297,1298],{"class":67,"line":261},[65,1299,595],{"class":71},[65,1301,1302],{"class":67,"line":268},[65,1303,265],{"emptyLinePlaceholder":264},[65,1305,1306,1308,1310,1312],{"class":67,"line":274},[65,1307,604],{"class":75},[65,1309,607],{"class":71},[65,1311,610],{"class":207},[65,1313,613],{"class":71},[65,1315,1316],{"class":67,"line":280},[65,1317,265],{"emptyLinePlaceholder":264},[65,1319,1320],{"class":67,"line":294},[65,1321,1322],{"class":194},"// Use the app slug returned by the create call, and a room that exists\n",[65,1324,1325,1327,1329,1331,1333,1335,1337,1339,1341,1343,1345,1347],{"class":67,"line":303},[65,1326,481],{"class":75},[65,1328,860],{"class":211},[65,1330,487],{"class":75},[65,1332,607],{"class":71},[65,1334,867],{"class":207},[65,1336,493],{"class":71},[65,1338,872],{"class":215},[65,1340,875],{"class":71},[65,1342,878],{"class":207},[65,1344,493],{"class":71},[65,1346,883],{"class":215},[65,1348,499],{"class":71},[65,1350,1351],{"class":67,"line":312},[65,1352,265],{"emptyLinePlaceholder":264},[65,1354,1355],{"class":67,"line":320},[65,1356,1357],{"class":194},"// Subscribe to a topic\n",[65,1359,1360,1362,1364,1366,1368],{"class":67,"line":325},[65,1361,890],{"class":71},[65,1363,893],{"class":207},[65,1365,493],{"class":71},[65,1367,898],{"class":215},[65,1369,499],{"class":71},[65,1371,1372],{"class":67,"line":331},[65,1373,265],{"emptyLinePlaceholder":264},[65,1375,1376],{"class":67,"line":345},[65,1377,909],{"class":194},[65,1379,1380,1382,1384,1386,1388,1390,1392,1394,1396],{"class":67,"line":354},[65,1381,890],{"class":71},[65,1383,516],{"class":207},[65,1385,493],{"class":71},[65,1387,898],{"class":215},[65,1389,524],{"class":71},[65,1391,924],{"class":527},[65,1393,531],{"class":71},[65,1395,534],{"class":75},[65,1397,537],{"class":71},[65,1399,1400,1402,1404,1406,1408],{"class":67,"line":363},[65,1401,542],{"class":71},[65,1403,625],{"class":207},[65,1405,493],{"class":71},[65,1407,941],{"class":215},[65,1409,944],{"class":71},[65,1411,1412],{"class":67,"line":806},[65,1413,595],{"class":71},[65,1415,1416],{"class":67,"line":812},[65,1417,265],{"emptyLinePlaceholder":264},[65,1419,1420],{"class":67,"line":817},[65,1421,1063],{"class":194},[65,1423,1424,1426,1428,1430,1432,1435,1437],{"class":67,"line":823},[65,1425,890],{"class":71},[65,1427,1070],{"class":207},[65,1429,493],{"class":71},[65,1431,898],{"class":215},[65,1433,1434],{"class":71},", { text: ",[65,1436,1085],{"class":215},[65,1438,1439],{"class":71}," })\n",[54,1441,1443],{"className":88,"code":1442,"filename":636,"language":91,"meta":60,"style":60},"from nolag import NoLag\n\nclient = NoLag('your_access_token')\n\n# Surface broker errors: subscribe and emit never raise\ndef handle_error(err):\n    print(f'NoLag error: {err}')\n\nclient.on('error', handle_error)\n\nawait client.connect()\n\n# Use the app slug returned by the create call, and a room that exists\nroom = client.set_app('my-app-a3f9').set_room('general')\n\n# Subscribe to a topic\nawait room.subscribe('messages')\n\n# Listen for messages\ndef handle_message(data, meta):\n    print('Received:', data)\n\nroom.on('messages', handle_message)\n\n# Publish a message\nawait room.emit('messages', {'text': 'Hello, World!'})\n",[62,1444,1445,1449,1453,1457,1461,1466,1470,1474,1478,1482,1486,1490,1494,1499,1503,1507,1512,1516,1520,1524,1528,1532,1536,1540,1544,1549],{"__ignoreMap":60},[65,1446,1447],{"class":67,"line":68},[65,1448,643],{},[65,1450,1451],{"class":67,"line":198},[65,1452,265],{"emptyLinePlaceholder":264},[65,1454,1455],{"class":67,"line":204},[65,1456,657],{},[65,1458,1459],{"class":67,"line":225},[65,1460,265],{"emptyLinePlaceholder":264},[65,1462,1463],{"class":67,"line":236},[65,1464,1465],{},"# Surface broker errors: subscribe and emit never raise\n",[65,1467,1468],{"class":67,"line":246},[65,1469,671],{},[65,1471,1472],{"class":67,"line":255},[65,1473,676],{},[65,1475,1476],{"class":67,"line":261},[65,1477,265],{"emptyLinePlaceholder":264},[65,1479,1480],{"class":67,"line":268},[65,1481,685],{},[65,1483,1484],{"class":67,"line":274},[65,1485,265],{"emptyLinePlaceholder":264},[65,1487,1488],{"class":67,"line":280},[65,1489,694],{},[65,1491,1492],{"class":67,"line":294},[65,1493,265],{"emptyLinePlaceholder":264},[65,1495,1496],{"class":67,"line":303},[65,1497,1498],{},"# Use the app slug returned by the create call, and a room that exists\n",[65,1500,1501],{"class":67,"line":312},[65,1502,968],{},[65,1504,1505],{"class":67,"line":320},[65,1506,265],{"emptyLinePlaceholder":264},[65,1508,1509],{"class":67,"line":325},[65,1510,1511],{},"# Subscribe to a topic\n",[65,1513,1514],{"class":67,"line":331},[65,1515,973],{},[65,1517,1518],{"class":67,"line":345},[65,1519,265],{"emptyLinePlaceholder":264},[65,1521,1522],{"class":67,"line":354},[65,1523,982],{},[65,1525,1526],{"class":67,"line":363},[65,1527,987],{},[65,1529,1530],{"class":67,"line":806},[65,1531,992],{},[65,1533,1534],{"class":67,"line":812},[65,1535,265],{"emptyLinePlaceholder":264},[65,1537,1538],{"class":67,"line":817},[65,1539,1001],{},[65,1541,1542],{"class":67,"line":823},[65,1543,265],{"emptyLinePlaceholder":264},[65,1545,1547],{"class":67,"line":1546},25,[65,1548,1121],{},[65,1550,1552],{"class":67,"line":1551},26,[65,1553,1554],{},"await room.emit('messages', {'text': 'Hello, World!'})\n",[54,1556,1558],{"className":100,"code":1557,"filename":707,"language":103,"meta":60,"style":60},"package main\n\nimport (\n    \"fmt\"\n    \"log\"\n\n    nolag \"github.com/NoLagApp/go-sdk\"\n)\n\nfunc main() {\n    client := nolag.New(\"your_access_token\")\n\n    // Surface broker errors: Subscribe and Emit do not return them\n    client.OnError(func(err *nolag.ServerError) {\n        log.Printf(\"NoLag %s (%d) on %s: %s\", err.Name, err.Code, err.Topic, err.Hint)\n    })\n\n    if err := client.Connect(); err != nil {\n        log.Fatal(err)\n    }\n\n    // Use the app slug returned by the create call, and a room that exists\n    room := client.SetApp(\"my-app-a3f9\").SetRoom(\"general\")\n\n    // Subscribe to a topic with message handler\n    room.Subscribe(\"messages\", func(data any, meta nolag.MessageMeta) {\n        fmt.Println(\"Received:\", data)\n    })\n\n    // Publish a message\n    room.Emit(\"messages\", map[string]string{\"text\": \"Hello, World!\"})\n}\n",[62,1559,1560,1564,1568,1572,1576,1580,1584,1588,1592,1596,1600,1604,1608,1613,1617,1621,1625,1629,1633,1637,1641,1645,1650,1655,1659,1664,1669,1675,1680,1685,1691,1697],{"__ignoreMap":60},[65,1561,1562],{"class":67,"line":68},[65,1563,714],{},[65,1565,1566],{"class":67,"line":198},[65,1567,265],{"emptyLinePlaceholder":264},[65,1569,1570],{"class":67,"line":204},[65,1571,723],{},[65,1573,1574],{"class":67,"line":225},[65,1575,728],{},[65,1577,1578],{"class":67,"line":236},[65,1579,733],{},[65,1581,1582],{"class":67,"line":246},[65,1583,265],{"emptyLinePlaceholder":264},[65,1585,1586],{"class":67,"line":255},[65,1587,742],{},[65,1589,1590],{"class":67,"line":261},[65,1591,499],{},[65,1593,1594],{"class":67,"line":268},[65,1595,265],{"emptyLinePlaceholder":264},[65,1597,1598],{"class":67,"line":274},[65,1599,755],{},[65,1601,1602],{"class":67,"line":280},[65,1603,765],{},[65,1605,1606],{"class":67,"line":294},[65,1607,265],{"emptyLinePlaceholder":264},[65,1609,1610],{"class":67,"line":303},[65,1611,1612],{},"    // Surface broker errors: Subscribe and Emit do not return them\n",[65,1614,1615],{"class":67,"line":312},[65,1616,779],{},[65,1618,1619],{"class":67,"line":320},[65,1620,784],{},[65,1622,1623],{"class":67,"line":325},[65,1624,789],{},[65,1626,1627],{"class":67,"line":331},[65,1628,265],{"emptyLinePlaceholder":264},[65,1630,1631],{"class":67,"line":345},[65,1632,798],{},[65,1634,1635],{"class":67,"line":354},[65,1636,803],{},[65,1638,1639],{"class":67,"line":363},[65,1640,809],{},[65,1642,1643],{"class":67,"line":806},[65,1644,265],{"emptyLinePlaceholder":264},[65,1646,1647],{"class":67,"line":812},[65,1648,1649],{},"    // Use the app slug returned by the create call, and a room that exists\n",[65,1651,1652],{"class":67,"line":817},[65,1653,1654],{},"    room := client.SetApp(\"my-app-a3f9\").SetRoom(\"general\")\n",[65,1656,1657],{"class":67,"line":823},[65,1658,265],{"emptyLinePlaceholder":264},[65,1660,1661],{"class":67,"line":1546},[65,1662,1663],{},"    // Subscribe to a topic with message handler\n",[65,1665,1666],{"class":67,"line":1551},[65,1667,1668],{},"    room.Subscribe(\"messages\", func(data any, meta nolag.MessageMeta) {\n",[65,1670,1672],{"class":67,"line":1671},27,[65,1673,1674],{},"        fmt.Println(\"Received:\", data)\n",[65,1676,1678],{"class":67,"line":1677},28,[65,1679,789],{},[65,1681,1683],{"class":67,"line":1682},29,[65,1684,265],{"emptyLinePlaceholder":264},[65,1686,1688],{"class":67,"line":1687},30,[65,1689,1690],{},"    // Publish a message\n",[65,1692,1694],{"class":67,"line":1693},31,[65,1695,1696],{},"    room.Emit(\"messages\", map[string]string{\"text\": \"Hello, World!\"})\n",[65,1698,1700],{"class":67,"line":1699},32,[65,1701,826],{},[18,1703,1705],{"id":1704},"troubleshooting","Troubleshooting",[14,1707,1708,1711,1712,1714,1715,1717,1718,1721,1722,554],{},[123,1709,1710],{},"Nothing arrives, and nothing errors."," Almost always the room does not exist, or\nthe app slug is missing its random suffix. Attach the ",[62,1713,444],{}," handler from Step 3\nand look for ",[62,1716,413],{},", then check the slug against\n",[62,1719,1720],{},"GET /apps"," and the room against ",[62,1723,1724],{},"GET /apps/{appId}/rooms",[14,1726,1727,1732,1733,1736],{},[123,1728,1729,1731],{},[62,1730,413],{}," on a topic you did create."," Topics resolve as\n",[62,1734,1735],{},"app-slug/room-slug/topic-name",". Confirm the topic is listed on the room, not only\non the app.",[14,1738,429,1739,1743],{},[30,1740,1742],{"href":1741},"/docs/api-reference/errors","Error Reference"," for the full list of codes.",[18,1745,1747],{"id":1746},"next-steps","Next Steps",[23,1749,1750,1756,1762,1768],{},[26,1751,1752],{},[30,1753,1755],{"href":1754},"/docs/concepts/topics","Learn about Topics & Pub/Sub",[26,1757,1758],{},[30,1759,1761],{"href":1760},"/docs/concepts/presence","Understand Presence Tracking",[26,1763,1764],{},[30,1765,1767],{"href":1766},"/docs/concepts/qos","Configure Quality of Service",[26,1769,1770],{},[30,1771,1773],{"href":1772},"/docs/sdks/javascript","Full JavaScript SDK Reference",[1775,1776,1777],"style",{},"html pre.shiki code .sVt8B, html code.shiki .sVt8B{--shiki-default:#24292E;--shiki-dark:#E1E4E8}html pre.shiki code .szBVR, html code.shiki .szBVR{--shiki-default:#D73A49;--shiki-dark:#F97583}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .sJ8bj, html code.shiki .sJ8bj{--shiki-default:#6A737D;--shiki-dark:#6A737D}html pre.shiki code .sScJk, html code.shiki .sScJk{--shiki-default:#6F42C1;--shiki-dark:#B392F0}html pre.shiki code .sj4cs, html code.shiki .sj4cs{--shiki-default:#005CC5;--shiki-dark:#79B8FF}html pre.shiki code .sZZnC, html code.shiki .sZZnC{--shiki-default:#032F62;--shiki-dark:#9ECBFF}html pre.shiki code .s4XuR, html code.shiki .s4XuR{--shiki-default:#E36209;--shiki-dark:#FFAB70}",{"title":60,"searchDepth":198,"depth":198,"links":1779},[1780,1781,1782,1783,1784,1785,1786,1787,1788],{"id":20,"depth":198,"text":21},{"id":45,"depth":198,"text":46},{"id":112,"depth":198,"text":113},{"id":437,"depth":198,"text":438},{"id":829,"depth":198,"text":830},{"id":1047,"depth":198,"text":1048},{"id":1181,"depth":198,"text":1182},{"id":1704,"depth":198,"text":1705},{"id":1746,"depth":198,"text":1747},"Get started with NoLag in 5 minutes. Learn how to connect, subscribe to topics, and publish messages.","md",{},"/docs/getting-started",{"title":5,"description":1789},"docs/getting-started","GoGViIcuieG26pyf83aeORaH1AsooRzRzEV-21Tkags",1788160343337]