{"result":{"depiction_url":null,"edges":{"hasreference":{"objects":[{"created":"2026-10-07T11:13:48Z","object_id":{"id":1981,"is_a":["text","documentation","reference","notification"],"name":"doc_notification_rsc_update_done","title":"observe_rsc_update_done\/2","uri":"https:\/\/zotonic.com\/id\/1981"},"seq":1},{"created":"2026-10-07T11:13:48Z","object_id":{"id":2052,"is_a":["text","documentation","reference","notification"],"name":"doc_notification_rsc_update","title":"observe_rsc_update\/3","uri":"https:\/\/zotonic.com\/id\/2052"},"seq":2},{"created":"2026-10-07T11:13:48Z","object_id":{"id":2976,"is_a":["text","documentation","developerguide"],"name":"developer_observer_tools","title":{"_type":"trans","tr":{"en":"Find registered observers"}},"uri":"https:\/\/zotonic.com\/id\/2976"},"seq":3}],"predicate":{"id":2774,"is_a":["meta","predicate"],"name":"hasreference","title":{"_type":"trans","tr":{"en":"Documentation reference"}},"uri":"https:\/\/zotonic.com\/id\/hasreference"}},"references":{"objects":[{"created":"2020-05-30T05:48:18Z","object_id":{"id":1577,"is_a":["text","documentation","cookbook"],"name":"doc_cookbook_overriding","title":{"_type":"trans","tr":{"en":"Override a module template"}},"uri":"https:\/\/zotonic.com\/id\/1577"},"seq":1000000},{"created":"2020-05-30T05:48:18Z","object_id":{"id":1122,"is_a":["meta","category"],"name":"notification","title":"Notifications","uri":"https:\/\/test.zotonic.com\/id\/1122"},"seq":1000000},{"created":"2020-05-30T05:48:18Z","object_id":{"id":1353,"is_a":["text","documentation","developerguide"],"name":"doc_developerguide_modules","title":{"_type":"trans","tr":{"en":"Create a reusable module"}},"uri":"https:\/\/zotonic.com\/id\/1353"},"seq":1000000},{"created":"2020-05-30T05:48:18Z","object_id":{"id":1457,"is_a":["text","documentation","reference","module"],"name":"doc_module_mod_development","title":"mod_development","uri":"https:\/\/zotonic.com\/id\/1457"},"seq":1000000},{"created":"2020-05-30T05:48:18Z","object_id":{"id":2010,"is_a":["text","documentation","reference","module"],"name":"doc_module_mod_signup","title":"mod_signup","uri":"https:\/\/zotonic.com\/id\/2010"},"seq":1000000},{"created":"2020-05-30T05:48:18Z","object_id":{"id":1331,"is_a":["text","documentation","reference","module"],"name":"doc_module_mod_admin","title":"mod_admin","uri":"https:\/\/zotonic.com\/id\/1331"},"seq":1000000}],"predicate":{"id":332,"is_a":["meta","predicate"],"name":"references","title":{"_type":"trans","tr":{"en":"References"}},"uri":"https:\/\/zotonic.com\/id\/references"}},"refers":{"objects":[{"created":"2026-10-07T11:13:00Z","object_id":{"id":1981,"is_a":["text","documentation","reference","notification"],"name":"doc_notification_rsc_update_done","title":"observe_rsc_update_done\/2","uri":"https:\/\/zotonic.com\/id\/1981"},"seq":1000000},{"created":"2026-10-07T11:13:00Z","object_id":{"id":2052,"is_a":["text","documentation","reference","notification"],"name":"doc_notification_rsc_update","title":"observe_rsc_update\/3","uri":"https:\/\/zotonic.com\/id\/2052"},"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:48Z","object_id":{"id":2976,"is_a":["text","documentation","developerguide"],"name":"developer_observer_tools","title":{"_type":"trans","tr":{"en":"Find registered observers"}},"uri":"https:\/\/zotonic.com\/id\/2976"},"seq":1},{"created":"2026-10-07T11:13:48Z","object_id":{"id":2963,"is_a":["text","documentation","developerguide"],"name":"developer_background_work","title":{"_type":"trans","tr":{"en":"Run work outside a request"}},"uri":"https:\/\/zotonic.com\/id\/2963"},"seq":2},{"created":"2020-05-30T05:48:18Z","object_id":{"id":1122,"is_a":["meta","category"],"name":"notification","title":"Notifications","uri":"https:\/\/test.zotonic.com\/id\/1122"},"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:48Z","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:48Z","object_id":{"id":2564,"is_a":["categorization","keyword","keyword_audience"],"name":"zotonic_topic_backend_developer","title":"Backend developer","uri":"https:\/\/zotonic.com\/id\/2564"},"seq":2},{"created":"2026-10-07T11:13:48Z","object_id":{"id":2627,"is_a":["categorization","keyword","keyword_architecture"],"name":"zotonic_topic_notification","title":"Notification","uri":"https:\/\/zotonic.com\/id\/2627"},"seq":3}],"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":1274,"is_a":["text","documentation","developerguide"],"links":[{"rel":"self","target":"https:\/\/zotonic.com\/.zotonic\/websub\/topic\/1274"},{"rel":"hub","target":"https:\/\/zotonic.com\/.zotonic\/websub"}],"medium":null,"medium_url":null,"name":"doc_developerguide_notifications","page_url":{"en":"https:\/\/zotonic.com\/docs\/1274\/respond-to-a-notification","x-default":"https:\/\/zotonic.com\/docs\/1274\/respond-to-a-notification"},"preview_url":null,"resource":{"body":{"_type":"trans","tr":{"en":"<p>Add the appropriate exported <code>observe_...<\/code> callback to your active module. Keep it short and return the value required by that notification&#39;s contract. Move slow work out of synchronous request paths where possible.<\/p>\n<p>Use the Development observer list to verify registration. Test with other modules enabled: an observer that works alone may interact with another observer through priority or return values.<\/p>\n<p>For example, add the header, export, and callback below to <code>mod_garden.erl<\/code> (merge declarations with existing ones):<\/p>\n<pre class=\"notranslate\"><code class=\"notranslate language-erlang\">-include_lib(&quot;zotonic_core\/include\/zotonic.hrl&quot;).\n-export([observe_rsc_update_done\/2]).\n\n-spec observe_rsc_update_done(Event, Context) -&gt; ok\n    when Event :: #rsc_update_done{}, Context :: z:context().\nobserve_rsc_update_done(#rsc_update_done{action = Action, id = Id}, _Context) -&gt;\n    ?LOG_INFO(#{text =&gt; &lt;&lt;&quot;Garden observed a resource change&quot;&gt;&gt;,\n                in =&gt; mod_garden, action =&gt; Action, id =&gt; Id}),\n    ok.\n<\/code><\/pre>\n<p>Compile, refresh module discovery, check the observer list, then save a practice page. Expect a log entry with its ID. This notification runs after persistence and ignores the observer&#39;s return value. Do not update the same resource unconditionally from this callback: that can trigger the observer again. <a href=\"\/id\/1981\" class=\"doc-reference doc-reference-notification\"><code>notification#rsc_update_done<\/code><\/a> and <a href=\"\/id\/2052\" class=\"doc-reference doc-reference-notification\"><code>notification#rsc_update<\/code><\/a> have different contracts.<\/p>\n<h2>Find registered observers<\/h2>\n<p>Open <strong>Show an overview of all observers<\/strong> from the Development page. Find the notification and inspect the registered callbacks and their order.<\/p>\n<p>If your callback is absent, check that the module is active, the callback is exported, and the compiled module contains your change. If it is present but has no visible effect, check the notification contract and which caller emits it.<\/p>\n<p>Use a focused trace or log entry to follow one event. Do not add a second observer registration to compensate for an inactive module.<\/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":"2020-05-30T05:47:15Z","creator_id":{"id":336,"is_a":["person","robot"],"name":"gitbot","title":"Git","uri":"https:\/\/zotonic.com\/id\/336"},"doc_editorial_bundle":true,"doc_editorial_edges":{"hasreference":[1981,2052,2976],"relation":[2963,2976],"subject":[2554,2564,2627]},"github_url":"https:\/\/github.com\/zotonic\/zotonic\/tree\/master\/doc\/developer-guide\/notifications.rst","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:37Z","modifier_id":{"id":1,"is_a":["person"],"name":"administrator","title":"Site Administrator","uri":"https:\/\/zotonic.com\/id\/1"},"name":"doc_developerguide_notifications","pivot_geocode":null,"pivot_location_lat":null,"pivot_location_lng":null,"privacy":0,"publication_end":"9999-06-01T00:00:00Z","publication_start":"2022-02-15T10:01:16Z","slug":"respond-to-a-notification","summary":{"_type":"trans","tr":{"en":"Find the notification definition and inspect its callers before implementing an observer. The notifier operation determines whether observers collect results, stop at a first result, or fold a value."}},"title":{"_type":"trans","tr":{"en":"Respond to a notification"}},"title_slug":{"_type":"trans","tr":{"en":"respond-to-a-notification"}},"tz":"UTC","uri":null,"version":42,"visible_for":0},"uri":"https:\/\/zotonic.com\/id\/1274","uri_template":"https:\/\/zotonic.com\/id\/:id","websub":{"hub":"https:\/\/zotonic.com\/.zotonic\/websub","topic":"https:\/\/zotonic.com\/.zotonic\/websub\/topic\/1274"}},"status":"ok"}