Using <script type='text/discourse-plugin>
or <script type='text/x-handlebars'>
in themes is now deprecated. Any use of these tags in themes should be updated according to the instructions below.
Regular <script>
and <script type='text/javascript'>
are unaffected by this change.
Timeline
These are rough estimates, subject to change
-
May 2025 - console deprecation messages enabled
-
July 2025 - admin warning banners enabled
-
September 2025 - removal of feature
Converting <script type='text/x-handlebars'>
Templates introduced using this method should be moved to dedicated .hbs
files, or refactored into gjs files.
To keep as HBS, connector templates can be placed in:
{theme}/javascripts/discourse/connectors/{outlet-name}/{connector-name}.hbs
and component templates can be placed in:
{theme}/javascripts/discourse/components/{component-name}.hbs
To build connectors and components in the modern .gjs
format, check out this chapter of the theme developer tutorial:
Converting <script type='text/discourse-plugin'>
Code inside these tags can be migrated to a dedicated JavaScript file.
If you develop your theme via the admin panel interface, copy the code out of the <script>
, and move it into the JS tab (where it says // your code here
).
If you develop your theme locally, create a new file at
{theme}/javascripts/discourse/api-initializers/init-theme.js
then add this wrapper, and place your code in the indicated spot:
import { apiInitializer } from "discourse/lib/api";
export default apiInitializer((api) => {
// Your code here
});
In script tags, the only way to import other JS modules was using the require()
syntax. While that will still work in a .js
file, it will soon be deprecated, so now would be a good time to convert it to modern ES6 imports. For example:
- const I18n = require("discourse-i18n").default;
+ import I18n from "discourse-i18n";
- const { h } = require("virtual-dom");
+ import { h } from "virtual-dom";
For more information on JS initializers: