How to add custom JavaScript to Joomla

Custom JavaScript in Joomla via Web Asset Manager and Easy Includes

Written by

in

Adding custom JavaScript to Joomla means loading your own .js files, CDN scripts, or trusted inline snippets on the public site without breaking the template on every update. On Joomla 4, 5, and 6 the modern stack is the Web Asset Manager. Site owners who want an admin UI can use Easy Includes by JoomlaX. Developers who prefer files in the theme can do the same job with a child template, joomla.asset.json, and a few lines of PHP. This guide covers both.

Old posts still paste raw <script> tags into Cassiopeia, hard-code CDN URLs in the head, or call deprecated Document::addScript. Those patterns fight updates and duplicate libraries. Use Easy Includes when you do not want to touch PHP. Use the DIY Web Asset Manager path when the script belongs to the template or a single override. The same guide shows how to remove custom JavaScript cleanly when you outgrow a snippet.

What you will learn

  • When to choose Easy Includes by JoomlaX vs a child template DIY path
  • Exact Easy Includes setup for files, CDN, defer/async, SRI, and exclusions
  • DIY: joomla.asset.json, useScript, registerAndUseScript, and inline scripts
  • How to remove custom JavaScript again (plugin rows, template assets, leftover hard-coded tags)
  • How to pass PHP options and language strings into JavaScript
  • Where tracking scripts belong (after cookie consent)

Pick the right place for your JavaScript

You need to… Best place Why
Add sitewide JS/CSS without editing PHP Easy Includes by JoomlaX Admin UI, Web Asset Manager, exclusions, survives template updates
Ship behaviour that belongs to one template Child template + joomla.asset.json (DIY below) Assets travel with the theme; parent can still update
Fix one component view only Template override + registerAndUseScript Loads only where needed
Build a reusable feature Module, plugin, or component media folder Proper extension packaging
Fire analytics / ads tags Consent module script slots See disable cookies for Joomla visitors

Official references: Web Asset Manager and Adding JavaScript. Product: Easy Includes · JED listing.

Why not paste scripts into the template head

  • Parent template updates overwrite index.php and media you edited in place
  • Hard-coded tags skip dependency ordering and can load jQuery or core twice
  • Document::addScript / addStyleSheet are deprecated in favour of Web Asset Manager
  • Tracking in the head often runs before visitors can Reject non-essential cookies
  • Article HTML <script> blocks are stripped by many editors and are hard to audit

Path A: Easy Includes by JoomlaX (no template edits)

Easy Includes 2.0 is a JoomlaX system plugin for Joomla 4, 5, and 6. It keeps custom CSS and JavaScript in plugin settings: site-relative files, CDN URLs, or trusted inline blocks. Each row can be enabled or disabled. Scripts register through Web Asset Manager with Normal, Defer, or Async loading, plus ES module, nomodule, crossorigin, and SRI options. Cache busting (Off, Auto, Aggressive) and exclusions for user groups, components, and URL fragments keep checkout and login clean.

Step 1: Install and enable Easy Includes

  1. Download from the JED listing or your JoomlaX account.
  2. System → Install → Extensions → upload the package.
  3. System → Manage → Plugins → System – Easy Includes.
  4. Enable the plugin. Leave administrator loading off unless you need admin assets.
  5. System → Clear Cache.

Step 2: Add a JavaScript file or CDN URL

  1. Upload your file under a stable path (for example media/templates/site/cassiopeia/js/site.js).
  2. Open Easy Includes and add a JavaScript file row.
  3. Path: site-relative such as media/templates/site/cassiopeia/js/site.js, or a full https:// CDN URL. Do not use .. traversal.
  4. Choose Normal, Defer, or Async. Prefer Defer for non-critical UI behaviour.
  5. Add SRI integrity and crossorigin when the file comes from a CDN you hash yourself.
  6. Enable the row, save, and clear cache.

Step 3: Inline JavaScript only when you must

Inline JS is trusted administrator input. Use it for tiny fixes, not large libraries. Prefer a file on disk for version control.

  • Keep snippets short with a comment naming the purpose
  • Do not paste secrets or unreviewed third-party blobs
  • Turn Debug logging on while testing exclusions, then off on production

Step 4: Exclude pages that must stay clean

Exclude Example Why
URL fragment /checkout, /cart Avoid JS that breaks payment or cart flows
Component com_users Keep login and reset pages minimal
User group Staff or special front-end groups Limit experimental scripts by audience

Step 5: Verify Easy Includes in the browser

  1. Open the front end as a guest. DevTools → Network → JS.
  2. Confirm your file loads once with the expected defer/async behaviour.
  3. Confirm excluded URLs do not load it.
  4. After editing a local file, use Auto cache busting once, then return to Off on stable production if you prefer clean URLs.
  5. Purge page cache / CDN too. Related: caching in Joomla.

Path B: DIY with Web Asset Manager

Use this when you own the template (or a child template) and want the script in Git next to the theme. Work on a child of Cassiopeia or your commercial template so parent updates do not wipe the files.

Step 6: Create the JS file in template media

  1. Create or open your child template.
  2. Add a file such as media/templates/site/YOUR_CHILD/js/custom.js (replace YOUR_CHILD with the child folder name).
  3. Put real behaviour in that file. Example starter:
document.addEventListener('DOMContentLoaded', () => {
  document.documentElement.classList.add('js-ready');
});

Step 7: Declare the asset in joomla.asset.json

Templates ship a joomla.asset.json. Add a script entry. For template media, the uri is often just the filename under the template’s js folder (Cassiopeia style). Example asset item:

{
  "name": "template.custom",
  "type": "script",
  "uri": "custom.js",
  "attributes": {
    "defer": true
  },
  "dependencies": [
    "core"
  ],
  "version": "1.0.0"
}

Bump version when you change the file so browsers fetch a fresh copy. If both custom.js and custom.min.js exist, Debug mode can prefer the non-minified file as documented in the manual.

For a CDN library, set uri to the full https:// URL and list it as a dependency of your own script asset.

Step 8: Enable the script in template PHP

In the child template index.php (near other Web Asset Manager calls):

/** @var Joomla\CMS\WebAsset\WebAssetManager $wa */
$wa = $this->getWebAssetManager();
$wa->useScript('template.custom');

Confirm the template still includes Joomla’s scripts output (the usual jdoc:include for scripts). Do not paste a raw <script src="…"> tag in the head for the same file.

Step 9: DIY for one view only

When only one override needs the script, register and use it from that tmpl file instead of loading it sitewide:

use Joomla\CMS\Factory;

$wa = Factory::getApplication()->getDocument()->getWebAssetManager();
$wa->registerAndUseScript(
    'tpl.custom.article',
    'templates/YOUR_CHILD/js/article.js',
    [],
    ['defer' => true],
    ['core']
);

Adjust the uri to match where you stored the file under media/ or the path style your template expects. Prefer a joomla.asset.json name when the asset is reused in many places.

Step 10: DIY inline script and PHP options

Tiny dynamic snippets:

$wa = Factory::getApplication()->getDocument()->getWebAssetManager();
$wa->addInlineScript("console.log('custom inline');");

Pass PHP values safely (your JS asset should depend on core):

$document = Factory::getApplication()->getDocument();
$document->addScriptOptions('site.custom', [
    'endpoint' => 'index.php?option=com_ajax&format=json',
]);
const opts = Joomla.getOptions('site.custom');

Language strings: Text::script('COM_EXAMPLE_LABEL') in PHP, then Joomla.Text._('COM_EXAMPLE_LABEL') in JS. Details: Adding JavaScript.

How to remove custom JavaScript from Joomla

Removing is the mirror of adding. Disable or delete the registration first, then delete the file, then clear every cache layer. If you only delete the .js file while the asset is still enabled, the browser shows a 404 and can break other scripts that depend on it.

Step 11: Remove scripts added with Easy Includes

  1. System → Manage → Plugins → System – Easy Includes.
  2. To pause a script without losing the row: turn that file or inline row off, save, clear cache, and verify Network no longer loads it.
  3. To remove it for good: delete the row (or clear the path / inline code), save, and clear cache.
  4. Optional: delete the physical file from media/… or your CDN upload once nothing references it.
  5. If you are retiring Easy Includes entirely: disable the plugin, confirm the front end, then System → Manage → Extensions to uninstall when you are sure.

Uninstalling the plugin removes the loader. It does not always delete files you uploaded elsewhere on disk. Remove those yourself if you no longer need them.

Step 12: Remove DIY template or override scripts

  1. Child template sitewide asset: remove or comment out $wa->useScript('template.custom'); in index.php.
  2. Remove the matching object from joomla.asset.json (or leave the file but stop calling useScript).
  3. One-view DIY: delete the registerAndUseScript / addInlineScript / addScriptOptions block from the override tmpl.
  4. Delete custom.js (and custom.min.js if present) from the template media folder when nothing else needs them.
  5. System → Clear Cache. Purge CDN / page cache. Hard-refresh DevTools with Disable cache checked and confirm the URL is gone.

Step 13: Hunt leftover hard-coded tags

Old sites often have scripts in more than one place. After you remove the modern registration, search for leftovers:

  • Parent or child index.php raw <script src="…"> tags
  • Template “Custom code” / head / footer fields in template options
  • Other system plugins that inject head scripts
  • Article or module HTML that still contains pasted <script> blocks
  • Consent module script slots (GA and ads belong there; remove or move them deliberately)
Symptom after a remove Likely cause Fix
404 for custom.js Asset still registered, file deleted Disable Easy Includes row or remove useScript / asset.json entry
Script still loads Second copy in template or another plugin Search Network initiator and remove the other source
Old file after edit Browser, Joomla, or CDN cache Bump asset version, clear all caches, hard refresh
Checkout broken after uninstall Unrelated; or you removed a required shop script Restore from backup; only remove scripts you added

Custom JavaScript vs cookie consent

Marketing and analytics tags are still JavaScript, but they are not a design asset. Put them in a consent-aware slot so Reject all prevents them from running. Easy Includes is for UI and site behaviour you control. Easy Cookie Alert (or your CMP) owns GA, ads, and similar tags.

What thinner articles leave out

Topic Typical post This guide
Joomla versions Joomla 3 template hacks Joomla 4 / 5 / 6 Web Asset Manager
No-edit path Missing or outdated free module Easy Includes by JoomlaX
DIY path Raw script tags in index.php joomla.asset.json + useScript / registerAndUseScript
Load strategy “Paste in head” Defer, async, version bumps, SRI
Tracking GA in the template Consent-first placement
Removal “Delete the file” Disable registration, then delete file, then clear caches and hunt duplicates

When the platform is the real problem

If the site is stuck on Joomla 3 with a club template full of inline scripts, adding more JS will not fix Core Web Vitals or security. Upgrade first, then add assets cleanly. Infyways migrations start at $149 with a free audit within 12 hours: Joomla Upgrade Services.

Key takeaways

  1. Use Web Asset Manager on Joomla 4, 5, and 6. Stop deprecated addScript habits.
  2. No PHP edits: Easy Includes by JoomlaX.
  3. Theme-owned scripts: child template + joomla.asset.json + useScript.
  4. One view only: registerAndUseScript in the override.
  5. Prefer files on disk over large inline blocks.
  6. Defer non-critical scripts. Bump asset version after edits.
  7. Put analytics behind consent, not in the template head.
  8. To remove: disable the Easy Includes row or useScript call first, then delete the file, then clear caches and check for hard-coded duplicates.
  9. Clear Joomla cache (and CDN/page cache) after every change.

Frequently asked questions

How do I add custom JavaScript to Joomla without editing the template?

Use Easy Includes by JoomlaX: enable the plugin, add a file or CDN row, choose Defer when appropriate, save, and clear cache.

How do I add custom JavaScript with DIY Web Asset Manager?

Put the file in child template media, declare it in joomla.asset.json, call useScript in the template PHP, and clear cache.

What is the Web Asset Manager?

It is Joomla’s system for registering and loading CSS/JS with names, dependencies, and attributes so extensions do not step on each other.

Should I still use Document::addScript?

No for new work. Use useScript, registerScript, or registerAndUseScript instead.

Can I add JavaScript to a single Joomla article?

Avoid pasting scripts into article HTML. Prefer a menu-assigned module, an override with registerAndUseScript, or Easy Includes exclusions aimed at that page.

What is the difference between Defer and Async?

Defer runs after HTML parsing and keeps order relative to other deferred scripts. Async runs when ready and may reorder. Prefer Defer for most site UI scripts.

Where should Google Analytics go?

In a consent-controlled script slot, not as always-on custom JS. See the Joomla cookies for visitors guide.

Will Easy Includes work on Joomla 6?

Yes. Easy Includes 2.0 supports Joomla 4, 5, and 6 with Web Asset Manager registration.

How do I stop my script on checkout pages?

With Easy Includes, use exclusions for the checkout URL or shop component. With DIY template assets, load the script only from overrides that are not the checkout view.

How do I remove custom JavaScript from Joomla?

Disable or delete the Easy Includes row, or remove the useScript / registerAndUseScript call and the joomla.asset.json entry, delete the file if unused, then clear Joomla and CDN caches and confirm in Network.

Why do I still see the script after I deleted the file?

Something is still registering it, or a cached HTML/CDN copy remains. Remove the registration, purge caches, and search for a second hard-coded tag.

Where do we start if the template is full of hard-coded scripts?

Request a Joomla upgrade audit, move assets into Easy Includes or a child template, and remove the hard-coded tags.