How to add Javascript the right way in Sage10

Want to add my own custom JavaScript to my small theme.

I’ve found that this is working ok, putting it in the app.js file like so.

import domReady from '@roots/sage/client/dom-ready';

/**
 * Application entrypoint
 */
domReady(async () => {
  console.log('test1');
});

/**
 * @see {@link https://webpack.js.org/api/hot-module-replacement/}
 */
import.meta.webpackHot?.accept(console.error);

But it doesn’t seem great for theme organisation, and its very different from Sage9 so i suspect there is another way of doing things. I can’t find any help on this in the docs, on any part of the javascript aspect at all. Is anyone able to point me in the right direction on how you split up your .js files and load them properly?

Here’s a link that should get you started: Modules, introduction

If I’m understanding your question, you’re looking to break up your app.js file into modules. Here’s a simplified example from a recent project:

/resources/scrpts/animations.js

export const animations = async (err) => {
  if (err) {
    console.error(err);
  }

  // ...
};

import.meta.webpackHot?.accept(animations);

/resources/scripts/app.js

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

/**
 * Application entrypoint
 */
domReady(async () => {
  animations();
});

/**
 * @see {@link https://webpack.js.org/api/hot-module-replacement/}
 */
import.meta.webpackHot?.accept(console.error);
7 Likes

Thank you @csorrentino for taking the time to respond to me, and with such a clear example! It’s working perfectly.

Much appreciated!

1 Like

Is this the recommended pattern for all modules being imported into app.js?

I’m new to sage and I’m assuming that some syntactic sugar has been used for other frameworks using HMR, or maybe this is new since I’ve used Webpack last.

You can also import ES modules conditionally

const main = async (err) => {
    if (err) {
        // handle hmr errors
        console.error(err);
    }

    if (document.body.classList.contains('home')) {
        const {default: Hero} = await import('./Hero/HomeHero.js');
        new Hero(document.querySelector('canvas.webgl'));

        // ALTERNATIVE SINTAX:
        // import('./Hero/HomeHero.js').then(({default: Hero}) => {
        //     new Hero(document.querySelector('canvas.webgl'));
        // });

        const {default: SwiperFrontPage} = await import('./swiperFrontPage.js');
        new SwiperFrontPage();

        // ALTERNATIVE SINTAX:
        // import('./swiperFrontPage.js').then(({default: SwiperFrontPage}) => {
        //     new SwiperFrontPage();
        // });
    }
};
3 Likes

Oh damn that’s powerful. Thx.

So for Sage 10 out of the box it could look something like

domReady(async (err) => {
  if (err) {
    console.error(err);
  }

  if (document.body.classList.contains('single-post')) {
    const { SinglePost } = await import('./singlePost.js');
    new SinglePost()
  }
});
2 Likes

Yes. Bud has documentation about dynamic imports:

4 Likes

That’s fantastic! I can see how powerful this will be for making themes as sleek as possible.

1 Like