{"result":{"depiction_url":null,"edges":{"hasreference":{"objects":[{"created":"2026-10-07T11:13:18Z","object_id":{"id":2736,"is_a":["text","documentation","reference","cotonic_reference","cotonic_model"],"name":"doc_cotonic_model_location","title":"model\/location","uri":"https:\/\/zotonic.com\/id\/2736"},"seq":1},{"created":"2026-10-07T11:13:18Z","object_id":{"id":1324,"is_a":["text","documentation","reference","module"],"name":"doc_module_mod_mqtt","title":"mod_mqtt","uri":"https:\/\/zotonic.com\/id\/1324"},"seq":2}],"predicate":{"id":2774,"is_a":["meta","predicate"],"name":"hasreference","title":{"_type":"trans","tr":{"en":"Documentation reference"}},"uri":"https:\/\/zotonic.com\/id\/hasreference"}},"refers":{"objects":[{"created":"2026-10-07T11:13:08Z","object_id":{"id":2736,"is_a":["text","documentation","reference","cotonic_reference","cotonic_model"],"name":"doc_cotonic_model_location","title":"model\/location","uri":"https:\/\/zotonic.com\/id\/2736"},"seq":1000000}],"predicate":{"id":2409,"is_a":["meta","predicate"],"name":"refers","title":{"_type":"trans","tr":{"en":"Refers"}},"uri":"https:\/\/zotonic.com\/id\/refers"}},"relation":{"objects":[{"created":"2026-10-07T11:13:18Z","object_id":{"id":2966,"is_a":["text","documentation","developerguide"],"name":"developer_http_api","title":{"_type":"trans","tr":{"en":"Expose an operation through an API"}},"uri":"https:\/\/zotonic.com\/id\/2966"},"seq":1},{"created":"2026-10-07T11:13:18Z","object_id":{"id":2967,"is_a":["text","documentation","developerguide"],"name":"developer_browser_debugging","title":{"_type":"trans","tr":{"en":"Diagnose a failed browser interaction"}},"uri":"https:\/\/zotonic.com\/id\/2967"},"seq":2},{"created":"2026-10-07T11:13:18Z","object_id":{"id":2960,"is_a":["text","documentation","developerguide"],"name":"developer_model_api","title":{"_type":"trans","tr":{"en":"Expose data through a model"}},"uri":"https:\/\/zotonic.com\/id\/2960"},"seq":3}],"predicate":{"id":303,"is_a":["meta","predicate"],"name":"relation","title":{"_type":"trans","tr":{"nl":"Relatie","en":"Relation"}},"uri":"http:\/\/purl.org\/dc\/terms\/relation"}},"subject":{"objects":[{"created":"2026-10-07T11:13:18Z","object_id":{"id":2554,"is_a":["categorization","keyword","keyword_information_type"],"name":"zotonic_topic_how_to_guide","title":"How-to guide","uri":"https:\/\/zotonic.com\/id\/2554"},"seq":1},{"created":"2026-10-07T11:13:18Z","object_id":{"id":2563,"is_a":["categorization","keyword","keyword_audience"],"name":"zotonic_topic_frontend_developer","title":"Frontend developer","uri":"https:\/\/zotonic.com\/id\/2563"},"seq":2},{"created":"2026-10-07T11:13:18Z","object_id":{"id":2598,"is_a":["categorization","keyword","keyword_domain"],"name":"zotonic_topic_messaging_and_pubsub","title":"Messaging and publish-subscribe","uri":"https:\/\/zotonic.com\/id\/2598"},"seq":3},{"created":"2026-10-07T11:13:18Z","object_id":{"id":2718,"is_a":["categorization","keyword","keyword_technology"],"name":"zotonic_topic_cotonic","title":{"_type":"trans","tr":{"en":"Cotonic"}},"uri":"https:\/\/zotonic.com\/id\/2718"},"seq":4},{"created":"2026-10-07T11:13:18Z","object_id":{"id":2677,"is_a":["categorization","keyword","keyword_technology"],"name":"zotonic_topic_mqtt","title":"MQTT","uri":"https:\/\/zotonic.com\/id\/2677"},"seq":5}],"predicate":{"id":308,"is_a":["meta","predicate"],"name":"subject","title":{"_type":"trans","tr":{"en":"Keyword"}},"uri":"http:\/\/purl.org\/dc\/elements\/1.1\/subject"}}},"id":2965,"is_a":["text","documentation","developerguide"],"links":[{"rel":"self","target":"https:\/\/zotonic.com\/.zotonic\/websub\/topic\/2965"},{"rel":"hub","target":"https:\/\/zotonic.com\/.zotonic\/websub"}],"medium":null,"medium_url":null,"name":"developer_browser_messaging","page_url":{"en":"https:\/\/zotonic.com\/docs\/2965\/use-cotonic-and-mqtt-for-browser-messaging","x-default":"https:\/\/zotonic.com\/docs\/2965\/use-cotonic-and-mqtt-for-browser-messaging"},"preview_url":null,"resource":{"body":{"_type":"trans","tr":{"en":"<p>Define a small payload and a clear reply contract. Subscribe before requesting data when the response can arrive immediately. Clean up component subscriptions when their lifetime ends, and handle reconnects without duplicating actions.<\/p>\n<p>Server-side topic access must follow the site&#39;s permission rules. A topic name is not a secret or an access check.<\/p>\n<p>With the greeting model from the model task active, try this read in the browser console:<\/p>\n<pre class=\"notranslate\"><code class=\"notranslate language-javascript\">cotonic.ready.then(() =&gt;\n    cotonic.broker.call(&quot;bridge\/origin\/model\/garden\/get\/greeting&quot;, {})\n).then(reply =&gt; console.log(reply.payload));\n<\/code><\/pre>\n<p>Inspect the reply&#39;s status and result; expect the greeting on success. An error or disconnected bridge is not an empty greeting. The <code>bridge\/origin\/<\/code> prefix crosses to the site&#39;s server model, while a browser-local model such as <code>model\/location<\/code> stays in the browser. Use <a href=\"\/id\/2736\" class=\"doc-reference doc-reference-cotonic\"><code>cotonic#location<\/code><\/a> for the latter&#39;s topic contract. Do not insert response text as HTML without escaping it.<\/p>"}},"category_id":{"id":317,"is_a":["meta","category"],"name":"developerguide","title":"Developer guide","uri":"https:\/\/zotonic.com\/id\/developerguide"},"content_group_id":{"id":339,"is_a":["meta","content_group"],"name":"default_content_group","title":{"_type":"trans","tr":{"en":"Default Content Group"}},"uri":"https:\/\/zotonic.com\/id\/default_content_group"},"created":"2026-10-07T11:12:56Z","creator_id":{"id":1,"is_a":["person"],"name":"administrator","title":"Site Administrator","uri":"https:\/\/zotonic.com\/id\/1"},"doc_editorial_bundle":true,"doc_editorial_edges":{"hasreference":[1324,2736],"relation":[2960,2966,2967],"subject":[2554,2563,2598,2677,2718]},"is_authoritative":true,"is_dependent":false,"is_featured":false,"is_protected":false,"is_published":true,"is_unfindable":false,"language":["en"],"modified":"2026-10-07T20:45:39Z","modifier_id":{"id":1,"is_a":["person"],"name":"administrator","title":"Site Administrator","uri":"https:\/\/zotonic.com\/id\/1"},"name":"developer_browser_messaging","pivot_geocode":null,"pivot_location_lat":null,"pivot_location_lng":null,"privacy":0,"publication_end":"9999-06-01T00:00:00Z","publication_start":"2026-10-07T11:12:56Z","slug":"use-cotonic-and-mqtt-for-browser-messaging","summary":{"_type":"trans","tr":{"en":"Use the existing Cotonic browser models and Zotonic MQTT bridge when components need to communicate through topics. First identify whether the topic stays inside the browser or crosses to the server."}},"title":{"_type":"trans","tr":{"en":"Use Cotonic and MQTT for browser messaging"}},"title_slug":{"_type":"trans","tr":{"en":"use-cotonic-and-mqtt-for-browser-messaging"}},"tz":"UTC","uri":null,"version":27,"visible_for":0},"uri":"https:\/\/zotonic.com\/id\/2965","uri_template":"https:\/\/zotonic.com\/id\/:id","websub":{"hub":"https:\/\/zotonic.com\/.zotonic\/websub","topic":"https:\/\/zotonic.com\/.zotonic\/websub\/topic\/2965"}},"status":"ok"}