Skip to main content
JavaScript for Joomla
On this page
# Topics

JavaScript for Joomla

29 June 2026

Open any Joomla page and look behind the scenes: the menus that fold open, the media manager that uploads without a reload, the editor that formats your text, the tabs that switch panels. None of that is PHP. It is JavaScript, the language that runs inside the visitor's browser. Joomla is written in PHP on the server, but almost everything that moves, reacts, or updates on the screen is JavaScript on the client.

This article explains JavaScript from a Joomla point of view. It covers the basics for site owners, the way Joomla loads and manages scripts for administrators, and the developer tools (the Web Asset Manager, ES modules, Web Components, and passing data from PHP to the browser) for those who build extensions and templates.

PHP builds the page on the server; JavaScript brings it to life in the browser.

The goal is simple: help you understand how Joomla uses JavaScript well enough to add your own, keep it fast, and keep it safe.

1. The Basics

1.1 What is JavaScript?

JavaScript is a programming language that runs inside the web browser, on the visitor's own computer or phone. This is the key difference from PHP: PHP runs on the server and builds the HTML, while JavaScript runs after that HTML has arrived, on the client side. The two never run in the same place at the same time.

When someone opens a Joomla page, the server sends finished HTML, CSS, and a set of JavaScript files. The browser draws the page, then runs the JavaScript. From that moment, JavaScript can change the page without asking the server again: it can show and hide elements, validate a form, or fetch a small piece of new data in the background.

1.2 Server Side Versus Client Side

It helps to keep the two halves of a Joomla request clearly apart:

QuestionPHP (server side)JavaScript (client side)
Where does it run? On the web server. In the visitor's browser.
When does it run? Before the page is sent. After the page has arrived.
Can it reach the database? Yes, directly. No, only by calling the server.
Can the visitor read it? No, only the output. Yes, it is delivered as plain text.
Good for Building pages, security, data. Interactivity, instant feedback.

That last row matters for security: anyone can read and change the JavaScript you send. So a check in JavaScript is a convenience for the user, never a real defence. The server must check everything again.

1.3 Where Joomla Uses JavaScript

You do not have to write a line of JavaScript to benefit from it. Joomla 6 already uses it across the whole interface:

  • The administrator menu, tabs, and modal dialogs.
  • The Media Manager, which uploads and previews without a page reload.
  • The editor (TinyMCE or CodeMirror), which is a large JavaScript application.
  • Form fields such as the tag picker, the calendar, and color pickers.
  • Guided Tours, the Joomla Update progress bar, and the System Dashboard.

All of this ships with Joomla and is maintained by the project. Your job, when you add your own JavaScript, is to plug into the same system rather than fight it.

Back to top

2. A Short History: No More jQuery by Default

2.1 From MooTools to Vanilla JavaScript

Older Joomla versions leaned on JavaScript libraries. Joomla 1.5 to 3 shipped MooTools, and Joomla 3 added jQuery and Bootstrap 2. Every page loaded a large library whether it needed it or not.

Joomla 4 broke with that. The core was rewritten to use plain, modern JavaScript (often called "vanilla JS") and the browser's own standards, so most pages no longer load jQuery at all. Joomla 6 continues this: the core ships clean, framework-free JavaScript and only loads a heavy library when an extension genuinely asks for it.

2.2 jQuery Is Still Available, But Optional

jQuery did not disappear; it became an opt-in asset. You can see it in the bundled libraries:

media/vendor/jquery/
media/vendor/jquery-migrate/
media/vendor/bootstrap/

If an old extension still needs jQuery, Joomla can load it on request through the Web Asset Manager (section 4). But for new code, the advice is clear: use plain JavaScript. The browser today does almost everything jQuery once did, with no extra download.

2.3 Why This Matters to You

The practical result is speed. A page that does not load jQuery, MooTools, and three plugins that each pull in their own copy is smaller and faster. When you add an extension, it is worth knowing whether it loads its own JavaScript library, because several extensions each loading jQuery is a common, hidden cause of a slow site.

2.4 Migrating Scripts From Joomla 3

If you maintain an old extension, the move to Joomla 6 is mostly a swap of habits. The pattern is the same for each one: drop the old framework call and use the modern equivalent.

Joomla 3 wayJoomla 6 way
JHtml::_('jquery.framework') Plain JavaScript, or useScript('jquery') only if truly needed.
$doc->addScript('path/to/file.js') A named asset loaded with useScript (section 4).
Inline <script> in a layout addScriptOptions for data, an external file for code.
jQuery selectors and effects document.querySelector and the browser's own methods.

You rarely have to rewrite everything at once. Start by moving scripts into the Web Asset Manager, then replace jQuery calls with plain JavaScript a piece at a time.

Back to top

3. How the Browser Loads Joomla's JavaScript

3.1 Scripts at the Bottom, Loaded Once

When Joomla renders a page, it collects all the JavaScript that the page, its modules, and its plugins asked for, removes duplicates, sorts them by dependency, and writes the <script> tags into the HTML. You never add the same file twice; Joomla handles that for you.

3.2 defer, async, and module

Modern Joomla marks its scripts so they do not block the page from drawing. Three attributes control this:

AttributeWhat it does
defer Download now, run after the HTML is parsed. The safe default.
async Download now, run as soon as ready, in any order. For independent scripts.
type="module" Treat the file as an ES module. Always deferred, and can import other modules.
nomodule Load only in old browsers that do not understand modules. A fallback.

Joomla's script renderer understands all of these. The point for you is that you should not paste a plain <script> at the top of a template; let Joomla add it with the right attributes so it does not slow the first paint.

3.3 ES Modules and the Import Map

Joomla 6 uses ES modules: modern JavaScript split into files that import from each other, the same standard your browser uses natively. To let one module find another by a short name instead of a long path, Joomla writes an import map into the page:

<script type="importmap">
{
  "imports": {
    "editor-api": "/media/system/js/editors/editor-api.min.js",
    "editor-decorator": "/media/system/js/editors/editor-decorator.min.js"
  }
}
</script>

An asset marked with "importmap": true in Joomla's asset list is added to this map automatically. For very old browsers, Joomla ships a small shim (es-module-shims) so the same code still works. You do not build the import map by hand; you mark an asset and Joomla generates it.

Back to top

4. The Web Asset Manager

The Web Asset Manager (WAM) is the modern, correct way to add CSS and JavaScript in Joomla 4, 5, and 6. It replaced the old habit of calling $document->addScript() with a hard-coded path. Understanding it is the single most useful thing a Joomla developer can learn about front-end assets.

4.1 The Problem It Solves

Before WAM, every extension added its own scripts directly, often the same library several times, in the wrong order, with no shared version. WAM fixes this by treating each script or style as a named asset with declared dependencies. You ask for an asset by name; Joomla works out the files, the order, and the duplicates.

4.2 The Asset Registry and joomla.asset.json

Assets are declared in a file named joomla.asset.json. Joomla's own core assets live in media/system/joomla.asset.json, and each extension or template can ship its own. Every entry has a name, a type, a file, and its dependencies:

{
  "name": "myextension",
  "version": "1.0.0",
  "assets": [
    {
      "name": "myextension.main",
      "type": "script",
      "uri": "com_myextension/main.min.js",
      "dependencies": ["core"],
      "attributes": { "defer": true }
    }
  ]
}

Because the asset declares "dependencies": ["core"], Joomla loads its own core script first, then yours. You never manage that order yourself.

4.3 Using an Asset

From PHP (in a view template, a module, or a plugin) you reach the manager through the document and call useScript() or useStyle() with the asset name:

use Joomla\CMS\Factory;

$wa = Factory::getApplication()
    ->getDocument()
    ->getWebAssetManager();

// Load a core asset by name:
$wa->useScript('core');

// Load your own registered asset:
$wa->useScript('myextension.main');

If you have a single file that is not worth a full joomla.asset.json entry, you can register and use it in one step:

$wa->registerAndUseScript(
    'myextension.inline',
    'com_myextension/extra.js',
    [],
    ['defer' => true],
    ['core']
);

4.4 The Main Methods

MethodWhat it does
useScript('name') Enable a registered script (and its dependencies).
useStyle('name') Enable a registered stylesheet.
registerScript('name', 'uri', ...) Declare a script without enabling it yet.
registerAndUseScript(...) Declare and enable a script in one call.
addInlineScript('code') Add a small block of inline JavaScript.
disableScript('name') Turn off an asset another extension enabled.

The same method names exist for styles (useStyle, registerStyle, and so on). This is the API to learn; with it you rarely need to touch raw <script> tags again.

4.5 Useful Core Assets You Can Load

Joomla registers many of its own scripts as named assets in media/system/joomla.asset.json and media/vendor/joomla.asset.json. You enable them by name, and Joomla pulls in whatever they depend on. The ones you will reach for most are:

Asset nameWhat it gives you
core The Joomla object and its helpers. Almost everything depends on it.
keepalive Pings the server so a long edit session does not log the user out.
form.validate Client-side form validation for Joomla forms.
messages Renders Joomla's system messages (the alert bar).
bootstrap.modal Bootstrap 5 modal dialogs (also .dropdown, .collapse, .toast, .offcanvas).

So instead of shipping your own copy of a modal or a validator, you load the one Joomla already provides:

$wa->useScript('keepalive');
$wa->useScript('form.validate');
$wa->useScript('bootstrap.modal');
Back to top

5. The Joomla JavaScript Object

Joomla ships a small core JavaScript file, media/system/js/core.js, that almost every back-end page loads. It defines a global Joomla object with helpers your own scripts can use. Knowing a handful of them saves a lot of work.

5.1 Joomla.getOptions: Read Data From PHP

Joomla.getOptions reads configuration that PHP placed in the page (see section 6). It is the clean way to pass a setting, an ID, or a URL from the server to your script:

// PHP put options under the key 'com_myextension'
const opts = Joomla.getOptions('com_myextension', {});
console.log(opts.apiUrl);

5.2 Joomla.request: Talk to the Server Safely

Joomla.request is a small wrapper around the browser's request handling that adds Joomla's security token automatically. It is the simplest way to call the server from your script:

Joomla.request({
  url: 'index.php?option=com_ajax&plugin=hello&format=json',
  method: 'GET',
  onSuccess: (response) => {
    const data = JSON.parse(response);
    console.log(data.data);
  },
});

You can also use the browser's own fetch directly; both are fine. For calls that read data, either works. For calls that change data, you must add the security token, which the next helper provides.

5.3 Joomla.Text: Translate in JavaScript

Strings you show from JavaScript should still be translatable. Joomla mirrors its language system into the browser. In PHP you mark a string for the front end with Text::script('MY_KEY'), and in JavaScript you read the translation back:

// In PHP, before the page renders:
// \Joomla\CMS\Language\Text::script('COM_MYEXTENSION_SAVED');

// In JavaScript:
alert(Joomla.Text._('COM_MYEXTENSION_SAVED'));

5.4 The Most Useful Helpers

HelperWhat it does
Joomla.getOptions(key) Read data PHP injected with addScriptOptions.
Joomla.request(options) Make a request with the CSRF token attached.
Joomla.Text._('KEY') Get a translated string in the browser.
Joomla.submitform(task, form) Submit a Joomla admin form to a task.
Joomla.submitbutton(task) Run a toolbar button's task, with form validation if asked.
Joomla.renderMessages(messages) Show Joomla-style alert messages.

To use these in your own script, declare core as a dependency (or call $wa->useScript('core')) so the Joomla object exists before your code runs.

5.5 Listening for Events

Most of your JavaScript reacts to something the user does: a click, a change, a key press. The modern way to react is addEventListener. Avoid the old habit of writing onclick straight into the HTML, because it mixes behaviour into your markup and a Content Security Policy (section 12) will block it.

// Good: behaviour lives in the script, not the HTML.
document.querySelector('#save')
  .addEventListener('click', (event) => {
    event.preventDefault();
    // do the work
  });

When you have many similar elements, such as every row in a long list, do not attach a listener to each one. Attach a single listener to the parent and check what was clicked. This pattern is called event delegation, and it stays fast even when the list grows or rows are added later:

document.querySelector('#list')
  .addEventListener('click', (event) => {
    const button = event.target.closest('.delete');
    if (button) {
      // handle the delete for this row
    }
  });

One listener on the parent does the work of hundreds on the children, and it keeps working for rows your script adds after the page has loaded.

Back to top

6. Passing Data From PHP to JavaScript

A common need is to give your script some data the server knows: an article ID, a base URL, a list of options, a feature flag. Never try to print it into a <script> tag by hand, because that is a classic source of bugs and security holes. Joomla has a safe, built-in way.

6.1 addScriptOptions on the Server

In PHP, add your data with addScriptOptions. Joomla turns it into safe, escaped JSON and writes it into the page for you:

use Joomla\CMS\Factory;

$doc = Factory::getApplication()->getDocument();

$doc->addScriptOptions('com_myextension', [
    'apiUrl'  => 'index.php?option=com_ajax&plugin=stock&format=json',
    'itemId'  => 42,
    'canEdit' => $user->authorise('core.edit', 'com_myextension'),
]);

6.2 Joomla.getOptions in the Browser

Your script then reads the data back by the same key, with no parsing of HTML and no risk of broken quotes:

const cfg = Joomla.getOptions('com_myextension', {});

if (cfg.canEdit) {
  // show the edit button
}
fetch(cfg.apiUrl).then((r) => r.json()).then(render);

6.3 Why Not Just Echo It?

Printing a PHP value straight into JavaScript looks easy but is dangerous. A quote or a </script> inside the data can break the page or let an attacker inject code (cross-site scripting). addScriptOptions encodes everything correctly as JSON, so the value arrives intact and safe. Always use it instead of building a script string yourself.

Back to top

7. Web Components: Joomla's Custom Elements

Instead of a heavy framework, Joomla builds reusable interface pieces as Web Components: custom HTML elements defined by the browser standard. You use them like ordinary tags, and the browser runs the JavaScript behind them.

7.1 What a Web Component Looks Like

Joomla ships several as custom elements in media/vendor/joomla-custom-elements/, such as the alert and the tab. In your HTML they read like normal tags:

<joomla-alert type="warning" dismiss="true">
  Please save your work before leaving.
</joomla-alert>

The browser sees <joomla-alert>, loads the matching JavaScript, and the element becomes a working, dismissible alert. There is no jQuery and no framework involved.

7.2 Why Joomla Chose This

Web Components are part of the browser itself, so they keep working as browsers update and they do not lock Joomla into one JavaScript framework that might fade away. They are self-contained, reusable across templates, and load only when the matching tag appears on the page. For you as a developer, it means a stable, standards-based set of building blocks rather than a moving target.

7.3 The Bundled Libraries

Beyond its own components, Joomla bundles a curated set of third-party JavaScript libraries in media/vendor/, loaded only when needed:

LibraryUsed for
tinymce / codemirror The rich-text and code editors.
choicesjs Searchable select boxes (such as the tag field).
cropperjs Image cropping in the Media Manager.
shepherdjs The Guided Tours feature.
bootstrap Modals, dropdowns, and other interface behaviour.

Because these are shared, two extensions that both need a date picker or a chart can use the same bundled copy instead of each shipping its own.

7.4 Bootstrap 5 Comes With Joomla

One bundled library deserves its own note: Joomla ships Bootstrap 5, and not just its CSS. The JavaScript behaviour is there too, split into named assets so you load only the piece you need:

AssetComponent
bootstrap.modal Pop-up dialogs.
bootstrap.dropdown Dropdown menus.
bootstrap.collapse Show and hide panels (accordions).
bootstrap.toast Small notification messages.
bootstrap.offcanvas Slide-in side panels.

So a modal, a dropdown, or an accordion needs no extra download and no other framework, only a single useScript call:

$wa->useScript('bootstrap.modal');

7.5 Adding Your Own Library

Joomla does not bundle every library. If you need Chart.js for a graph, SortableJS for drag-and-drop, or a small framework such as Alpine.js or Vue, add it the same way as any other asset: register it in your joomla.asset.json (or with registerAndUseScript) and let the Web Asset Manager load it. Do not paste a hard-coded <script src="/..."> into your template; register the library so Joomla handles its order, its version, and its duplicates like everything else.

Back to top

8. Calling the Server: Ajax in Joomla

The most common reason to write JavaScript is to fetch or save a small piece of data without reloading the whole page. On the server side, Joomla's com_ajax component answers these calls. On the browser side, you send the request from JavaScript.

8.1 A Simple Read With fetch

For a request that only reads data, the browser's built-in fetch is enough:

const url = 'index.php?option=com_ajax&plugin=hello&format=json&name=JUG';

fetch(url)
  .then((response) => response.json())
  .then((json) => {
    console.log(json.data); // your result lives in .data
  });

8.2 Writing Data Needs the CSRF Token

Any request that changes something (save, delete, vote) must carry Joomla's one-time security token, so another site cannot forge the request. Read the token from the page options and send it as a header:

const token = Joomla.getOptions('csrf.token', '');

fetch('index.php?option=com_ajax&plugin=cart&format=json', {
  method: 'POST',
  headers: { 'X-CSRF-Token': token },
  body: new URLSearchParams({ productId: 42 }),
});

On the server, the handler must verify the token before it acts. The rule is the same as everywhere in Joomla: a read may use GET, but a write must use POST and a token.

8.3 Where to Learn More

The server side of this, including how to build the plugin that answers the call and how to secure it, is covered in its own article on com_ajax. From the JavaScript side, the two patterns above (a plain fetch for reads, a token-carrying POST for writes) cover almost everything you will do.

Back to top

9. Building and Compiling JavaScript

The JavaScript Joomla ships is not the same as the JavaScript its developers write. The source is modern and split into many files; the version sent to browsers is minified and bundled. Knowing this helps you understand what you see in media/.

9.1 Source Versus Built Files

Joomla's core JavaScript source lives in a build/ folder and is compiled into the media/ folder. You will see pairs of files:

core.js        the readable source (for debugging)
core.min.js    the minified version (smaller, for production)
core.min.js.gz pre-compressed for faster delivery

Joomla loads the .min.js version on a live site and can load the readable .js when Debug mode is on, so you can read the real code while troubleshooting.

9.2 The Build Tools

Compiling these files uses Node.js and npm, the standard JavaScript tooling, with a build script in the project. You only need this if you develop the core or an extension with its own build step. For a normal site, the built files are already in place and you never run a build.

9.3 You Rarely Need a Build for Custom Code

For your own small scripts, you do not need a build pipeline at all. Write a plain, modern .js file, register it with the Web Asset Manager, and Joomla serves it. Reach for a build step (bundling, transpiling) only when your code grows large enough to need it, not for a few lines of interactivity.

Back to top

10. Where to Put Your Own JavaScript

As with PHP, the golden rule is to never edit core files. Joomla gives you clean places to add JavaScript that survive updates.

10.1 The Right Places

You want to...Put the script in...
Add behaviour to one template's pages Your template (or child template) and a joomla.asset.json.
Change how one view outputs A template override, loading the script from there.
Add a feature site-wide A plugin that calls the Web Asset Manager.
Ship a self-contained feature A component or module with its own assets.

10.2 Loading a Script From a Plugin

A system plugin is a tidy way to add a script to every page. It listens to a page event and enables the asset:

public function onBeforeCompileHead(): void
{
    $wa = $this->getApplication()
        ->getDocument()
        ->getWebAssetManager();

    $wa->registerAndUseScript(
        'myplugin.widget',
        'plg_system_myplugin/widget.min.js',
        [],
        ['defer' => true],
        ['core']
    );
}

10.3 Avoid Inline Scripts in Content

It is tempting to paste a <script> into an article. By default Joomla's editor and text filters may strip it, and even when it survives it is hard to maintain and easy to break. Keep your JavaScript in a real .js file, loaded through the asset system, and let the article hold only content.

Back to top

11. Performance: Keep JavaScript Fast

JavaScript is powerful, but every script the browser downloads, parses, and runs costs time. On a phone over a weak connection, heavy JavaScript is one of the biggest reasons a site feels slow.

11.1 Load Less, and Load It Late

  • Use defer (the Web Asset Manager default) so scripts do not block the first paint.
  • Only enable an asset on the pages that need it, not site-wide by habit.
  • Watch for extensions that each load their own copy of jQuery or a chart library; share the bundled one instead.

11.2 Combine and Minify

Joomla can be helped here at two levels. The built core files are already minified. For the rest, a good caching or optimisation extension can combine several small scripts into one request and minify them. Fewer, smaller files mean fewer round trips and faster pages, especially on HTTP/1.1 hosts.

11.3 Debounce and Cache Requests

When your script calls the server as the user types (a live search, for example), do not send a request on every keystroke. Debounce the input: wait until the user pauses, then send one request. And cache results that rarely change, such as a list of countries, so you do not ask the server twice for the same answer.

11.4 Measure, Do Not Guess

Use the browser's developer tools (the Network and Performance tabs) to see which scripts load and how long they take. A tool such as Lighthouse points directly at render-blocking or oversized JavaScript. Optimise what the measurement shows, not what you assume.

Back to top

12. Security and JavaScript

JavaScript runs on the visitor's machine and is fully visible, so it changes how you think about security. The two big ideas are that you can never trust the client, and that injected scripts are the main threat.

12.1 Never Trust the Client

Any check you do in JavaScript, the visitor can skip, change, or fake. Form validation, a hidden "is admin" flag, a disabled button: all of it is a convenience, not a guard. The server must validate and authorise every request again, exactly as if the JavaScript were not there.

12.2 Cross-Site Scripting (XSS)

The most common JavaScript-related attack is XSS: an attacker gets their script to run inside your page, in your visitor's browser, where it can steal sessions or change content. It usually happens when user input is printed without escaping. Two habits stop most of it:

  • On the server, escape data before printing it ($this->escape($value) in templates).
  • In JavaScript, set text with element.textContent, not element.innerHTML, when you insert user-supplied data.
// Safe: treated as text, never as HTML.
node.textContent = userValue;

// Risky: if userValue contains <script>, it can run.
node.innerHTML = userValue;

12.3 Pass Data Safely

This is why section 6 matters: use addScriptOptions and Joomla.getOptions to move data from PHP to JavaScript. They encode the value as JSON so it can never break out and become executable code, which a hand-built script string can.

12.4 Content Security Policy

A Content Security Policy (CSP) is an HTTP header that tells the browser which scripts it may run, for example "only scripts from my own domain". A good CSP turns many XSS attempts into harmless, blocked requests. Joomla can set security headers through its HTTP Headers system plugin; a CSP is one of the strongest defences you can add, and it pairs well with avoiding inline scripts.

Back to top

13. SEO and Metadata

JavaScript and search ranking meet in two places: speed and content visibility. Both can help or hurt, depending on how you use scripts.

  • Render-blocking scripts delay the first paint and hurt Core Web Vitals. Defer your JavaScript so the page draws before the scripts run.
  • Heavy JavaScript raises the time before a page becomes usable. Smaller, fewer scripts give better scores.
  • Content built only by JavaScript may not be seen reliably by every crawler. Important text should be in the HTML Joomla sends, with JavaScript enhancing it, not creating it.
  • Progressive enhancement is the safe pattern: the page works without JavaScript, and scripts add convenience on top. Search engines and users with scripts blocked still see the core content.

In short, treat JavaScript as an enhancement layer for SEO. Let Joomla and PHP deliver the content and the structure; let JavaScript make it nicer, quickly and without blocking.

Back to top

14. Common Mistakes and Pitfalls

14.1 Adding Scripts the Old Way

Symptom: a script loads twice, in the wrong order, or before core.js, and your code throws "Joomla is not defined".

Fix: use the Web Asset Manager (useScript, registerAndUseScript) and declare core as a dependency, instead of a hand-written <script> tag.

14.2 Echoing PHP Data Into a Script

Symptom: the page breaks when a value contains a quote, or a security scan flags an XSS hole.

Fix: pass data with addScriptOptions in PHP and read it with Joomla.getOptions in JavaScript. Never build a script string by hand.

14.3 Trusting a JavaScript Check

Symptom: a form passes validation in the browser, but bad or unauthorised data still reaches the database.

Fix: validate and authorise on the server as well. Client-side checks are for user comfort only.

14.4 Forgetting the CSRF Token

Symptom: a save or delete call works in testing but is insecure, or fails once token checks are added on the server.

Fix: send the token (X-CSRF-Token header) on every request that changes data, and verify it server-side.

14.5 Loading jQuery Several Times

Symptom: the site is slow and the network tab shows jQuery downloaded more than once.

Fix: let extensions share Joomla's bundled libraries through the asset system, and remove extensions that ship their own duplicate copies.

14.6 Putting a Script Inside an Article

Symptom: the script vanishes after saving, or works for an admin but not for an editor.

Fix: Joomla's text filter strips scripts from content for most users. Load JavaScript from a template, override, or plugin instead.

Back to top

15. Best Practices

If you remember only a few things from this article, remember these:

  • Use the Web Asset Manager for every script and style; declare dependencies instead of guessing the order.
  • Write plain, modern JavaScript; reach for jQuery or a framework only when you truly must.
  • Pass data from PHP to JavaScript with addScriptOptions and read it with Joomla.getOptions.
  • Use Joomla.Text::script and Joomla.Text._() so script messages stay translatable.
  • Defer scripts, load them only where needed, and share bundled libraries to keep pages fast.
  • Send and verify a CSRF token for anything that changes data; keep reads on GET.
  • Never trust the client: validate and authorise every request again on the server.
  • Guard against XSS: escape on output, prefer textContent, and consider a Content Security Policy.
  • Never edit core files; add JavaScript through templates, overrides, plugins, or your own extension.
  • Keep content in the HTML and let JavaScript enhance it, so SEO and no-script users are safe.
Back to top

16. Quick Reference

WHAT IT IS    JavaScript runs in the browser; PHP runs on the server
CORE FILE     media/system/js/core.js  defines the global Joomla object
ADD A SCRIPT  $wa = $doc->getWebAssetManager(); $wa->useScript('core');
REGISTER+USE  $wa->registerAndUseScript('name', 'path.js', [], ['defer'=>true], ['core'])
ASSET FILE    joomla.asset.json  (name, type, uri, dependencies, attributes)
PHP -> JS     $doc->addScriptOptions('key', $data)
JS READ DATA  Joomla.getOptions('key', {})
TRANSLATE     PHP Text::script('KEY')  ->  JS Joomla.Text._('KEY')
REQUEST       fetch(url) for reads; Joomla.request(...) adds the token
WRITE SAFELY  header X-CSRF-Token = Joomla.getOptions('csrf.token')
MODULES       type="module" + importmap (mark asset "importmap": true)
ATTRIBUTES    defer (default), async, type=module, nomodule
WEB COMPONENT <joomla-alert>, <joomla-tab> in media/vendor/joomla-custom-elements
LIBRARIES     media/vendor/  (tinymce, codemirror, choicesjs, bootstrap, jquery)
BUILT FILES   *.js source, *.min.js production, *.min.js.gz pre-compressed
NO JQUERY     Core is vanilla JS since Joomla 4; jQuery is opt-in
SECURITY      Never trust the client; escape output; CSP; textContent over innerHTML
CUSTOM CODE   Template, override, plugin, or component - never core hacks
Back to top

17. Summary

JavaScript is the half of Joomla that runs in the browser. PHP builds the page on the server; JavaScript makes it interactive once it arrives. Joomla 6 takes a modern, standards-based approach to it:

  • Plain JavaScript: the core dropped MooTools and made jQuery optional; new code uses the browser's own features.
  • The Web Asset Manager: the correct way to add scripts and styles, with named assets and declared dependencies, so nothing loads twice or in the wrong order.
  • The Joomla object: helpers such as getOptions, request, and Text connect your script to Joomla's data, security token, and translations.
  • Web Components and ES modules: reusable, standards-based building blocks instead of a heavy framework.
  • Security and speed: never trust the client, escape output, send tokens for writes, and defer scripts so pages stay fast.

Most JavaScript problems on a Joomla site are not deep coding bugs. They are scripts added the wrong way, a library loaded several times, data echoed unsafely into a page, or a check trusted on the client that should have run on the server. Each one is quick to fix once you know how Joomla expects JavaScript to be loaded and secured.

If your site feels sluggish, throws "is not defined" errors, or you want to add interactivity such as live search or save-without-reload the right way, the cause and the cure usually sit in how the JavaScript is loaded and how it talks to the server. That is exactly the kind of front-end and Joomla integration work I help with, so a site stays fast, safe, and easy to maintain for years.

Back to top
JavaScript for Joomla
Peter Martin
Peter Martin
Joomla Specialist

Peter is a Joomla specialist and a Linux admin for fast, secure and scalable websites.

Frequently Asked Questions

What is JavaScript in Joomla?

JavaScript is the programming language that makes Joomla websites interactive. While PHP generates the page on the server, JavaScript runs in the visitor's browser to handle menus, modals, tabs, form validation, AJAX requests, media uploads, and other dynamic features. Modern Joomla uses JavaScript extensively in both the frontend and administrator interface.

How does Joomla load JavaScript files?

Joomla loads JavaScript through the Web Asset Manager (WAM). Instead of adding <script> tags manually, developers register assets in joomla.asset.json and load them with PHP. The Web Asset Manager automatically resolves dependencies, prevents duplicate scripts, improves caching, and ensures files are loaded in the correct order.

Does Joomla support modern JavaScript?

Yes. Joomla supports modern JavaScript features, including ES modules (ESM) and Web Components. ES modules allow developers to split code into reusable files, while Web Components make it possible to create encapsulated, reusable HTML elements. These technologies help developers build faster, more maintainable Joomla extensions and templates.

How do you pass data from PHP to JavaScript in Joomla?

Joomla provides several safe ways to pass server-side data to JavaScript. Developers can use the Document API, HTML data attributes, JSON responses, or Joomla's JavaScript options system. These methods avoid mixing PHP directly into JavaScript files and help keep applications secure and maintainable.

Can I use JavaScript without jQuery in Joomla?

Absolutely. Modern Joomla no longer depends on jQuery for most functionality. Native JavaScript APIs provide everything needed for DOM manipulation, event handling, AJAX requests, and animations. Using vanilla JavaScript results in smaller page sizes, better performance, and fewer external dependencies.

What is Vanilla JavaScript, and why is it called that?

Vanilla JavaScript is plain JavaScript without any external libraries or frameworks such as jQuery, React, or Vue. It uses only the features built into modern web browsers.

The term "vanilla" comes from the idea of vanilla ice cream, the basic, unflavoured version that serves as the foundation for many other flavours. Likewise, Vanilla JavaScript refers to the original, standard JavaScript language before adding extra tools or frameworks.

What are JavaScript best practices for Joomla developers?

The most important best practices are using the Web Asset Manager, writing ES modules, avoiding inline JavaScript, sanitizing all user input, minimizing DOM manipulation, loading only required scripts, and using Joomla's APIs instead of custom workarounds. Following these practices improves security, performance, and long-term compatibility with future Joomla versions.

How can I debug JavaScript errors in Joomla?

The easiest way to debug JavaScript in Joomla is to use your browser's Developer Tools. Open the Console to view errors and warnings, inspect variables, and run JavaScript code. The Network tab helps identify missing or blocked JavaScript files, while the Sources tab lets you set breakpoints and step through your code line by line.

If a script is not loading, first check whether it is registered correctly in Joomla's Web Asset Manager and whether all required dependencies are available. A missing asset or incorrect load order is a common cause of JavaScript errors.

For AJAX requests, inspect the request and response in the Network tab to verify that the server returns the expected data. If you're using ES modules, ensure the browser loads the module correctly and that import paths are valid.

When debugging, use console.log(), console.error(), and browser breakpoints to understand what your code is doing. Once you've found the problem, remove temporary debugging statements before deploying your code.

A systematic approach, checking the Console, Network, Sources, and asset loading, usually reveals JavaScript issues quickly.