Split up theme Javascript into multiple files

Complex theme javascript can be split into multiple files, to keep things nicely organised.

To use this functionality, simply add files to the /javascripts folder in your theme directory. Currently, these files can not be edited from the Discourse UI, so you must use the Theme CLI or source the theme from git.

Javascript files are treated exactly the same as they are in core/plugins, so you should follow the same file/folder structure. Theme files are loaded after core/plugins, so if the filenames match, the theme version will take precedence.


As an example, you can now accomplish Connect your theme to plugin-outlets to inject templates with custom content by adding a single file to your theme:

/javascripts/mytheme/connectors/discovery-list-container-top/add-header-message.hbs

Welcome {{currentUser.username}}. Please visit <a class="nav-link " href="http://google.com" target="_blank">My Site</a>

To add a connector class, add another file

/javascripts/mytheme/connectors/discovery-list-container-top/add-header-message.js.es6

import { isAppleDevice } from "discourse/lib/utilities";

export default {
  shouldRender(args, component) {
    return isAppleDevice();
  }
};

If you want to simply move some existing theme javascript out of a <script type="text/discourse-plugin" block, you should wrap it in an initializer like this:

/javascripts/mytheme/initializers/initialize-stuff.js.es6

import { withPluginApi } from "discourse/lib/plugin-api";
export default {
  name: "my-initializer",
  initialize(){
    withPluginApi("0.8.7", api => {
      // Do something with the API here
    });
  }
}

If you need a totally different .js asset (e.g. for a web worker), check out this topic.

26 Likes

Hello!
Is there a way to replace a template using a similar format to the ones in this post? For example, if I have a handlebars script with data-template-name="application", could is there a path I could put it in to automatically override it?
Or, would I just need to include the handlebars file in common/head_tag.html - something like

<script type="text/x-handlebars" data-template-name="application" src="javascripts/application.hbs"></script>

EDIT: After taking another look at How to override a template.hbs from a plugin, the second option may be

<script type="text/x-handlebars" data-template-name="javascripts/application.hbs"></script>

Never mind! Figured out that putting the templates in /javascripts/discourse/templates will override the default templates. Could be worth adding to this guide :slight_smile:

1 Like