# Trigger javascript on clicking any page link, but before the page content loads?

**URL:** https://meta.discourse.org/t/trigger-javascript-on-clicking-any-page-link-but-before-the-page-content-loads/167970
**Category:** Development
**Created:** [October 22, 2020, 3:13pm UTC](https://meta.discourse.org/t/trigger-javascript-on-clicking-any-page-link-but-before-the-page-content-loads/167970 "2020-10-22T15:13:01Z")
**Posts on this page:** 11
**Page:** 1

<div class="post-metadata">

### Author: ![Canapin](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/canapin/32/119591_2.png) [@Canapin](https://meta.discourse.org/u/Canapin)
#### Post date: [October 22, 2020, 3:13pm UTC](https://meta.discourse.org/t/trigger-javascript-on-clicking-any-page-link-but-before-the-page-content-loads/167970/1 "2020-10-22T15:13:01Z")

</div>

Hi.  
When we change page in Discourse, these are the apparent steps:

1. We click on the link
2. The current content disappears and the loader appears
3. The URL is updated and the new content appears

This is slightly different when we go from a page to the home, as the URL is changed to the home URL when the current content disappears, and not when the new content appears.

My goal is to have a script that is executed as soon as we click any page link on Discourse.  
`api.onPageChange` won’t fit in this case since the code is executed quite at the same time the new page content is loaded.

Is there a Discourse method for that? I look at the event triggers but didn’t find any one corresponding to what I need.

---

<div class="post-metadata">

### Author: ![Johani](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/johani/32/176920_2.png) [@Johani](https://meta.discourse.org/u/Johani)
#### Post date: [October 22, 2020, 6:12pm UTC](https://meta.discourse.org/t/trigger-javascript-on-clicking-any-page-link-but-before-the-page-content-loads/167970/2 "2020-10-22T18:12:43Z")

</div>

Hey 👋

There’s currently no method in the Plugin-API that will allow you to fire a script before a page transition because this has not come up before as far as I recall.

That said, you can leverage on the `willTransition()` action in the application route

> <https://github.com/discourse/discourse/blob/52672b9eabccb1184d85dc7f08062d5a7c18cb73/app/assets/javascripts/discourse/app/routes/application.js#L61-L64>

You would use something that like this in your theme / component

```javascript
// this fires after the transition
api.onPageChange((url, title) => {
  console.log("after transition");
});

// this fires right before the transition
api.modifyClass("route:application", {
  pluginId: "some-name",
  actions: {
    willTransition() {
      // run core code first
      this._super(...arguments);
      // then do some work
      console.log("before transition");
      // you can also do something like this to see what data you have
      // to work with like _router
      console.log(this)
    }
  }
});

```

---

<div class="post-metadata">

### Author: ![Canapin](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/canapin/32/119591_2.png) [@Canapin](https://meta.discourse.org/u/Canapin)
#### Post date: [October 23, 2020, 4:38pm UTC](https://meta.discourse.org/t/trigger-javascript-on-clicking-any-page-link-but-before-the-page-content-loads/167970/3 "2020-10-23T16:38:16Z")

</div>

Exactly what I needed. Thanks!

---

<div class="post-metadata">

### Author: ![merefield](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/merefield/32/176214_2.png) [@merefield](https://meta.discourse.org/u/merefield)
#### Post date: [November 4, 2024, 10:28am UTC](https://meta.discourse.org/t/trigger-javascript-on-clicking-any-page-link-but-before-the-page-content-loads/167970/4 "2024-11-04T10:28:41Z")

</div>

> [@Johani](#):
>
> ```plaintext
> // this fires right before the transition
> api.modifyClass("route:application", {
> pluginId: "some-name",
> actions: {
> willTransition() {
> 
> ```

This doesn’t seem to fire on entering a Topic from a Topic List?

I’ve also tried adding one:

```plaintext
      api.modifyClass("route:topic", {
        pluginId: PLUGIN_ID,
        actions: {
          willTransition() {

```

but that doesn’t fire either.

---

<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: [November 4, 2024, 12:04pm UTC](https://meta.discourse.org/t/trigger-javascript-on-clicking-any-page-link-but-before-the-page-content-loads/167970/5 "2024-11-04T12:04:28Z")

</div>

Couple of reasons that might not be working:

1. putting actions in a hash is an old syntax which we no longer use in Discourse. Theoretically it should work, but the interop with the new syntax might not be perfect. The modern way would be

2. I don’t think `willTransition` is guaranteed to fire on the application route in all situations. (e.g. if a child route has a willTransition action, it won’t necessarily bubble up)

I’d recommend using the events on the Ember router service instead: [RouterService | 5.12.0 | Ember API Documentation](https://api.emberjs.com/ember/5.12/classes/RouterService/events)

e.g. something like

```js
const router = api.container.lookup("service:router");
router.on("routeWillChange", () => {
  console.log("route will change fired");
});

```

---

<div class="post-metadata">

### Author: ![merefield](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/merefield/32/176214_2.png) [@merefield](https://meta.discourse.org/u/merefield)
#### Post date: [November 4, 2024, 12:10pm UTC](https://meta.discourse.org/t/trigger-javascript-on-clicking-any-page-link-but-before-the-page-content-loads/167970/6 "2024-11-04T12:10:11Z")

</div>

Nice, thanks David, I will try that next!

This investigation was triggered (ahem) because I needed a way of firing something on every page change, and _prior_ to Render.

Page Change api event doesn’t seem to be guaranteed to fire before page elements are rendered, apparently.

---

<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: [November 4, 2024, 12:13pm UTC](https://meta.discourse.org/t/trigger-javascript-on-clicking-any-page-link-but-before-the-page-content-loads/167970/7 "2024-11-04T12:13:02Z")

</div>

> [@merefield](#):
>
> needed a way of firing something on every page change, prior to Render.

I think you’ll struggle to do this perfectly. Ember expects to be in full control of rendering, so trying to hook into arbitrary points will be hard, and may cause issues (depending what you’re trying to do).

Obviously I don’t know what your end goal is… so maybe the pain is justified. In which case: feel free to ignore me 😉

(of course, if you’d like to open a #Development topic about the problem you’re trying to solve, I’d happily take a look)

---

<div class="post-metadata">

### Author: ![merefield](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/merefield/32/176214_2.png) [@merefield](https://meta.discourse.org/u/merefield)
#### Post date: [November 4, 2024, 12:16pm UTC](https://meta.discourse.org/t/trigger-javascript-on-clicking-any-page-link-but-before-the-page-content-loads/167970/8 "2024-11-04T12:16:37Z")

</div>

Happy to be explicit as the code is open source:

> <https://github.com/merefield/discourse-tc-house-ads-livewrapped/blob/ce2bc2a3d7d4ef8ad29f48295c5c9b37403dbeb5/javascripts/discourse/components/livewrapped-ad.gjs#L43>

I’m working with a third party ad provider and they have an ad page reset function in javascript that needs to be run before the new page’s ads are triggered.

any improvement is welcome and I’ve already realised this on the Topic List with Johani’s code. (in an open PR).

But this left the Topic … I will try your suggestion next and adopt it in both instances if that improves things further.

---

<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: [November 4, 2024, 12:20pm UTC](https://meta.discourse.org/t/trigger-javascript-on-clicking-any-page-link-but-before-the-page-content-loads/167970/9 "2024-11-04T12:20:56Z")

</div>

Ah I see, so you’re not modifying the DOM directly 👌

In that case I hope `routeWillChange` will work - it should certainly fire before the next route is rendered.

Caveat is that… in the case of things like redirects, it may fire twice. Or may fire, and then the transition ends up being aborted. But maybe that’s fine in this case.

---

<div class="post-metadata">

### Author: ![merefield](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/merefield/32/176214_2.png) [@merefield](https://meta.discourse.org/u/merefield)
#### Post date: [November 4, 2024, 12:23pm UTC](https://meta.discourse.org/t/trigger-javascript-on-clicking-any-page-link-but-before-the-page-content-loads/167970/10 "2024-11-04T12:23:11Z")

</div>

Yes, none of that naughty direct DOM modification malarky here at Merefield Technology Towers. 😅

Yes, I’ll use the service, that’s what it’s for! I’ll revert with my experience as I’m sure the results might interest others.

---

<div class="post-metadata">

### Author: ![merefield](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/merefield/32/176214_2.png) [@merefield](https://meta.discourse.org/u/merefield)
#### Post date: [November 4, 2024, 12:29pm UTC](https://meta.discourse.org/t/trigger-javascript-on-clicking-any-page-link-but-before-the-page-content-loads/167970/11 "2024-11-04T12:29:52Z")

</div>

So yes, that cleans up and things do happen in the right order on both routes now.

🚀

Thanks for your help!
