Styles and scripts
Styles and scripts in Joomla are not added with hand-written link and script tags. That is the job of the Web Asset Manager. It never outputs the same file twice, orders dependencies correctly and appends a version number to the URL so the browser does not keep an old file in its cache.
Where the files live
Everything served to the browser directly is stored in the media folder of the site — in a subfolder named after the extension. Create the files by hand:
media/mod_hello/
├── css/
│ └── style.css
└── js/
└── hello.js/* media/mod_hello/css/style.css */
.mod-hello {
padding: 12px;
border-left: 4px solid #1d6fb8;
}Loading in the layout
<?php
// modules/mod_hello/tmpl/default.php
defined('_JEXEC') or die;
$wa = $app->getDocument()->getWebAssetManager();
$wa->registerAndUseStyle('mod_hello.style', 'mod_hello/style.css');
?>
<div class="mod-hello">
<p><?php echo htmlspecialchars($greeting, ENT_QUOTES, 'UTF-8'); ?></p>
</div>The first argument is the asset name, the second is the path. mod_hello/style.css means the file media/mod_hello/css/style.css: Joomla adds the css folder itself based on the file extension. Reload the site — the block gets a blue bar on the left, and the page source gets a link tag.
A script
// media/mod_hello/js/hello.js
document.querySelectorAll('.mod-hello').forEach((block) => {
block.addEventListener('click', () => block.classList.toggle('is-open'));
});// modules/mod_hello/tmpl/default.php
$wa->registerAndUseScript('mod_hello.script', 'mod_hello/hello.js', [], ['defer' => true]);The third argument holds asset options, the fourth holds tag attributes: defer postpones the script until the page has loaded.
The joomla.asset.json file
When there are several assets, they are described once in the file media/mod_hello/joomla.asset.json:
{
"$schema": "https://developer.joomla.org/schemas/json-schema/web_assets.json",
"name": "mod_hello",
"version": "1.0.0",
"assets": [
{
"name": "mod_hello.style",
"type": "style",
"uri": "mod_hello/style.css"
},
{
"name": "mod_hello.script",
"type": "script",
"uri": "mod_hello/hello.js",
"dependencies": ["core"],
"attributes": {"defer": true}
}
]
}The layout then only loads this file and names the assets it needs:
// modules/mod_hello/tmpl/default.php
$wa = $app->getDocument()->getWebAssetManager();
$wa->getRegistry()->addExtensionRegistryFile('mod_hello');
$wa->useStyle('mod_hello.style')
->useScript('mod_hello.script');dependencies are assets that must be output earlier: core is the main Joomla script. For a component the joomla.asset.json file is loaded automatically; modules and plugins need the addExtensionRegistryFile() call.
The media section of the manifest
For the files to reach the media folder when installing from an archive, list them in the manifest:
<!-- modules/mod_hello/mod_hello.xml -->
<media destination="mod_hello" folder="media">
<filename>joomla.asset.json</filename>
<folder>css</folder>
<folder>js</folder>
</media>In the archive these files sit in a media folder next to the manifest, and the installer copies them into media/mod_hello of the site. When developing in place you have already put the files there yourself.
Manager methods
| Method | What it does |
|---|---|
registerAndUseStyle(), registerAndUseScript() | Describe and load a file in one line |
useStyle(), useScript() | Load an asset described in joomla.asset.json |
addInlineStyle(), addInlineScript() | Add code straight into the page |
Common mistake
Style files are put into the module folder itself — modules/mod_hello/css — and a link tag is written in the layout. Such a file is loaded several times when there are two modules on the page and stays outside the common asset order. Static files go only into media, and loading goes only through the manager.