// TODO ASYNC hooks

Available 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.

Filter 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.

Action hooks

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

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

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 req and 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.

Special Hooks

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>.build is fired on a particular page load, based on the template file being rendered. For example, /recent draws its view from recent.tpl, and thus a plugin can subscribe to filter:recent.build and 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.page is called on every single page load, prior to any processing (template generation, etc.)
  • filter:middleware.render is 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 filter:widget.render:<widget>

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.