# Modernizing inline script tags for templates & JS API

**URL:** https://meta.discourse.org/t/modernizing-inline-script-tags-for-templates-js-api/366482
**Category:** Development
**Tags:** dev-news
**Created:** [May 19, 2025, 9:55am UTC](https://meta.discourse.org/t/modernizing-inline-script-tags-for-templates-js-api/366482 "2025-05-19T09:55:17Z")
**Posts on this page:** 1
**Showing post:** 1

<div class="post-metadata">

### Author: ![david](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/david/32/157490_2.png) [@david](https://meta.discourse.org/u/david)
#### Post date: [May 19, 2025, 9:55am UTC](https://meta.discourse.org/t/modernizing-inline-script-tags-for-templates-js-api/366482/1 "2025-05-19T09:55:17Z")

</div>

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

- ~~**Late September 2025**~~ **March 2026** - 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:

```plaintext
{theme}/javascripts/discourse/connectors/{outlet-name}/{connector-name}.hbs

```

and component templates can be placed in:

```plaintext
{theme}/javascripts/discourse/components/{component-name}.hbs

```

> ⚠ Since March 2026, `.hbs` files are also deprecated. After making this conversion, move on to the instructions in [Deprecating .hbs file extension in themes and plugins](https://meta.discourse.org/t/deprecating-hbs-file-extension-in-themes-and-plugins/398896)

To build connectors and components in the modern `.gjs` format, check out this chapter of the theme developer tutorial:

> [@Theme Developer Tutorial: 4. Using Outlets to insert and replace content](https://meta.discourse.org/t/357799):
>
> Discourse uses the [Ember JS Framework](https://emberjs.com/) for its user interface. On top of Ember, Discourse provides a number of APIs to allow themes to customize the user interface. The most commonly-used API is Plugin Outlets. These outlets are positioned throughout Discourse core, and allow themes to render Ember Components inside them. Those components are given access to some contextual information called “outlet args”. Some outlets also “wrap” part of the core user interface, which allows themes to add the…

### 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

```plaintext
{theme}/javascripts/discourse/api-initializers/init-theme.js

```

then add this wrapper, and place your code in the indicated spot:

```js
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:

```diff
- const I18n = require("discourse-i18n").default;
+ import I18n from "discourse-i18n";

```

```diff
- const { h } = require("virtual-dom");
+ import { h } from "virtual-dom";

```

For more information on JS initializers:

> [@Theme Developer Tutorial: 6. Using the JS API](https://meta.discourse.org/t/357801):
>
> In the last couple of chapters, we’ve explored how to use the JavaScript API to render content into outlets. renderInOutlet is the most commonly-used API, but there are a ton more! In this chapter we’ll try out a few of them, and show you how to discover more. Common API methods getCurrentUser() api.getCurrentUser() will return information about the current user, or null if nobody is logged in. This can be used for all sorts of things, including per-group logic, or rendering a user’s username i…

---

_[View the full topic](https://meta.discourse.org/t/modernizing-inline-script-tags-for-templates-js-api/366482)._
