# 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:** 20
**Page:** 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…

---

<div class="post-metadata">

### Author: ![jimkleiber](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/jimkleiber/32/121814_2.png) [@jimkleiber](https://meta.discourse.org/u/jimkleiber)
#### Post date: [June 28, 2025, 11:44am UTC](https://meta.discourse.org/t/modernizing-inline-script-tags-for-templates-js-api/366482/2 "2025-06-28T11:44:16Z")

</div>

Maybe a very dumb question, but I have a very very simple theme component that I put directly into the admin console under `<head>`:

```js
<script type="text/x-handlebars" data-template-name="/connectors/top-notices/whos-online-below-site-header">
{{whos-online}}
</script>

```

If I’m following this post correctly, does it mean that I now have to create a separate theme component folder, host it on GitHub and add the component just for something as simple as adding to a plugin outlet?

I sure hope not, as it’ll break most of my simple theme components 😬

---

<div class="post-metadata">

### Author: ![NateDhaliwal](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/natedhaliwal/32/313494_2.png) [@NateDhaliwal](https://meta.discourse.org/u/NateDhaliwal)
#### Post date: [June 28, 2025, 11:52am UTC](https://meta.discourse.org/t/modernizing-inline-script-tags-for-templates-js-api/366482/3 "2025-06-28T11:52:32Z")

</div>

There is the JS tab now, so you can probably use `api.renderInOutlet` now.

---

<div class="post-metadata">

### Author: ![jimkleiber](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/jimkleiber/32/121814_2.png) [@jimkleiber](https://meta.discourse.org/u/jimkleiber)
#### Post date: [June 28, 2025, 12:01pm UTC](https://meta.discourse.org/t/modernizing-inline-script-tags-for-templates-js-api/366482/4 "2025-06-28T12:01:21Z")

</div>

> [@NateDhaliwal](#):
>
> here is the JS tab now, so you can probably use `api.renderInOutlet` now.

> [@david](#):
>
> 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`).

Ah, I didn’t see that this was possible to do with connectors/components as well, but in the linked article found this:

> [@Theme Developer Tutorial: 4. Using Outlets to insert and replace content](https://meta.discourse.org/t/theme-developer-tutorial-4-using-outlets-to-insert-and-replace-content/357799/1):
>
> The simplest component is a “template only component”, and can be authored like this:
> 
> ```plaintext
> const MyComponent = <template>Hello World</template>;
> api.renderInOutlet("some-outlet", MyComponent);
> 
> // Or on one line
> api.renderInOutlet("some-outlet", <template>Hello World</template>);
> 
> ```

Maybe easier than I thought, thank you!

---

<div class="post-metadata">

### Author: ![Sujeeva\_Tissaarachchi](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/sujeeva_tissaarachchi/32/511571_2.png) [@Sujeeva\_Tissaarachchi](https://meta.discourse.org/u/Sujeeva_Tissaarachchi)
#### Post date: [July 14, 2025, 3:19am UTC](https://meta.discourse.org/t/modernizing-inline-script-tags-for-templates-js-api/366482/5 "2025-07-14T03:19:59Z")

</div>

Thank you for this post!  
May be a very basic question I believe:  
Since we do not have a sandbox, I need to be sure before I proceed.  
I have to update a theme affected so am I correct if say that all the code related to “Script” from “ **head** ” tab need to be moved into the **JS** tab as illustrated below:

 ![Screenshot 2025-07-14 at 1.15.15 pm](https://global.discourse-cdn.com/meta/original/4X/6/d/2/6d29703e9c4eb02c8f99d723548590ec2f9c71ea.jpeg)

---

<div class="post-metadata">

### Author: ![NateDhaliwal](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/natedhaliwal/32/313494_2.png) [@NateDhaliwal](https://meta.discourse.org/u/NateDhaliwal)
#### Post date: [July 14, 2025, 4:35am UTC](https://meta.discourse.org/t/modernizing-inline-script-tags-for-templates-js-api/366482/6 "2025-07-14T04:35:20Z")

</div>

Almost, but not quite. You’d want to remove the script tags, and change the imports to something like:

```js
import { ajax } from "discourse/lib/ajax";

```

Then, paste all this in the JS tab, **inside** :

> [@david](#):
>
> ```js
> export default apiInitializer((api) => {
> // Your code here
> });
> 
> ```

---

<div class="post-metadata">

### Author: ![BradCray](https://avatars.discourse-cdn.com/v4/letter/b/7feea3/32.png) [@BradCray](https://meta.discourse.org/u/BradCray)
#### Post date: [July 14, 2025, 5:42pm UTC](https://meta.discourse.org/t/modernizing-inline-script-tags-for-templates-js-api/366482/7 "2025-07-14T17:42:31Z")

</div>

Our Discourse site (hosted by Discourse) is currently generating the following error bar (which is what led me to this thread):

 ![Screenshot 2025-07-14 at 10.40.31 AM](https://global.discourse-cdn.com/meta/original/4X/3/1/a/31a74f7fc4b4c97fb192f1ad08d79905cc5afa80.png)

I’m not aware that we’ve done any cutomization of the ‘Light’ theme of our own, and looking at its admin page, am not seeing anything suggesting this is anything more than the system-provided default (but could easily be missing something).

For a hosted site like ours, is this likely to self-resolve over time, or does it require some action on our part?

Thanks,  
-Brad

---

<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: [July 14, 2025, 5:53pm UTC](https://meta.discourse.org/t/modernizing-inline-script-tags-for-templates-js-api/366482/8 "2025-07-14T17:53:33Z")

</div>

You will need to take action to resolve this - it won’t go away on its own.

I took a quick look at your site in chrome dev tools, and it looks like the relevent code is related to adding the ‘chapel’ language to highlightjs.

 ![SCR-20250714-qmbq](https://global.discourse-cdn.com/meta/original/4X/a/2/0/a200b76883e7ccb1cc9b2c8015f3ce53e079d672.png)

If you visit your ‘Light’ theme, and hit ‘edit code’, you should be able to find this under one of the HTML tabs. Then you can follow the instructions in the OP of this topic to move it to the ‘JS’ tab.

---

<div class="post-metadata">

### Author: ![BradCray](https://avatars.discourse-cdn.com/v4/letter/b/7feea3/32.png) [@BradCray](https://meta.discourse.org/u/BradCray)
#### Post date: [July 14, 2025, 9:27pm UTC](https://meta.discourse.org/t/modernizing-inline-script-tags-for-templates-js-api/366482/9 "2025-07-14T21:27:45Z")

</div>

Thanks @david! I’d forgotten that we’d done some customizations to get Chapel highlighting and am not sure I would’ve gotten there on my own from the error banner, so appreciate the assistance and pointers.

-Brad

---

<div class="post-metadata">

### Author: ![marco084](https://avatars.discourse-cdn.com/v4/letter/m/4da419/32.png) [@marco084](https://meta.discourse.org/u/marco084)
#### Post date: [July 15, 2025, 12:44pm UTC](https://meta.discourse.org/t/modernizing-inline-script-tags-for-templates-js-api/366482/10 "2025-07-15T12:44:02Z")

</div>

I have a simple .html file:

```plaintext
<script type='text/x-handlebars' data-template-name='/connectors/below-site-header/oprs-top-container'>
    <div id='WW_T_D_1' class='oprs-top-leaderboard'></div>
</script>

```

I’m kind of confused with different ways to do this migration. Appreciate if someone explains what to do. Thanks

---

<div class="post-metadata">

### Author: ![Lhc\_fl](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/lhc_fl/32/268115_2.png) [@Lhc\_fl](https://meta.discourse.org/u/Lhc_fl)
#### Post date: [July 15, 2025, 2:13pm UTC](https://meta.discourse.org/t/modernizing-inline-script-tags-for-templates-js-api/366482/11 "2025-07-15T14:13:16Z")

</div>

Just `renderInOutlet` to the connector

```gjs
import { apiInitializer } from "discourse/lib/api";

export default apiInitializer((api) => {
  api.renderInOutlet("below-site-header", <template>
    <div id='WW_T_D_1' class='oprs-top-leaderboard'></div>
  </template>);
});

```

---

<div class="post-metadata">

### Author: ![marco084](https://avatars.discourse-cdn.com/v4/letter/m/4da419/32.png) [@marco084](https://meta.discourse.org/u/marco084)
#### Post date: [July 15, 2025, 2:28pm UTC](https://meta.discourse.org/t/modernizing-inline-script-tags-for-templates-js-api/366482/12 "2025-07-15T14:28:50Z")

</div>

Thank you. I tried and it didn’t work 😕

This my structure and these are

below-site-header.js

```plaintext

export function test() {
    let test2 = document.querySelector('.test');
    console.log('test ', test2);
}

```

And below-siteheader-connectors.hbs

```plaintext
<div class="test"></div>

```

I’m new to this so any help is appreciated. I took this repo from a previous dev.

 ![image](https://global.discourse-cdn.com/meta/original/4X/1/3/b/13bb8ab5fd79f5fe618ad2e4a71548e0db294d9a.png)

---

<div class="post-metadata">

### Author: ![NateDhaliwal](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/natedhaliwal/32/313494_2.png) [@NateDhaliwal](https://meta.discourse.org/u/NateDhaliwal)
#### Post date: [July 15, 2025, 11:39pm UTC](https://meta.discourse.org/t/modernizing-inline-script-tags-for-templates-js-api/366482/13 "2025-07-15T23:39:34Z")

</div>

Hi there, could you share the link to your Github repo? Thanks!

---

<div class="post-metadata">

### Author: ![Yuun](https://avatars.discourse-cdn.com/v4/letter/y/977dab/32.png) [@Yuun](https://meta.discourse.org/u/Yuun)
#### Post date: [July 20, 2025, 3:17pm UTC](https://meta.discourse.org/t/modernizing-inline-script-tags-for-templates-js-api/366482/14 "2025-07-20T15:17:00Z")

</div>

So I’ve slapped my tiny “make-avatar-bigger” script into the JS tab (out of `Desktop - <head>` ), and that works simply enough, but is there at least a quick ‘n dirty way to keep it only applying in Desktop? My mobile avatars are also now large and it all looks rather silly.

The code for ref is:

```javascript
import { apiInitializer } from "discourse/lib/api";

export default apiInitializer((api) => {
 api.changeWidgetSetting('post-avatar', 'size', '70');
});

```

---

<div class="post-metadata">

### Author: ![NateDhaliwal](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/natedhaliwal/32/313494_2.png) [@NateDhaliwal](https://meta.discourse.org/u/NateDhaliwal)
#### Post date: [July 20, 2025, 3:52pm UTC](https://meta.discourse.org/t/modernizing-inline-script-tags-for-templates-js-api/366482/15 "2025-07-20T15:52:49Z")

</div>

Hmm… maybe adjust this with CSS?

Or, maybe:

```plaintext
import { apiInitializer } from "discourse/lib/api";

export default apiInitializer((api) => {
  const site = api.container.lookup("service:site");
  if (!site.mobileView) {
    api.changeWidgetSetting('post-avatar', 'size', '70');
  }
});

```

Something from the top of my head.

---

<div class="post-metadata">

### Author: ![Yuun](https://avatars.discourse-cdn.com/v4/letter/y/977dab/32.png) [@Yuun](https://meta.discourse.org/u/Yuun)
#### Post date: [July 20, 2025, 4:03pm UTC](https://meta.discourse.org/t/modernizing-inline-script-tags-for-templates-js-api/366482/16 "2025-07-20T16:03:47Z")

</div>

That did the trick perfectly, thank you!

---

<div class="post-metadata">

### Author: ![Lhc\_fl](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/lhc_fl/32/268115_2.png) [@Lhc\_fl](https://meta.discourse.org/u/Lhc_fl)
#### Post date: [July 21, 2025, 8:09am UTC](https://meta.discourse.org/t/modernizing-inline-script-tags-for-templates-js-api/366482/17 "2025-07-21T08:09:24Z")

</div>

Just a friendly reminder: `changeWidgetSetting` on post-avatar [is a deprecated API and will be removed soon](https://meta.discourse.org/t/upcoming-post-stream-changes-how-to-prepare-themes-and-plugins/372063).

Maybe you should change your code to this

```gjs
import { apiInitializer } from "discourse/lib/api";

export default apiInitializer((api) => {
  const site = api.container.lookup("service:site");
  if (!site.mobileView) {
    api.modifyClass("component:post/avatar", (SuperClass) => class extends SuperClass {
      get size() { return "70"; } 
    });
  }
});

```

---

<div class="post-metadata">

### Author: ![JammyDodger](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/jammydodger/32/254611_2.png) [@JammyDodger](https://meta.discourse.org/u/JammyDodger)
#### Post date: [July 21, 2025, 9:38am UTC](https://meta.discourse.org/t/modernizing-inline-script-tags-for-templates-js-api/366482/18 "2025-07-21T09:38:06Z")

</div>

I think there’s also an #official theme component for this as well? [Avatar Size and Shape](https://meta.discourse.org/t/avatar-size-and-shape/106124)

Not sure if it fits the particular use case, but it seems like it should (with the added bonus that someone will fix it if it needs updating 🙂)

---

<div class="post-metadata">

### Author: ![Yuun](https://avatars.discourse-cdn.com/v4/letter/y/977dab/32.png) [@Yuun](https://meta.discourse.org/u/Yuun)
#### Post date: [July 21, 2025, 11:36am UTC](https://meta.discourse.org/t/modernizing-inline-script-tags-for-templates-js-api/366482/19 "2025-07-21T11:36:21Z")

</div>

I have upgraded all the way from quick 'n dirty to officially supported, thanks all!

---

<div class="post-metadata">

### Author: ![ES-Alexander](https://avatars.discourse-cdn.com/v4/letter/e/6a8cbe/32.png) [@ES-Alexander](https://meta.discourse.org/u/ES-Alexander)
#### Post date: [July 22, 2025, 2:58pm UTC](https://meta.discourse.org/t/modernizing-inline-script-tags-for-templates-js-api/366482/20 "2025-07-22T14:58:41Z")

</div>

Noting for people with legacy components (using separate Desktop/Mobile handling) that the JS tab is only available in the Common section - hopefully saves somebody else a few searches 🙂

[Next page](https://meta.discourse.org/t/modernizing-inline-script-tags-for-templates-js-api/366482.md?page=2)
