In advance of the release of version 2, we are releasing this guide in order to give third-party developers a chance to bring their plugins and themes up-to-date. In the successive sections below, we will outline the breaking change or new best-practice, and the steps to migrate, along with a live example.
We tried to plan out this release in such a way that any breaking changes would be minimized. There is a chance that your theme or plugin will just work out-of-the-box, or with minimal changes.
We've tried to list any gotchas and necessary changes in this article, but please do let us know if you encounter one we haven't seen yet.
scripts
and acpScripts
to modules
(breaking change 🚨)Standard practice in v1.x was to write a page-specific client-side script or admin script as an AMD module, and bundle them with the minified files served to the browser. We now recommend that the files be defined in the modules
property in package.json
so that they can be bundled as necessary, or dynamically loaded otherwise.
Note:These scripts can continue to be written in AMD-style, as it is supported by Webpack.
The persona theme contains two page-specific scripts, one loaded on the user settings page, and another loaded in the ACP settings page.
scripts
and acpScripts
sections, and added to modules
../
-- this is necessary because they are not added to the modules folderAny third-party modules are no longer recommended to be used in the modules
section of plugin.json
. Instead, install them directly from npm if available, and just import them into your client-side code.
There are some savings to be had by no longer appending third-party code into the main bundle. Webpack can choose to either bundle it in, or dynamically load it as-needed.
Additionally, having a dependency maintained in your package.json
allows for better version control and updates, without needing to modify copy-pasted code directly in your repository.
The markdown plugin relies on highlightjs
as a dependency in order to highlight code written in code blocks.
require
-ing them as an AMD module, they are now imported in by WebpackThe 2factor plugin relies on @github/webauthn-json to properly encode and verify key registrations and challenges.
While modules and client-side scripts can continue to be written in AMD-style (with define
and require
calls), you will no longer be able to use the AMD-style require
in widgets or the browser console to get modules. By and large, this will not affect most installations/plugins.
A helper method app.require
is added to require modules dynamically. app.require
can be used in widgets or custom javascript tab in the ACP to require modules.
require(['alerts'], function (alerts) {}); // single module
require(['alerts', 'translator'], function (alerts, translator) {}); // multiple modules
const alerts = await app.require('alerts'); // single module
const [alerts, translator] = await app.require(['alerts', 'translator']); // multiple modules
try_files
directive in nginx config (best practice)Power users may opt to have a reverse proxy serve the built assets directly, instead of going through NodeBB.
Several paths are included in this configuration, but you no longer need to have your reverse proxy handle the /plugins
path prefix.
location /plugins/ {
root /path/to/nodebb/build/public/;
try_files $uri @nodebb;
}
nbbpm.compatibility
in third-party themes and plugins (best practice)In order to ensure that plugins and themes updated for NodeBB v2.x are not accidentally installed in v1.x installations, you should update the nbbpm.compatibility
string in your package.json
to at least ^2.0.0
.
Keep in mind that after updating your plugin, it might still actually be compatible with NodeBB v1.x. Whether your plugin continues to be backwards compatible does not depend on whether you needed to apply the breaking changes in this guide. A breaking change just means that change is needed to be forwards compatible.
{ ... \"nbbpm\": {- \"compatibility\": \"^1.17.4\"+ \"compatibility\": \"^2.0.0\" } ...}
translator
, utils
, and helpers
library restrictions (breaking change 🚨)The following three libraries were used on both the server and client side:
utils
(basic utility functions)translator
(localisation methods)helpers
(NodeBB's set of built-in Benchpress helpers)In NodeBB v1.x, you were able to require()
them from the server-side, even though they were contained in the client-side directories.
As of NodeBB v2.x, you will need to require()
from the server-side src/
directory instead:
src/utils.js
src/translator.js
src/helpers.js
- const utils = require.main.require('./public/src/utils');+ const utils = require.main.require('./src/utils');
- const translator = require.main.require('./public/src/modules/translator');+ const translator = require.main.require('./src/translator');
- const helpers = require.main.require('./public/src/modules/helpers');+ const helpers = require.main.require('./src/helpers');
If you maintain a theme that modifies one of the following files:
admin/partials/privileges/global.tpl
admin/partials/privileges/category.tpl
The format of the privilege labels has changed from an array of objects to a simpler array of language keys (strings).
Apply the changeset to the right.
- {privileges.labels.users.name}+ {@value}
Core maintains templates for the ACP privilege page, the diff for this particular changeset can be found here.
A client-side hook used in the sorted-lists module has been renamed from action:settings.sorted-list.loaded
to action:settings.sorted-list.itemLoaded
.
A new action hook by the same name is still called, but only once at the very end, when all sorted list items have been parsed and inserted into the DOM.
hook.on('action:settings.sorted-list.loadedItemLoaded', ...
In v1.19.x and earlier, the body element had a 70px top padding, which was missing on mobile. This discrepancy meant that styles for mobile needed to account for a missing 70px in their positioning.
The padding is now removed, and the #panel element now contains a top padding corresponding to the dynamically generated height of the header bar(s).
The Persona theme contains the logic for calculating the panel-offset. As part of this change, some of the styles depending on the old 70px offset needed to be adjusted. Some additional styles needed to be removed as they were no longer required as a single common style for both desktop and mobile was applicable.
utils.params()
refactored.params()
has been refactored in order to use browser and node built-ins, instead of executing its own logic.skipToType
and disableToType
options have now been removedfull
— has been added, which will cause the method to return an URLSearchParams
object instead of a plain ObjectThere are no pre-existing usages of the .params()
method &mdashl that we know of — that use either of the deprecated options.
This commit shows how to use the new full
option to return something other than a plain Object.