// TODO ASYNC hooks
The following is a list of all hooks present in NodeBB. This list is intended to guide developers who are looking to write plugins for NodeBB. For more information, please consult Writing Plugins for NodeBB <create>.
Most of the time, when you want to integrate with NodeBB, you'll want to hook into some part of NodeBB's internal processing. This is done by attaching a listener from your plugin, via our plugin hook system. There are four types of hooks, filters, actions, static, and response hooks.
Filters act on content, and can be useful if you want to alter certain pieces of content as it passes through NodeBB.
For example, a filter may be used to alter posts so that any occurrences of "apple" gets changed to "orange". Likewise, filters may be used to beautify content (i.e. code filters), or remove offensive words (profanity filters).
Most filter hooks called from NodeBB will pass a single argument in the form of an object, and you must send back your return payload in the same schema, as multiple plugins could be listening to the same hook, and expect the same object schema. We don't enforce that you send back the exact same object, but that is encouraged as well.
NodeBB will execute all of the registered listeners sequentially, and wait for all of them to return data back (transformed or not) before continuing onwards with execution.
Actions, true to their name, are executed when NodeBB does a certain action. They are useful if you'd like to do something asynchronously after a certain trigger.
For example, an action hook can be used to notify an admin if a certain user has posted. Other uses include analytics recording, or automatic welcome posts on new user registration.
Action hooks may or may not contain a data payload for processing, but NodeBB will explicitly not care what comes back (and will not use the data that comes back)
NodeBB will execute all registered listeners for an action hook at once, and not wait for a response before continuing onwards. If you need NodeBB to wait, you want a filter/static hook.
Static hooks are executed and wait for you to do something before continuing. They're similar to action hooks, but whereas execution in NodeBB continues immediately after an action is fired, static hooks grant you a bit of time to run your own custom logic, before resuming execution.
NodeBB will pass in a data payload, and execute all registered listeners at once. It will wait for all of the listeners to return (or execute the return callback) before continuing onwards
Response hooks are executed serially and are similar to action hooks up until one of the listeners sends a response to the client. In that event, the plugin hooks that come afterward are skipped completely, including the default response from core.
Response hooks are used in situatons where one or more plugins may elect to send an error to the client, or redirect them somewhere else. Response hooks are structured in a way so that conflicts are avoided.
Admittely, there are few response hooks in NodeBB. The only one in core is
response:middleware.authenticate, which allows a plugin to add their own authentication strategies to protected routes. In this scenario, NodeBB passes in
res, much like a middleware would, and a plugin can elect to respond or not. NodeBB checks whether headers were sent, and continues onwards if a response wasn't already sent to the client.
For example, if a user accesses a protected route, NodeBB fires off
response:middleware.authenticate for non-logged-in users, and if nothing was done, continues with the default action, which is to show the "Not Allowed" page.
List of hooks
Please consult the autogenerated list of hooks. The aforementioned list is automatically generated from the NodeBB codebase and is not guaranteed to be complete at all times.
There are a number of special hooks that are included in the NodeBB codebase that are not explicitly called out in the autogenerated hooks page. They are included below as they are either a) useful, or b) difficult to understand given its context.
Page Build Hooks
In addition to hooks executed on certain actions, a pair of hooks are also fired whenever a page is loaded (either via direct page access, or via a page transition):
filter:<template>.buildis fired on a particular page load, based on the template file being rendered. For example,
/recentdraws its view from
recent.tpl, and thus a plugin can subscribe to
filter:recent.buildand react whenever the recent page is loaded.
- Keep in mind that there is no guarantee that the hook is only fired on that particular page. A plugin may elect to render that same template, which would also cause the hook to be fired.
filter:router.pageis called on every single page load, prior to any processing (template generation, etc.)
filter:middleware.renderis called on every single page load, and is useful for situations where you want to append or change data for every page. It is called after the bulk of processing is done.
Widget Render Hook
A widget defined by a plugin needs to let NodeBB know what's in the widget (e.g. html, and other assorted data). This is handled via a plugin hook fired whenever a widget is rendered. The hook name itself is defined by the widget name, so if a widget with the
widget property set to
mywidget is rendered, the hook
filter:widget.render:mywidget will be fired.
For more information, please consult the page on writing widgets
How to use hooks
NodeBB looks for
plugin.json in every plugin. This file defines an entry point, in the
library property. That entry point will be where your hook listener logic is written.
In that same file, the
hooks array allows you to hook up a listener method from your library, to a hook from NodeBB. Here's an example of how this is done, in the quickstart plugin.
Likewise, in the entry point,
library.js, the logic for the hooks are defined.