# Issue with Defining and Using Functions from Custom Script in Sage 10

**URL:** https://discourse.roots.io/t/issue-with-defining-and-using-functions-from-custom-script-in-sage-10/27278
**Category:** sage
**Created:** 2024-06-09T10:56:19Z
**Posts:** 10

## Post 1 by @dehol — 2024-06-09T10:56:19Z

Hello everyone,

I’m currently working on a project using Sage 10 and I have encountered an issue with importing and using a custom JavaScript function. Here are the details:  
What I’ve Done

```
Created a custom JavaScript file:
    File: resources/scripts/custom.js
    Content:
```

```
export const custom = async (err) => {
      if (err) {
        console.error(err);
      }
      console.log('custom js loaded');
    };

    function changeImage(src) {
      document.getElementById('mainImage').src = src;
    }
```

Imported the custom script in app.js:

```
File: resources/scripts/app.js
Content:
```

```
import domReady from '@roots/sage/client/dom-ready';
        import { custom } from '@scripts/custom.js';

        /**
         * Application entrypoint
         */
        domReady(async () => {
          // application code
          custom();
        });
```

The Issue

```
The console log console.log('custom js loaded'); in custom.js works well, indicating that the custom script is being loaded.
However, the changeImage function defined in custom.js is not working and returns an error changeImage is not defined.
```

What I’ve Tried

```
If I include the changeImage function directly in the Blade file, it works without any issues.
I want to keep the code clean and maintain the separation of concerns by keeping the JavaScript in the custom.js file.
```

Question

How can I properly define and use the changeImage function (and other similar functions) from the custom.js file in my Blade templates or other JavaScript files in Sage 10? Any guidance on how to solve this issue while keeping the code clean would be greatly appreciated.

Thank you in advance for your help!  
Additional Information

```
Environment: Sage 10
JavaScript Framework: Included with Sage 10 setup
Any other relevant details: The project structure follows the default Sage 10 setup.
```

---

## Post 2 by @strarsis — 2024-06-12T10:32:27Z

> [@dehol](#):
>
> ```
> function changeImage(src) {
> ```

If I understand you correctly, you want to import the `changeImage` method in `app.js`. In your current code the `changeImage` method is not exported, only `custom` method is.

You want to make the `changeImage` method globally available?

I mean, you could just assign `window.changeImage = changeImage` and it should be globally available. But you have to export it correctly first.

---

## Post 3 by @ahmed — 2024-06-15T06:22:40Z

Can you give more details if you have an idea about the topic? Thanks

---

## Post 4 by @strarsis — 2024-06-15T08:43:38Z

When I understand you correctly, you want to make the `changeImage` method available to some other, external script? Or do you want to use it in your own script?

---

## Post 5 by @ahmed — 2024-06-15T10:53:21Z

the function changeImage to be used in the templates files , when to use in html file it will be working add it to onclick for example

---

## Post 6 by @strarsis — 2024-06-15T11:00:13Z

I see, so are you using `onclick` or `addEventListener` on those elements in the template files (HTML)?

```
export const custom = async (err) => {
      if (err) {
        console.error(err);
      }
      console.log('custom js loaded');
    };

    export const changeImage = (src) => {
      document.getElementById('mainImage').src = src;
    };
```

```
import domReady from '@roots/sage/client/dom-ready';
        import { custom, changeImage } from '@scripts/custom.js';

        /**
         * Application entrypoint
         */
        domReady(async () => {
          // application code
          custom();

         const element = document.querySelector('.my-selector');
         element.addEventListener('click', changeImage.bind(this, 'some-src'));
         element.addEventListener('touchstart', changeImage.bind(this, 'some-src'));
        });
```

I am not sure what the exact use case is. There are many solutions, but few are of best practice. If each element should have its own src, you may want to use a data-attribute and the changeImage handler to use that instead.  
Or use `addEventListener` on the containing element and filter by those elements.

---

## Post 7 by @ahmed — 2024-06-22T20:11:32Z

> [@strarsis](#):
>
> `export const`

The problem that the js script works only when I add it to single custom post type in the bottom of single-product.blade.php  
but when I enqueue it (I use bundle , entrypoints correctly ) It does not work and show as undefined function.

```
<script>
    function changeImage(src) {
      document.getElementById('mainImage').src = src;
      document.querySelectorAll('.product-thumbnails img').forEach(img => img.classList.remove('active'));
      document.querySelector(`.product-thumbnails img[src="${src.replace('600x600', '150x150')}"]`).classList.add('active');
    }
</script>
```

---

## Post 8 by @strarsis — 2024-06-22T20:32:55Z

> [@ahmed](#):
>
> It does not work and show as undefined function.

But where does it show as undefined? Are you using event listener attributes directly (as `onclick`)?

---

## Post 9 by @ahmed — 2024-06-23T09:39:39Z

I am using on click as function in html attribute; onclick=functionname() after that I am defining the function in js file  
function functionname(){…

---

## Post 10 by @strarsis — 2024-06-23T11:49:43Z

> [@ahmed](#):
>
> onclick=functionname()

When you import that function in app.js, but not using it there, webpack would optimize it away. You should be able to make it globally available and prevent webpack from optimizing it away by attaching it to the `window` object:

```
import { functionname } from ...

window.functionname = functionname;
```
