Blog

  • How to Upgrade Joomla 3 to Joomla 6: The Complete Step-by-Step Guide

    How to Upgrade Joomla 3 to Joomla 6: The Complete Step-by-Step Guide

    Short answer: You can’t jump straight from Joomla 3 to Joomla 6. The supported path is 3.10 → 4.4 → 5.4 → 6.x, with a backup, a Pre-Update Check, and an extension review at every step. Joomla 3 and Joomla 4 no longer get security fixes. Joomla 5 bug fixes end on October 13, 2026, and Joomla 6 is supported until October 2029. The core update is usually the easy part. Most of the work goes into extensions, templates, and hosting.

    Current versions (as of September 30, 2026)

    • Joomla 6.1.4 and Joomla 5.4.9: security and bugfix releases, published September 29, 2026 (release announcement).
    • Joomla 6.2: Release Candidate 1 is out for testing only. General availability is planned for about October 13, 2026 (RC announcement).
    • The last releases for the older lines are 3.10.12 and 4.4.14 (from Joomla’s official update feed).

    This guide brings together what we’ve learned from running this upgrade path on client sites. It points you to the official Joomla documentation for exact, button-by-button steps, and focuses on the decisions and problems those docs assume you’ve already worked out.


    1. Which Joomla version are you on, and why upgrade now?

    In the administrator, open System → System Information and write down three things: your Joomla version, your PHP version, and your database type and version. Everything else in this guide depends on those three numbers.

    Version lineStatusKey dates (official)
    Joomla 3.xEnd of lifeSupport ended in August 2023
    Joomla 4.xEnd of lifeSecurity support ended in October 2025 (Joomla version support table)
    Joomla 5.xSecurity fixes only, soonBugfix support ends October 13, 2026; security-only support ends October 12, 2027 (Joomla roadmap)
    Joomla 6.xCurrent majorReleased October 14, 2025; bugfixes until October 17, 2028; security until October 16, 2029 (Joomla roadmap)

    What this means in practice:

    • On Joomla 3 or 4? You’re running a CMS that no longer gets security patches. The September 29, 2026 release alone fixed 16 core security issues in 5.4 and 6.1 (release notes). Joomla 3 and 4 sites don’t get fixes like these.
    • On Joomla 5.4? You’re fine for now, but bug fixes stop in October 2026. Plan the move to 6.x on staging while you still have time.
    • Hosting pressure: Joomla 6 requires PHP 8.3. Hosts are phasing out old PHP versions, so a Joomla 3 site on PHP 7.x can break when your host upgrades PHP, whether or not you’re ready.

    2. Know the path before you start

    StageYou must be onYou move toOfficial guide
    1Latest Joomla 3.10.xJoomla 4.4.xJoomla 3.x to 4.x Step by Step Migration
    2Joomla 4.4.xJoomla 5.4.xJoomla 4.4.x to 5.x Planning and Upgrade
    3Joomla 5.4.xJoomla 6.xJoomla 5 to 6 Planning and Upgrade

    Joomla calls 3.10 → 4 a “mini-migration” because the core upgrades with one click, while third-party extensions may not. It calls 4.4 → 5 and 5.4 → 6 upgrades. If you’re on 3.9 or older, update to 3.10.12 first. On Joomla 1.5 or 2.5, you’re doing a rebuild or data migration, not an in-place upgrade.

    A note on jUpgrade: Some older videos still recommend jUpgrade. It was built for Joomla 1.5-era migrations and plays no part in the 3 → 4 → 5 → 6 path, which runs through the core Joomla Update component.

    Server requirements for each hop

    TargetPHP (minimum)Database (minimum supported)Source
    Joomla 4.x7.2.5MySQL 5.6 / PostgreSQL 113.10 → 4.0 notes
    Joomla 5.x8.1.0 (8.3 recommended)MySQL 8.0.13 / MariaDB 10.4 / PostgreSQL 12Joomla 5 requirements
    Joomla 6.x8.3.0 (8.4 recommended)MySQL 8.0.13 / MariaDB 10.6 / PostgreSQL 14Joomla 6 requirements

    Joomla 6 also needs the PHP modules json, simplexml, dom, zlib, gd, and a database driver (mysqlnd, pdo_mysql, or pdo_pgsql), plus a memory limit of at least 256 MB. If your host can’t run PHP 8.3, you’ll stop at 5.4 until you change hosts, so sort out hosting before you spend a weekend on 3 → 4. Our Joomla PHP.ini settings guide covers memory and execution limits.

    3. Pre-upgrade audit: extensions, templates, and custom code

    Most upgrade failures come from third-party code, not the Joomla core. Before you touch anything:

    1. Export an inventory. Go to Extensions → Manage and filter by type: Package, Component, Module, Plugin, Template, Library. For each item, record the name, version, developer, and whether it’s in use.
    2. Label every extension with one of these:
      • Keep: the developer offers Joomla 5.4 and Joomla 6 builds.
      • Replace: abandoned, or Joomla 3-only. If it’s dead on Joomla 4, it’s dead on Joomla 6.
      • Remove: installed but not used. Uninstall packages first, so their modules and plugins go with them.
    3. Check against Joomla 6, not just Joomla 4. An extension that only supports Joomla 4 means paying for the same migration twice.
    4. Find custom code. Look for custom components, templates/YOUR_TEMPLATE/html/ overrides, and CLI or cron scripts. You can test extension and template ZIPs for Joomla 6 problems with our free Joomla Migration Scanner, which runs in your browser, and look up replacements for each finding in the Joomla Migration Reference.
    5. Clean up the content. The official 3.10 guide recommends emptying the trash (articles, categories, menu items) and fixing the database schema before you migrate.

    If the audit turns up more rewrites than you have time for, that’s the part of the job a Joomla upgrade team usually takes on. Everything else in this guide you can still do yourself.

    ExtensionTypeVersionDeveloperIn use?Decision (Keep/Replace/Remove)Notes
    Akeeba BackupComponentJoomla 3 buildAkeeba LtdYesKeepUpdate to the Joomla 4, 5 and 6 builds at each hop. Take a backup before every hop.
    K2Component2.xJoomlaWorksYesReplaceMove items to core articles while still on Joomla 3. Map extra fields to custom fields and 301-redirect changed URLs.
    sh404SEFComponentJoomla 3 buildWeeblrYesReplaceInstall 4SEF + 4SEO on Joomla 3 and run their sh404SEF import before the 3 → 4 migration.
    Site template (Helix3)TemplateJoomla 3 buildJoomShaperYesReplaceRebuild the layout in Helix Ultimate on staging, then remove Helix3 and its plugins.
    ChronoFormsComponentv6ChronoEngineYesReplaceInstall ChronoForms v8 alongside v6, rebuild the forms, and test email and custom PHP actions.
    JCommentsComponent3.xOriginal project (no longer developed)YesReplaceBack up the _jcomments tables, then move to the JComments 4 community fork.
    Old slideshow moduleModule1.xThird-partyNoRemoveNot published on any page. Uninstall it before the upgrade.
    Example extension inventory (illustrative example, not taken from a real site)

    4. Backups and staging: never upgrade the live site first

    • Take a full backup (files and database) before every hop, not just once at the start. Akeeba Backup is the tool most Joomla professionals use. See how to back up a Joomla website.
    • Test the restore. Restore the backup to a staging location at least once. An untested backup isn’t a rollback plan.
    • Build staging on a subdomain, a subfolder, a local stack, or a temporary hosting account, as the official guide suggests. Match the PHP and database versions you’ll run in production.
    • Keep your Joomla 3 backup until the site has been stable on Joomla 6 for a while. You’ll want the original data if an extension vendor turns out to have no Joomla 6 build.
    • Go live last. Do every hop on staging, test it, and then promote the finished site.

    5. Step by step: 3.10 → 4.4 → 5.4 → 6

    Step 1: Joomla 3.10 → 4.4

    1. On staging, update to the latest 3.10.x and fix the database schema (Extensions → Manage → Database → Fix).
    2. Go to Components → Joomla Update → Options and set Update Channel to Joomla Next. This shows the Pre-Update Check. Don’t click update yet.
    3. Read both parts of the check: Required/Recommended Settings and Extensions. Update what you’re keeping and uninstall what won’t survive. The official guide also lists old core leftovers to remove: plg_content_geshi, and the templates Beez_20, Beez5, Atomic, and Bluestork. Protostar disappears in Joomla 4.
    4. Switch to a core template (Protostar or Beez3) so Joomla 4 has a working default. You’ll replace it after the upgrade.
    5. Run the update. Then go to System → Maintenance → Database, check the schema, clear the cache, and test.
    6. Move to the latest 4.4.x before going further.

    What the Pre-Update Check really tells you: it reads each developer’s compatibility tag. It doesn’t run the code. “Missing Compatibility Tag” means the developer never told Joomla anything, so ask the developer. An extension can show as compatible and still crash with your overrides.

    Step 2: Joomla 4.4 → 5.4

    1. Once 4.4 is stable, switch PHP to 8.1 or newer (8.3 is recommended). Joomla 4.4 runs on PHP 8.1, so change PHP while you’re still on 4.4 and retest.
    2. Update your extensions to their Joomla 5 builds.
    3. Set the channel to Joomla Next, run the Pre-Update Check, and upgrade to 5.x. The Behaviour – Backward Compatibility plugin is enabled during this upgrade, which lets older extension code keep working for now.
    4. Work through the official 4.4 → 5 guide’s notes on removed or changed core pieces. For example, the old Search component should give way to Smart Search.
    5. Update to the latest 5.4.x. Joomla 6 will only install from 5.4.

    Step 3: Joomla 5.4 → 6.x (the plugin step most guides skip)

    Joomla 5.4 ships with two plugins with almost identical names (official compatibility plugin notes):

    PluginRequired state before upgrading to 6
    Behaviour – Backward Compatibility (no number)Disabled, and your site must still work with it off
    Behaviour – Backward Compatibility 6Enabled (Joomla 5.4 installs it enabled by default)

    The official procedure:

    1. On staging, disable Behaviour – Backward Compatibility. Click through the whole site and the administrator.
    2. If something breaks, turn the plugin back on, find the extension that depends on it, and update, replace, or remove that extension, all while you’re still on 5.4. Joomla’s reasoning: it’s much safer for an incompatible extension to fail on 5.4, where you can re-enable the plugin, than halfway through the 6 upgrade.
    3. Once the site works with that plugin off, confirm PHP 8.3+ and a supported database, then take a fresh backup.
    4. Set the channel to Joomla Next, run the Pre-Update Check, and upgrade to the current 6.1.x. Once 6.2.0 is out, you can move to it.

    If the administrator won’t load after you disable the plugin, re-enable it directly in the database (use your own table prefix):

    UPDATE jos_extensions SET enabled = 1
    WHERE type = 'plugin' AND folder = 'behaviour' AND element = 'compat';

    Behaviour – Backward Compatibility 6 is a bridge, not a permanent fix. Joomla says Joomla 7 won’t provide the same compatibility layer for Joomla 5-era extensions, so treat any extension that still needs it as technical debt.

    Joomla 5.4 Plugins screen filtered to Backward Compatibility, showing Behaviour - Backward Compatibility disabled and Behaviour - Backward Compatibility 6 enabled
    Joomla 5.4 Plugins screen (demo site), filtered to “Backward Compatibility”: Behaviour – Backward Compatibility is disabled and Behaviour – Backward Compatibility 6 is enabled, the state Joomla requires before you upgrade to 6.
    Joomla 5.4 Joomla Update component showing the Pre-Update Check for Joomla 6.1.4 with all required settings marked OK
    Joomla 5.4 Pre-Update Check screen (demo site) with the update channel set to Joomla Next. It offers Joomla 6.1.4, and every required setting passes, including the checks for both Backward Compatibility plugins.

    6. Common blockers and their replacements

    ExtensionStatusWhat to do
    K2JoomlaWorks announced K2 won’t be released for Joomla 4/5 (May 2024). There’s an unofficial community fork (K2ForJ4).Move K2 content to core articles while you’re still on Joomla 3 (see K2 to Joomla articles). Map extra fields to custom fields and add 301 redirects for changed URLs. For large sites, see our K2 migration service.
    sh404SEFJoomla 3-only; discontinued August 17, 2023.While you’re still on Joomla 3, install 4SEF (SEF URLs) and 4SEO (metadata, redirects) and use their sh404SEF import wizards. The imports need sh404SEF data on the site, so they must happen before the 3 → 4 migration.
    T3 Framework templatesBuilt for Joomla 3. JoomlArt’s current framework is T4, and there’s no direct conversion.Rebuild on a Joomla 5/6 template: T4, another maintained framework, or Cassiopeia with a child template. Budget it as a redesign, not a setting change.
    Helix3 templatesJoomShaper’s current framework is Helix Ultimate. It’s a separate framework, with no one-click upgrade from Helix3 (JoomShaper forum).Recreate the layout in Helix Ultimate on staging, then remove the Helix3 template and its plugins.
    ChronoForms v5/v6ChronoForms v8 supports Joomla 3 to 6 and requires PHP 8+.Install v8 alongside the old version on Joomla 3, rebuild or import forms, and test email and custom PHP actions before upgrading the core.
    JCommentsThe original is no longer developed. The community fork JComments 4 supports Joomla 4.2+ and 5, and a Joomla 6/PHP 8.3 beta has been released.Back up the _jcomments tables, uninstall v3 (your comments stay in the database), install the fork, then repair the database and reset permissions (steps in the fork’s README).
    VirtueMartVirtueMart 4.6.x supports Joomla 3.10, 4, and 5. VirtueMart’s developer says the unnamespaced 4.x line will never run on Joomla 6, and a namespaced VirtueMart 5 is in development/beta.Upgrade VirtueMart to the build for each target Joomla version before each core hop. For stores, 5.4 may be the sensible stopping point until a stable Joomla 6 VirtueMart release exists. Test checkout, payment, and shipping plugins every time. See VirtueMart upgrades.

    Verify each vendor’s status yourself on the day you start. This list reflects what we could confirm on September 30, 2026. When a site has two or more of these blockers, the extension work usually takes longer than the core upgrade. Plan for that, whether you handle it in-house or through a Joomla upgrade service.

    7. Fixing templates and layout overrides

    Joomla 4 replaced Bootstrap 2 and MooTools with Bootstrap 5 and the Web Asset Manager, so a Joomla 3 template, or an override copied across from one, will break layouts, module chrome, or the whole page.

    1. Isolate the template first. Set the site template to Cassiopeia. If the site renders correctly, the CMS is fine and the problem is your old template.
    2. Update commercial templates to the vendor’s release for your Joomla version (Helix Ultimate, T4, Gantry, and so on).
    3. Compare each override in templates/YOUR_TEMPLATE/html/ with the new core layout it replaces. Treat old overrides as rewrites, not file copies.
    4. For the 6.x hop, search overrides for patterns Joomla 6 removed. Items returned as stdClass break $item->get('title') (use $item->title), and $app is no longer available in plugin layouts (use $this->getApplication()). See the official removed and backward-incompatible list.
    5. Put your real template back only after you’ve clicked through the whole site.

    If an override stops applying after the upgrade, work through why Joomla template overrides stop working.

    8. Common errors and how to fix them

    What you seeUsual causeFix
    White screen or 500 error right after upgradingA PHP fatal error in an extension, template, or .htaccessRead the host error log and administrator/logs/joomla_update.php, then disable the extension named there. Don’t click Update again.
    Class "JTable", "JFactory", "JPlugin" or "JText" not foundThe backward compatibility layer is off. On Joomla 6, that’s Backward Compatibility 6 or its Classes Aliases settingEnable the plugin (using SQL if you’re locked out), then find and update the extension still using the old class names.
    Class "JRequest" not foundRemoved in Joomla 4; no compatibility plugin restores itThe extension code has to be rewritten to use the application input object.
    “Unknown column” or “table doesn’t exist”A database schema step didn’t finishSystem → Maintenance → Database → Update Structure.
    The next major version never appearsUpdate channel is still Default, or PHP is below the minimumSwitch to Joomla Next and meet the PHP minimum for the target version.
    Unstyled site, modules missingA Joomla 3 template or overridesSwitch to Cassiopeia to confirm, then update or replace the template.
    Homepage works but every other URL gives a 404 or 500.htaccess or URL rewriting mismatchRename .htaccess, turn off URL rewriting, rebuild from htaccess.txt, then re-add your custom redirects (mod_rewrite 500 fix).
    Login loopSession table, cookie domain, or $live_site settingEmpty #__session and confirm the site URL in Global Configuration.
    Download failed, out of memory, or the progress bar stallsUpdater transport or server limits, not compatibilityRaise the memory and time limits, or use Upload & Update. See how to fix Joomla update errors.

    For recovery SQL, schema repair when the Database screen shows nothing, and the full Joomla 6 removals list, use our Joomla upgrade issues runbook.

    9. Post-upgrade checks: SEO, redirects, and speed

    Once the final hop is on staging and working, check these before and just after go-live:

    • Functionality: homepage, login, registration, contact and other forms, search, checkout and payments, multilingual switching, ACL-restricted pages, and scheduled tasks (old cli/ scripts need rewriting as console commands on Joomla 6).
    • URLs: crawl the old site and the staging site with any SEO crawler, then compare. Every old URL should return 200 or a single 301 to its new equivalent. Pay special attention to K2 and sh404SEF URLs.
    • Redirects: a fresh .htaccess drops hand-written rules (www, HTTPS, legacy aliases). Use the core Redirect component or your server config for 301s. Our Joomla .htaccess guide covers the common rules.
    • Indexing signals: check the robots meta tags (staging is often set to noindex, and that setting sometimes goes live with the site), canonical tags, your XML sitemap, and structured data. Joomla 5 and 6 include a core Schema.org system plugin, so check it doesn’t duplicate markup from an SEO extension.
    • Search Console: submit the sitemap and watch Coverage and 404 reports for the first few weeks.
    • Speed: test key templates with PageSpeed Insights before and after, enable caching, and remove leftover jQuery or legacy assets you no longer need.
    • Security: remove unused extensions and old admin accounts, and make sure you’re on the latest 6.1.x or 5.4.x security release.

    10. Managing upgrades across many Joomla sites

    Agencies and IT teams with dozens of sites run into the same problem as the Stack Exchange question on managing updates for multiple sites: doing every site by hand doesn’t scale.

    • Standardize first. Group sites by Joomla version, template framework, and key extensions. Sites with the same stack can share one tested runbook.
    • Use a central dashboard for version and extension status and routine updates. Options include self-hosted Akeeba Panopticon and hosted services like Watchful or mySites.guru. Compare their current features, since this guide doesn’t endorse any of them.
    • Use the CLI where you can. Joomla 4 and later include a command-line tool (php cli/joomla.php) for checking and applying core updates, which fits scheduled or scripted maintenance. Keep major-version upgrades as a staging-first process per site.
    • Pilot, then batch. Upgrade the simplest site in each group first, record every fix, then roll out to the rest.
    • Track support dates. Put October 13, 2026 (end of Joomla 5 bug fixes) and October 12, 2027 (end of Joomla 5 security fixes) on the calendar for every Joomla 5 site you manage.

    For ongoing patching after the upgrade, see Joomla support and maintenance.

    11. DIY or hire help?

    You can reasonably do this yourself if:

    • The site runs mostly core Joomla and a few well-maintained extensions
    • Your host already supports PHP 8.3 and MySQL 8.0.13+ or MariaDB 10.6+
    • You’re comfortable restoring a backup and editing a database row

    Consider a professional Joomla upgrade if:

    • You’re still on Joomla 3 with K2, sh404SEF, a T3/Helix3 template, or custom components
    • The Pre-Update Check lists extensions you can’t replace
    • Disabling the Joomla 5 Backward Compatibility plugin breaks the site and you can’t find the cause
    • Two attempts have already left the database or the administrator broken
    • Checkout, memberships, or bookings bring in revenue and downtime costs money

    Whoever does the work, insist on the same things: a written extension plan, a tested backup, a staging site you can review, a redirect map, and a rollback plan.

    FAQ

    Can I upgrade Joomla 3 directly to Joomla 6?

    No. The supported path is 3.10 → 4.4 → 5.4 → 6.x. Joomla 6 only installs from 5.4, and each hop needs its own backup and Pre-Update Check.

    Should I stop at Joomla 5 or go all the way to Joomla 6?

    Go to Joomla 6 when your hosting runs PHP 8.3 and your key extensions have Joomla 6 builds. Stopping at 5.4 makes sense only as a temporary step (for example, while waiting for a stable Joomla 6 VirtueMart). Joomla 5 bug fixes end on October 13, 2026, and security fixes end on October 12, 2027.

    Is Joomla 4 still supported?

    No. Joomla 4’s security support ended in October 2025. The last release was 4.4.14.

    How long does a Joomla 3 to 6 upgrade take?

    It depends almost entirely on your extensions, templates, and custom code. A mostly core site can be done fairly quickly, while sites with K2, e-commerce, or custom components take much longer. Do an inventory before you commit to a timeline.

    Will upgrading Joomla hurt my SEO?

    Not if URLs are preserved or 301-redirected, robots and canonical settings are checked, and the sitemap is resubmitted. Most SEO losses come from changed K2 or sh404SEF URLs, or from a noindex setting carried over from staging.

    What’s the difference between a Joomla update and an upgrade?

    An update stays within one major version (for example, 6.1.3 → 6.1.4) and uses the Default update channel. An upgrade changes the major version (for example, 5.4 → 6) and needs the Joomla Next channel, a Pre-Update Check, and an extension review.

    Do I need the Backward Compatibility plugin?

    When going from 4.4 to 5, the Behaviour – Backward Compatibility plugin helps older extensions keep working. Before upgrading from 5.4 to 6, it must be disabled, and Behaviour – Backward Compatibility 6 must be enabled.

    Can I still use jUpgrade?

    No. It was built for Joomla 1.5-era migrations. The 3 → 4 → 5 → 6 path runs through the core Joomla Update component.


    Need a hand? If your site has blockers you’d rather not untangle yourself, our Joomla upgrade service handles the audit, staging, and each hop, with you signing off before anything goes live.

  • How to Disable Right Click in Joomla

    How to Disable Right Click in Joomla

    Disabling right click in Joomla means stopping the browser context menu on the public site so casual visitors cannot open “Save image as” or similar shortcuts in one click. On Joomla 3, 4, 5, and 6 the reliable way is a system plugin that injects the behaviour sitewide (or for images only) without editing the template. It is a soft deterrent, not real copy protection.

    This guide explains what the feature does, when it helps, how to turn it on with Right Click Disable from Infyways, and what still fails if you expect it to stop theft.

    What you will learn

    • What right-click disable blocks, and what it never blocks
    • How to disable right click in Joomla with the Right Click Disable plugin
    • Why a plugin beats pasting scripts into a commercial template
    • Images-only versus sitewide scope
    • UX, accessibility, and SEO trade-offs before you enable it

    What disabling right click does

    Browsers open a context menu on right click (and on some long-press gestures). A Joomla right-click plugin cancels that default menu on the front end. Official event behaviour is documented on MDN’s contextmenu page.

    Goal Plugin helps? Better approach
    Stop casual “Save image as” Partially Watermarks, low-res previews, licensed galleries
    Stop View Source / Inspect No Source is always available in the browser
    Stop scrapers and bots No Rate limits, firewall rules, non-public assets
    Reduce casual image grabs on a portfolio Often yes Combine with watermarking
    Protect paid downloads No Login walls and expiring file links

    Some browsers still offer ways around a cancelled menu (for example Firefox with Shift held while right-clicking). Mobile long-press menus vary. Treat the feature as a UX preference for galleries and content sites, not as security.

    Plugin versus custom code

    Approach Who it fits Risk
    Right Click Disable plugin Most site owners and agencies Low. Toggle in the administrator. Survives template updates
    Hand-edited template JavaScript Developers who own the whole template High. Commercial template updates wipe custom files. Easy to break the admin or forms
    Random “paste this in index.php” snippets Nobody long term Breaks on Joomla 4+ asset changes and child-template setups

    If you only need the outcome, use the plugin. Custom scripts belong in a maintained child template when you already have a developer on retainer, not as a substitute for an extension that is built, tested, and update-safe.

    Step 1: Decide the scope

    1. Whole site: every public page loses the context menu. Avoid this on heavy form or SaaS-style sites.
    2. Images and media: visitors keep normal menus on text and links. Best default for portfolios and magazines.
    3. Selected sections: only a gallery or a protected category. Use when the rest of the site should stay normal.

    Pick the narrowest scope that solves the complaint you actually get (usually image saving).

    Step 2: Install Right Click Disable

    1. Get the package from the Joomla Extensions Directory listing or your JoomlaX download area. Live behaviour: Right Click Disable demo.
    2. In the administrator open System → Install → Extensions (Joomla 4, 5, 6) or Extensions → Manage → Install (Joomla 3).
    3. Upload and install the ZIP.
    4. Open System → Plugins (or Extensions → Plugins on Joomla 3).
    5. Search for Right Click Disable and open it.
    6. Set Status to Enabled.
    7. Enable Disable Right Click. Choose images-only or related options if your build offers them.
    8. Save & Close.
    9. Clear Joomla cache, then test the public site in a private window.

    Confirm /administrator/ still has a normal context menu. The plugin is meant for the site front end. If the admin UI is affected, disable the plugin and contact support with your Joomla version.

    Step 3: Configure for your content type

    • Portfolio / photography: prefer image-focused protection so writers and clients can still use browser menus on text.
    • Brochure marketing site: sitewide can be acceptable if you have few forms.
    • Membership or course site: do not use right-click disable as the paywall. Protect files on the server.
    • Multilingual: enable once. The front-end script applies per page load, not per language pack.

    Step 4: Test before you call it done

    1. Right-click a paragraph and an image. Confirm the scope you chose.
    2. Open a contact or login form. Confirm paste and browser tools still feel usable.
    3. Check Chrome, Firefox, Edge, and Safari, plus one phone long-press.
    4. Clear CDN cache if the old page without the script is still served.

    Why template hacks fall apart

    Forum snippets that dump JavaScript into index.php or a random module chron look easy. They fail when:

    • You update Helix, T4, Gantry, or another commercial template and lose the edit
    • Joomla 4+ expects assets through the Web Asset Manager, not ad-hoc script tags
    • The script also runs in the administrator and blocks your own workflow
    • A cache or optimisation extension reorders scripts and the listener never binds

    A dedicated system plugin is built for those edges. That is the product Infyways maintains on JED so agencies do not babysit template forks for a five-line behaviour.

    Accessibility, UX, and SEO

    • Accessibility: some people use the context menu for browser features. Prefer images-only when you can.
    • UX: silent blocking beats an alert on every click.
    • SEO: crawlers do not need the context menu. Enabling or disabling right click does not move rankings by itself. Content quality still does.
    • Legal: watermarks and copyright notices matter more than this feature.

    When to skip right-click disable

    • Documentation hubs and apps full of forms
    • Products that teach “right-click to download”
    • Any pitch that this “secures” paid media. Use authentication instead

    Need the plugin installed on a client site, wired to a gallery, or bundled in a white-label stack? Infyways can handle that under Joomla plugin development or contact us.

    Key takeaways

    1. Right-click disable is a soft deterrent for casual copying, not security.
    2. Use Right Click Disable for a maintained, toggleable solution on Joomla 3 through 6.
    3. Prefer images-only when the complaint is photo theft.
    4. Avoid pasting one-off scripts into commercial templates.
    5. Test the administrator and forms after enabling.
    6. SEO neither rewards nor punishes this feature on its own.

    Frequently asked questions

    How do I disable right click in Joomla?

    Install and enable the Right Click Disable system plugin, set Disable Right Click to Yes, clear cache, and test the front end.

    Does disabling right click protect my images?

    Only against casual use. Anyone can still download images from the page source, a screenshot, or the image URL.

    Does Right Click Disable work on Joomla 5 and Joomla 6?

    Yes. Use a current package from JED or JoomlaX that lists your Joomla major.

    Can I disable right click on images only?

    Yes, when the plugin options (or your project brief) include image-focused mode. That is usually better than a sitewide block.

    Will this hurt SEO?

    No. Search engines do not use the context menu. Rankings still depend on content and technical SEO.

    Why not paste JavaScript into the template instead?

    Because template updates overwrite custom edits, and sitewide scripts are easy to mis-scope into the administrator. A system plugin is the durable approach.

    Where do I download Right Click Disable?

    From the Joomla Extensions Directory or the Infyways / JoomlaX download linked from that page. Try the live demo first.

  • Remove the Joomla Generator Meta Tag

    Remove the Joomla Generator Meta Tag

    The Joomla generator meta tag is a single line in the HTML head, <meta name="generator" content="Joomla! - Open Source Content Management">. Joomla adds it in the document class. There is no switch for it in Global Configuration on Joomla 3, 4, 5, or 6. Remove it with setGenerator('') before the head is rendered, or with a system plugin. An empty string omits the tag. null is the wrong value and can fatal on PHP 8.

    The tag does not contain your version number. Removing it does not change Google rankings. It only drops one fingerprint. RSS feeds, the administrator login page, and administrator/manifests/files/joomla.xml still identify the CMS unless you handle those separately.

    What you will learn

    • The exact tag Joomla prints, and why it is not a version number
    • How to see it in HTML and in RSS
    • The template one-liner, and why it disappears on the next template update
    • Why setGenerator(null) is unsafe
    • What still gives the site away after the tag is gone

    What the tag is

    HTML’s generator meta names the software that built the page. Joomla sets that string when it creates the HTML document. It is not read from a menu item, not stored in the database, and not a language string you can override. The same property is written into RSS and Atom as a <generator> element.

    On current Joomla 3.10, 4, 5, and 6 the content is only:

    <meta name="generator" content="Joomla! - Open Source Content Management">

    Very old releases (Joomla 1.5 and early 2.5) put the version in that string. That stopped years ago. If a scanner claims it learned “Joomla 3.9.28” from this meta tag, it learned it somewhere else.

    What removing it does, and what it does not

    Claim Reality
    Hides the Joomla version from attackers The version is not in this tag. It is in administrator/manifests/files/joomla.xml and in the administrator’s System Information screen
    Improves Google rankings No. Google does not use meta name="generator" as a ranking signal
    Hurts SEO No, as long as you do not also delete the robots meta tag
    Makes the site invisible to scanners No. /media/system/js/core.min.js, /administrator/, and Cassiopeia paths still look like Joomla
    Removed by a Joomla or template update if you only edited index.php Yes. A template update replaces that file
    Removed from RSS if you only call setGenerator inside <head> after the head include No. Feeds never render that head block

    Treat this as housekeeping, not as a security patch. An outdated Joomla site with the tag removed is still outdated. Update path: how to update Joomla.

    Step 1: See the tag before you change anything

    1. Open the public homepage.
    2. View source (not only the inspector). Search for generator.
    3. You should find the meta line above. Joomla 3 often writes it self-closed (/>). Joomla 4 and newer usually do not.
    4. Open the feed: add ?format=feed&type=rss to the site URL, or use the RSS link in the page. Search for <generator>. The same sentence is there.
    5. Optional: open /administrator/ and view source. The login page carries the tag too.

    If the line is missing already, a plugin or the template is stripping it. Do not add a second strip until you know which one.

    Step 2: Prefer a plugin over a template edit

    A system plugin runs on every HTML and feed response and survives template updates. Infyways publishes Remove Meta Generator for this. Version 1.4 is for Joomla 4, 5, and 6. It clears or replaces the generator on the public site, can clean RSS and Atom, and can drop the X-Powered-By header. It does not touch the administrator. Listing: Joomla Extensions Directory.

    1. Install the zip and enable System – Remove Meta Generator.
    2. Set generator to remove, or replace it with your own brand text if you want a tag with different content.
    3. Leave the robots option alone unless you have a reason to change indexing. Deleting meta name="robots" can drop a noindex you still need, or strip a normal index directive.
    4. Clear Joomla cache and any CDN cache.
    5. View source on the homepage and on one article. Then check the RSS feed.

    Joomla 3 is not a target of the 1.4 build. On 3.10 use the template line in the next step, or stay on a plugin build that still lists Joomla 3.

    Step 3: Or set an empty generator in the template

    This works on Joomla 3, 4, 5, and 6. In templates/YOUR_TEMPLATE/index.php, before <jdoc:include type="head" /> and before <jdoc:include type="metas" />:

    <?php
    $this->setGenerator('');
    ?>

    Use an empty string. Do not pass null. The document API types setGenerator as a string. On PHP 8 a null argument becomes a fatal once that type is enforced. An empty string is what makes the renderer skip the tag. Joomla only prints the meta when getGenerator() is non-empty.

    Put the line at the top of the file if you are unsure. Code after the head include is too late: the meta block has already been built.

    A template update overwrites index.php. Put the line in a child template, or use the plugin. Do not edit libraries/src/Document/HtmlDocument.php or libraries/joomla/document/html/html.php. The next Joomla update puts the tag back and can break the core file.

    Step 4: Cover feeds, not only the homepage

    The template line never runs for format=feed. A plugin event does. This is the body of a system plugin method. On Joomla 3.8 and newer, and on 4, 5, and 6, Joomla\CMS\Factory is available without the compatibility plugin:

    public function onBeforeRender()
    {
        $app = Factory::getApplication();
    
        if (!$app->isClient('site')) {
            return;
        }
    
        $doc = $app->getDocument();
        $type = $doc->getType();
    
        if ($type !== 'html' && $type !== 'feed') {
            return;
        }
    
        $doc->setGenerator('');
    }

    onBeforeRender is early enough for HTML and for RSS. onBeforeCompileHead is HTML-only, so a head-only hook leaves the feed element in place. Skip non-HTML types such as JSON and raw so you do not touch component output that is not a document head.

    On Joomla 3.7 and older, swap Factory::getApplication() for JFactory::getApplication() and isClient('site') for isSite().

    Step 5: Confirm it is gone, including cache

    • View source on the homepage, an article, and a category blog.
    • Search for name="generator". No match means the Joomla tag is gone. A match with different content means a template or extension hardcoded its own tag. setGenerator will not delete a string that was echoed by hand. Search the template for generator and remove that line.
    • Open the RSS URL and confirm there is no <generator>Joomla! element, if you used the plugin or onBeforeRender.
    • Clear System → Maintenance → Clear Cache, then the host cache or Cloudflare, or you will keep seeing the old HTML.
    • Check /administrator/ only if you intended to change it. The JoomlaX plugin leaves admin pages alone on purpose.

    Other fingerprints people confuse with this tag

    Signal What it is Removed by setGenerator?
    meta name="generator" HTML fingerprint, no version Yes, if you set an empty string in time
    RSS <generator> Same property, feed renderer Only if the call runs for feed documents
    X-Powered-By: PHP/x.y Server header, not Joomla’s meta tag No. Turn it off in PHP or in the plugin’s header option
    administrator/manifests/files/joomla.xml Core manifest, includes the version No. This file is the real version leak
    /media/system/js/core.min.js and /administrator/ Paths and the login screen No
    meta name="robots" Indexing instructions Should stay. Unrelated to the generator

    Blocking the manifest is a hosting or Admin Tools job, not a meta-tag job. Hiding files is still weaker than installing updates. If the site is on Joomla 3, plan the move instead of collecting hide-the-CMS tricks: Joomla upgrade services.

    SEO

    Removing the generator tag does not move rankings. Google indexes the visible page, links, and a handful of meta tags it actually reads (description, robots). generator is not one of them. More on what does matter: Joomla SEO.

    The change that does hurt SEO is a plugin option that deletes every robots meta. Leave that control on “leave” unless you are setting a specific policy, such as index, follow on purpose.

    Key takeaways

    1. The tag says Joomla. It does not say which version.
    2. There is no Global Configuration checkbox. Use setGenerator('') or a plugin.
    3. Never pass null. Never edit files under libraries/.
    4. A template edit dies on the next template update and never touches RSS.
    5. Removing the tag does not change SEO. Do not remove the robots meta while you are there.
    6. Update Joomla. Hiding the tag is not a substitute.

    Frequently asked questions

    How do I see the Joomla generator meta tag?

    View source on the homepage and search for generator. The default content is Joomla! - Open Source Content Management. The same text is in the RSS <generator> element.

    How do I remove the Joomla meta generator from the head?

    Call $this->setGenerator('') in the template before the head include, or enable a system plugin that does it on onBeforeRender. Empty string, not null.

    Will removing the generator tag affect SEO?

    No. Google does not use that meta tag for ranking. Leave meta name="robots" in place.

    Does this tag reveal my Joomla version?

    Not on Joomla 3.10, 4, 5, or 6. The version is in administrator/manifests/files/joomla.xml, not in the generator meta.

    Does Joomla 5 or 6 still add the tag?

    Yes. There is still no core switch. The same setGenerator('') call works, or use Remove Meta Generator 1.4.

    Will a Joomla update put the tag back?

    A core update does not restore a plugin setting. A template update does restore index.php if you edited the parent template. Core file hacks under libraries/ are overwritten.

    Does the template line remove it from RSS?

    No. Feeds do not load index.php. Use onBeforeRender or a plugin that cleans feed output.

    Is setGenerator(null) safe on PHP 8?

    No. Pass an empty string. Null does not match the string argument and can fatal.

    Can I remove it without editing files?

    Yes. Install Remove Meta Generator, enable it, clear cache, and view source.

  • Fix Call to a member function setState() in Joomla

    Fix Call to a member function setState() in Joomla

    Call to a member function setState() on null (also “on bool”, “on boolean”, or “on a non-object”) means Joomla tried to call setState() on a model that was never created. getModel(), JModelLegacy::getInstance(), or createModel() returned false or null, and the next line did not check. This is not a session error, and clearing the cache does not create the missing class.

    The line that dies is almost always a content module or an old component controller preparing a list query. The fix is to load the model, or to update or disable the extension named in the stack trace.

    What you will learn

    • What setState() does on a Joomla model, and why this is not React and not the session
    • Why the same bug is worded three different ways on PHP 7 and PHP 8
    • How to read the file path and name the extension in one minute
    • The Joomla 3 include-path failure, and the Joomla 4, 5, and 6 bootComponent() pattern
    • What to do when the administrator will not open

    What the error actually means

    Joomla list screens do not read $_GET inside the query. They park filters on the model first:

    $model->setState('filter.published', 1);
    $model->setState('list.limit', 5);
    $model->setState('params', $params);
    $items = $model->getItems();

    setState() only exists on a model object (ListModel, BaseDatabaseModel, and the older JModelLegacy). If $model is false or null, PHP stops with a fatal error before getItems() runs. The message changes with the PHP version, not with the bug:

    What PHP says What $model is Typical PHP
    on a non-object false from getInstance() or getModel() PHP 5
    on boolean Same false PHP 7
    on bool Same false PHP 8 and newer
    on null createModel() found nothing PHP 7.0+ and Joomla 4+

    A different sentence, Call to undefined method ... setState(), means you do have an object, but it is the wrong class. Do not mix those up. This article is only the null or false case.

    This is not the session, and it is not React

    Session data in Joomla is $app->setUserState() and getUserState(). Deleting files in /tmp, logging out, or emptying #__session does not make getModel() return an object. Do that only when the error text actually names the session handler.

    React’s setState() is a JavaScript method on a component. A PHP fatal in a .php file under modules or components has nothing to do with a React build. If the stack trace is a .js bundle, you are in a different app that happens to be hosted beside Joomla.

    Where it breaks

    Path in the error What failed Fix
    modules/mod_articles_latest, mod_articles_category, mod_articles_news, mod_related_items The articles model was not booted before setState('params') Use the core helper pattern below, or replace a cloned module
    components/com_SOMETHING/controller.php or controllers/cpanel.php $this->getModel() returned false, then the controller called setState anyway Update that component. Pass the model name. Check the return value
    administrator/components/com_SOMETHING Same failure, backend only Disable that admin component. The public site can stay up
    libraries/legacy/controller or libraries/src/MVC/Controller Core ran. The component in the URL did not provide a model Read option=com_... in the URL. Fix that extension, not the library
    templates/YOUR_TEMPLATE/html An override copied an old helper Compare it with the current core file and drop the stale copy

    The classic core case was Joomla 3.5.0: mod_related_items/helper.php line 44 called setState() on false because com_content models were not on the lookup path. That was fixed in 3.5.1. The report is still the best illustration of the bug: Related Articles module fatal error. Third-party modules still copy the broken pattern.

    Step 1: Get the file and the line

    1. If the page is a blank 500, open the host PHP error log or administrator/logs/. The fatal is one line: message, file, line number.
    2. On a staging copy you can set Global Configuration → Server → Error Reporting to Maximum. Turn it off again on production. Do not leave display_errors on a public site.
    3. Copy the first fatal only. Later errors are fallout.
    4. A white page with no setState text may be .htaccess instead. Check that only after the log is silent. Guide: Joomla 500 on mod_rewrite.

    Step 2: Confirm the variable is empty

    Open the file at the line number. You want a call shaped like one of these:

    • $model->setState(
    • $this->getModel()->setState(
    • $defaultModel->setState(

    Look up three to ten lines. The assignment is getInstance, getModel, or createModel. There is no if (!$model) before setState. That missing check is the crash. Adding a return when the model is empty stops the fatal. It does not by itself bring the module back. You still have to make createModel succeed.

    Step 3: Name the extension from the path

    • mod_ prefix: a module. Unpublish that module to confirm the homepage returns. System → Manage → Extensions, or published = 0 on that row in #__modules if you cannot log in.
    • com_ prefix: a component. The menu item or the URL option= is what triggers it. Note the folder name before you disable anything.
    • plg_ or plugins/: a plugin. Rename that plugin’s folder over FTP if the administrator is already dead.
    • Path contains libraries/joomla or libraries/src and your Joomla version is current: core is the messenger. The broken model belongs to the component in the request.

    Take a backup before you rename folders or edit PHP. Method: how to backup a Joomla website.

    Step 4: Load the articles model the way core does now

    On Joomla 4, 5, and 6, article modules boot the component, then set state. This is the current core pattern in Latest Articles:

    $model = $app->bootComponent('com_content')
        ->getMVCFactory()
        ->createModel('Articles', 'Site', ['ignore_request' => true]);
    
    if ($model === null) {
        return [];
    }
    
    $model->setState('params', $app->getParams());
    $model->setState('filter.published', 1);
    $model->setState('list.limit', (int) $params->get('count', 5));

    $app is Factory::getApplication(). ignore_request stops the model from reading the page URL as its own filters, which is what you want inside a module. Core reference: ArticlesLatestHelper.php.

    If createModel still returns null, com_content is missing, half-updated, or the model name is wrong. Reinstalling random core files is not the first move. Confirm components/com_content exists and that System → Maintenance → Database shows no schema errors. A partial update leaves new PHP calling old tables, or the reverse. Update path: update Joomla and fix update errors.

    Step 5: Fix the Joomla 3 version of the same bug

    Joomla 3 will not boot a component. You add the model folder, then ask for the class prefix ContentModel:

    JModelLegacy::addIncludePath(
        JPATH_SITE . '/components/com_content/models',
        'ContentModel'
    );
    
    $model = JModelLegacy::getInstance(
        'Articles',
        'ContentModel',
        array('ignore_request' => true)
    );
    
    if (!$model) {
        return array();
    }
    
    $model->setState('params', $params);

    The file on disk must be components/com_content/models/articles.php and the class must be ContentModelArticles. A renamed class returns false from getInstance, and the next setState is this fatal.

    Do not paste the Joomla 3 block into Joomla 4, 5, or 6. JModelLegacy is legacy. On current Joomla the failure mode changes: either the class is missing (see class not found after an upgrade) or getInstance returns false and you are back to setState() on bool. Use bootComponent().

    Step 6: Update or disable the extension in the trace

    If the file sits in a commercial component, you cannot invent its model name from the articles example. The controller is calling $this->getModel() with no name, the default model file is gone or not autoloaded after a Joomla 3.10 or Joomla 4 hop, and setState runs on false. That is an extension bug.

    • Update it to a build that lists your Joomla major.
    • If there is no update, disable it and unpublish its modules and menu items.
    • Do not edit libraries/ to hide the message. The next core update overwrites the library and the fatal returns.
    • A template override of a module helper is a copy. Delete the override and let the current module file run. Then retest.

    Major-version breakage of this kind is covered in Joomla upgrade issues. Hop order still matters. A Joomla 3 controller will not start loading models correctly just because the site folder was copied onto Joomla 5.

    Step 7: Clear cache after the page renders

    Module HTML is often cached. A cached fatal, or a cached empty module, can linger after you fix the PHP. Clear it only once the uncached page works:

    1. System → Maintenance → Clear Cache, or the cache button on the module.
    2. Clear the host or CDN cache if the HTML is stored there.
    3. Reload the page that crashed. The log line for setState should be gone.

    If you clear cache first and the model is still null, the error comes straight back. Cache was never the cause.

    Step 8: Get the administrator back

    1. Read the log. If the path contains /administrator/components/com_ or /plugins/, rename that one folder via FTP or the host file manager. Joomla skips an extension whose folder is missing.
    2. If a site module crashes every admin page because it is assigned to the admin menu, unpublish it in #__modules (published set to 0). Match module to the mod_ name from the log.
    3. Leave com_content, com_users, and com_login in place. Renaming those locks you out for a different reason.
    4. When the administrator loads, update or uninstall the extension properly, then restore the folder name only if you still need it.

    What a correct call looks like

    Core always sets state after it knows the model exists. The states you will see in article modules are the query, not user session keys:

    • params: component or module parameters
    • filter.published, filter.category_id, filter.access, filter.language, filter.featured
    • list.start, list.limit, list.ordering, list.direction

    If your code sets those on a model that failed to load, fix the load. If your code sets them on $app, you wanted setUserState() and you are in the wrong API.

    When to stop patching the module

    Stop if any of these are true:

    • The trace names a component you cannot update, and the site still runs Joomla 3
    • Several modules fatal with the same createModel null after a half-finished upgrade
    • You already renamed folders and you are not sure which ones the business needs

    Infyways runs those repairs and version jumps from $149, with a compatibility audit within 12 hours. Start at Joomla Upgrade Services.

    Key takeaways

    1. setState() on null or bool means the model object was never created.
    2. It is not the session, not React, and not fixed by emptying /tmp.
    3. The file path is the extension name. Start there.
    4. Joomla 4, 5, and 6 load article models with bootComponent('com_content') and createModel('Articles', 'Site').
    5. Joomla 3 needs addIncludePath plus ContentModelArticles. Check getInstance before setState.
    6. Clear cache after the page renders, not before.

    Frequently asked questions

    What does Call to a member function setState() mean in Joomla?

    PHP called setState() on null or false. In Joomla that value was supposed to be a model from getModel(), getInstance(), or createModel().

    Is this a session or login error?

    No. Session storage uses setUserState(), which is a different method. Logging out or deleting /tmp does not load a missing model.

    Why does it say on bool on one site and on null on another?

    Same failure. getModel() and getInstance() return false, so PHP 8 says “on bool”. createModel() returns null, so PHP says “on null”.

    Which file should I open?

    The file and line in the error. That line is the setState call. The extension folder in that path is what you update or disable.

    Will Clear Cache fix it?

    No. Clear cache only after the model loads, so Joomla does not keep serving a cached copy of the crash.

    Does Joomla 5 or 6 still use setState()?

    Yes. Article modules still call $model->setState() after createModel('Articles', 'Site'). The method is fine. A null model is not.

    Can I fix it by reinstalling Joomla core?

    Only when the trace points at a core file that does not match a stock copy of your version. If the path is a third-party component, reinstalling core leaves the bug in place.

    The administrator is a white screen. How do I get in?

    Rename the plugin or admin component folder named in the log. Do not rename com_login or com_users. Unpublish a site module from #__modules if that module is what crashes.

    Who can fix setState() fatals across an upgrade?

    Infyways traces the model load and finishes the version jump when the extension has no update. Request a Joomla upgrade audit.

  • Joomla Module Not Showing: Complete Troubleshooting Guide

    Joomla Module Not Showing: Complete Troubleshooting Guide

    A Joomla module is not showing when the module row is not allowed to render for that request: Status is not Published, Access or Language excludes the visitor, Menu Assignment is No pages (or the ticks do not include this Itemid), publishing dates are outside now, or cache still holds an empty slot. A Note in the module list is not a status. This article is that checklist. It is not position wiring (name vs jdoc). It is not “the module appears, but on the wrong pages.”

    If Status, Access, Language, Assignment, and dates are already correct and the region is still empty on every page that uses this template, stop here and open Joomla module position not showing. If the module shows, just not where you meant, open Joomla module showing on the wrong pages. Official assignment help: How do you assign a module to specific pages? and Module display by menu item. Site module overview: Site Modules.

    Unpublished status, access lock, publishing dates, and language

    Published is not enough. Access, Language, Menu Assignment, Start and Finish dates, and cache each get a veto. A Note in the list is only an admin reminder.

    What you will learn

    • How to read Status versus the Note column
    • Why a Super User still “proves nothing” until you test as a guest
    • What Menu Assignment No pages does (without the full wrong-pages deep dive)
    • How Language Filter hides a module that is Published
    • How Start Publishing and Finish Publishing hide a Published module
    • When module cache or Page Cache makes a fixed module look missing
    • When to hand off to the position article (and when not to)
    What you see Likely cause Wrong rabbit hole
    Missing everywhere, including Home Unpublished, Trashed, No pages, dates, or Access Reinstalling the module type
    Missing for guests, visible when you are logged in Access is Registered (or higher) Position names
    Missing in one language Module Language is not All / not that language CSS
    Missing only after a date you set Finish Publishing passed, or Start is still in the future Cache only
    You “fixed it,” guests still see empty Page Cache or Progressive module cache Editing index.php
    Empty slot, ?tp=1 shows the position name Position wiring or chrome/CSS This article’s Status toggles
    Module HTML in View Source, invisible on screen Chrome or CSS Publishing dates

    Step 1: Confirm Status is Published (Note is not Status)

    System → Site Modules. Filter carefully. Administrator modules are a different list (Administrator Modules). A login module you edited in the backend list will never appear on the site.

    Open the module you think is missing. Status must be Published. Unpublished and Trashed do not render. A yellow or grey icon in the list is easy to miss if you sorted by Note.

    The Note field (Administrator Note) is a private reminder in the module list. It does not publish anything. It does not unpublish anything. Operators scan the Note column, see a comment such as “hold” or “old,” and assume Joomla unpublished the row. Read the Status column, then the module header Status dropdown.

    Also check you are not editing a Save as Copy draft. Two rows, same title, one Published on Home, one Unpublished. The frontend uses the published id. Confirm the id in the URL (id=) matches the row you intend.

    If Status is Published and you still see nothing, do not toggle it twice “to refresh.” Leave it Published and continue.

    Step 2: Match Access to the visitor you are testing

    Access is a veto.

    • Public: guests can see it (if every other check passes).
    • Guest: logged-in users may not see it (depending on your ACL). Super Users testing while logged in will swear the module is missing.
    • Registered and above: guests will not see it. That is correct ACL, not a bug.

    Test a private window logged out if the module should be public. Test a registered account if it should be members-only. Do not debug Access while logged in as Super User unless you also check a guest.

    ACL background: Access Control List and the user manual Access Control.

    If the site is multilingual, Access still applies per request. Language is a separate veto (Step 4).

    Step 3: Rule out Menu Assignment of No pages

    Open Menu Assignment.

    If Module Assignment is No pages, the module never renders. That looks identical to Unpublished on the frontend. Set it to On all pages for this diagnosis, save, retest one URL. If it appears, Assignment was the veto. Then set the real map using module showing on the wrong pages. Do not rebuild that whole Itemid article here.

    If Assignment is Only on the pages selected and the tree has no ticks (or only a hidden-menu item you are not visiting), the module is effectively No pages. Expand: All. Confirm the item for the URL you have open is ticked.

    If Assignment is On all pages and the module is still missing everywhere, Assignment is not the problem. Continue. If it is missing on some URLs and present on others, you are on the wrong-pages article, not this one.

    Default for a new module is often On all pages. Copies inherit whatever the original had, including No pages from a test.

    Step 4: Set Language to All, or to the language of the page

    Language on the module must be All, or the same language as the page Joomla is serving.

    With System – Language Filter published, a module set to English is omitted on the French page even when Status is Published and Assignment includes that menu item. That is Language Filter doing its job.

    Test:

    1. Set Language to All. Save. Clear cache. Retest.
    2. If you need per-language modules, duplicate the module (Save as Copy), set each copy’s Language, and assign each to the matching menu items. Do not expect one English module to print on every language.

    Site vs Administrator language packs do not apply here. This is the module’s Language field on Site Modules.

    Step 5: Check Start Publishing and Finish Publishing

    Open the Publishing tab.

    • Start Publishing in the future: Status can say Published. The module still waits. Site timezone is Global Configuration, not your laptop clock.
    • Finish Publishing in the past: the module has expired. Published-looking rows still vanish.
    • Empty dates: no date veto.

    A campaign module you scheduled last quarter will “randomly” disappear on the Finish day. That is not cache and not a template update.

    If you use scheduled tasks or a workflow elsewhere, they do not replace these two fields. Read the Publishing tab on the module itself.

    Step 6: Clear module cache and Page Cache after a real fix

    Once Status, Access, Assignment, Language, and dates are correct, an empty guest page can still be yesterday.

    1. System → Maintenance → Clear Cache. If that does nothing, the handler may be Redis: Joomla cache not clearing.
    2. Module Advanced → Caching. A cached empty output can survive your publish click until the cache key expires. Set to No caching on staging to prove it, then put a sane cache back.
    3. System – Page Cache: guests get a full HTML snapshot from before the module was published. Logged-in Super Users skip it and think the site is fine. Test a private window. Layers: cache showing old content.

    Progressive System Cache is aggressive about module combinations. If a module “won’t come back” after you publish it, Progressive plus Page Cache is a usual pair. Conservative is enough for most sites.

    Do not “fix cache” by deleting cache/ in FTP when Cache Handler is Redis.

    Step 7: Only then ask whether the position exists

    If every check above passes and View Source still has no module HTML on a page that should include it:

    • The position string may not exist on this template (position-7 on Cassiopeia, or a name with no jdoc). That is module position not showing.
    • The menu item may use a different template style whose index.php never includes that position. Still a position/style problem, not Status.

    If View Source has the module HTML, the module showed. Chrome, CSS, or a script hid it. CSS: Joomla CSS changes not showing. JS emptying the node: Joomla JavaScript not working.

    Do not add a jdoc to parent Cassiopeia to “make it show.” Extra positions belong on a child template. Safe file rule: customize without editing core.

    Custom HTML inside the module that looks stock is an override or chrome issue, not unpublished: template override not working.

    Five checks: published, access, assignment and language, cache, dates and note

    Status, then Access, then Assignment plus Language, then cache, then dates. Treat Note as a label, not a switch. Position wiring is a later article.

    Key takeaways

    1. A Joomla module is not showing when a veto failed: Status, Access, Language, Menu Assignment, dates, or cache. Note is not a veto.
    2. Test as a guest in a private window. Super User Access proves little for Public modules.
    3. No pages (or Only-on-selected with no ticks) looks like Unpublished on the frontend.
    4. Language Filter hides modules whose Language is not All and not this page’s language.
    5. Start Publishing in the future and Finish Publishing in the past hide a Published row.
    6. Page Cache and module cache keep an empty guest page after you fix the row.
    7. Position name vs jdoc is module position not showing. Wrong URLs are wrong pages.
    8. Do not edit core index.php to compensate for Unpublished.

    Frequently asked questions

    Why is my Joomla module not showing?

    Status is not Published, Access or Language excludes the visitor, Menu Assignment is No pages or unticked, Start or Finish dates hide it, or cache still has the empty page. Check those before you touch the template.

    What is the difference between a Note and Unpublished?

    Note is an administrator reminder in the module list. Unpublished is Status. Only Status (and dates, Access, Language, Assignment) control the frontend.

    Should I fix the template position first?

    Only after this list passes. If the module is unpublished, a perfect jdoc still prints nothing. Position wiring is Joomla module position not showing.

    Why do I see the module when logged in but guests do not?

    Access is not Public, or Page Cache is serving guests an old empty HTML page. Test a private window after Clear Cache.

    Can Language hide a published module?

    Yes. With Language Filter on, a module set to one content language is omitted on the other. Set Language to All to prove it.

    The module shows on Home but not on Contact. Is that this guide?

    That is Menu Assignment / Itemid. Use Joomla module showing on the wrong pages. This page is for modules that show nowhere (or nowhere for that visitor).

    Where are the official module assignment docs?

    How do you assign a module to specific pages? and Module display by menu item.

    Conclusion

    When a Joomla module is not showing, read the module row like an operator: Published, Public (or the Access you intend), Assignment that is not No pages, Language All or matching, dates that include now, then cache. Ignore the Note column as a status. If that list is clean and the slot is still empty, the position name or the template style is next: module position not showing. If the module is visible on the wrong URLs, that is wrong pages.

    If production has copies, languages, and Page Cache stacked, Joomla support and maintenance is faster than toggling Status. Layout and chrome work: Joomla design services.

  • How to Update Joomla and Fix Update Errors

    How to Update Joomla and Fix Update Errors

    Updating Joomla to the latest version means applying the official update package through System → Update → Joomla (older sites: Components → Joomla Update). A Joomla update error is almost always one of four failures: the update server cannot be reached, PHP runs out of memory or time while downloading the ZIP, files cannot be extracted because of permissions, or the database schema is left behind after files change. Major jumps (3 to 4, 4 to 5, 5 to 6) are upgrades, not one-click patches, and need a staging plan.

    This is the Infyways runbook for Joomla 4, 5, and 6. It covers the clean update path, every common error, the manual Upload & Update fallback, and when to stop and hire a migration instead of forcing Live Update.

    What you will learn

    • How to update Joomla to the latest version inside the same major (5.4.x to 5.4.y, or 6.1.x to 6.1.y)
    • Why a next major does not appear until you switch the update channel
    • How to read administrator/logs/joomla_update.php so you stop guessing
    • Fixes for download failures, out of memory, timeouts, extract errors, and database schema lag
    • The Upload & Update method when the host blocks outbound HTTPS

    Update vs upgrade: do not mix them

    A Joomla update stays inside one major version. Example: 5.4.2 to 5.4.3, or 6.1.1 to 6.1.2. The built-in updater is the right tool.

    A Joomla upgrade changes the major number: 3 to 4, 4 to 5, or 5 to 6. Extensions, PHP, and templates can break. Do that on a staging copy with a tested backup. Our Joomla upgrade service is for that job. This article is for the updater itself and the errors it throws.

    Goal Update channel Where
    Latest patch of your current major Default System → Update → Joomla
    Next major (for example 5.4 to 6) Joomla Next Same screen, Options, then Pre-Update Check
    Updater cannot download the ZIP Either Download the official update package and use Upload & Update
    Joomla 3 or heavily customized site Do not force one click Staged migration. See Joomla 3 to 6 path

    Official references: Updating from an existing version and Joomla Update problems.

    Step 1: Confirm the installed version and the target

    1. Log into the administrator.
    2. Open System → Update → Joomla. If that menu is missing, see the FAQ below (rebuild menus, or look under Components on very old builds).
    3. Note the installed version and the version Joomla offers.
    4. Open System → System Information and record PHP version, database type, and memory limit.

    If the offered version is only a patch and Pre-Update Check is green, continue. If you expected Joomla 6 and only see 5.4.x, you are still on the Default channel. That is not a bug.

    Step 2: Back up files and the database

    Do not click Start Update on a production site without a restorable backup. Use Akeeba or a host snapshot, then keep one copy off the server. Full method: How to backup a Joomla website.

    If the update dies halfway, restore first. Debugging a half-written core is slower than a clean restore.

    Step 3: Check the server before the download

    • PHP memory: sites have failed updates at 96 MB and succeeded at 192 MB. Set memory_limit to at least 256M before a core update.
    • Time: raise max_execution_time (120 seconds or more). Shared hosts also kill long PHP-FPM requests.
    • Upload limits (needed for the manual ZIP path): upload_max_filesize and post_max_size above the package size (often 20 to 40 MB, sometimes larger).
    • Writable paths: tmp/, administrator/logs/, and the site root must be writable by PHP.
    • Outbound HTTPS: the server must reach https://update.joomla.org (and historically GitHub CDNs used by the update infrastructure). Firewalls that block outbound HTTPS cause “failed to download” with a healthy admin.
    • Disk space: leave room for the ZIP plus extracted files. A full disk looks like a random extract error.

    Step 4: Set the update channel

    1. On the Joomla Update screen, open Options.
    2. For a normal latest-version update, keep Update Channel on Default.
    3. Only switch to Joomla Next when you intentionally want the next major, and only after staging, PHP, and extension checks.
    4. Save & Close, then reload the update screen.

    Joomla 6 will not appear from Joomla 5.4 until the channel is Joomla Next and the server meets Joomla 6 requirements (current PHP 8.3-class, supported MySQL/MariaDB or PostgreSQL). The Behaviour – Backward Compatibility plugin rules also block that hop if they are wrong. Read Behaviour – Backward Compatibility before a 5.4 to 6 upgrade.

    Step 5: Run Pre-Update Check, then start the update

    1. Read Required settings, Recommended settings, and Extensions.
    2. Update or disable extensions that the check flags as incompatible. The check is metadata, not a full runtime test, so still keep the backup.
    3. Confirm you have a backup.
    4. Click Start Update (wording varies slightly by version) and leave the tab open until it finishes.
    5. After success, open System → Maintenance → Database, select Joomla CMS, and click Update Structure / Fix if any tables are listed.
    6. Clear Joomla cache and your host cache. Test the homepage, login, and one form.

    Error map: match the symptom to the fix

    What you see Usual cause Fix
    No update offered, or only an old patch Wrong channel, or update server unreachable Options → Default or Joomla Next. Then check outbound HTTPS
    Failed to download update package / could not connect Firewall, DNS, TLS, or update.joomla.org blocked Read the log. Ask the host to allow outbound HTTPS. Use Upload & Update
    Out of memory, or download dies with no clear reason memory_limit too low (96 MB is a known failure point) Raise to 256M and retry. Confirm in System Information
    Progress bar stalls, then a timeout or blank page PHP or proxy timeout during a large ZIP Raise execution time, retry off-peak, or upload the package manually
    Extract failed / could not create file Permissions, open_basedir, or full disk Fix ownership on tmp and core folders. Free disk. Retry
    Files updated, admin shows database errors SQL schema step did not finish System → Maintenance → Database → Fix
    White screen or 500 right after update PHP version, incompatible extension, or .htaccess Error log first. See mod_rewrite 500 and extension disable via database if locked out
    Class JRequest not found after a major hop Legacy extension code Replace JRequest with getInput()
    Joomla 6 button missing on 5.4 Channel still Default, or PHP too old, or compat plugin mis-set Joomla Next + PHP check + compat plugin guide

    Step 6: Read the update log before you change ten settings

    Open administrator/logs/joomla_update.php (or download it from the host file manager). Look at the last lines around the failure time.

    • Attempting to download then nothing: connectivity, timeout, or memory during download.
    • Download failed with a URL on update.joomla.org: outbound HTTPS or TLS.
    • Error extracting: permissions or disk.
    • Finalizing / cleanup then a PHP fatal on the next page: the core files may already be new. Fix the extension or PHP error. Do not start a second update on top.

    Step 7: Upload & Update when download keeps failing

    1. On a computer that can reach the internet, download the Update Package ZIP for your exact target from the official Joomla downloads (not a random mirror). Use the update package, not the full install package with an installation/ folder, unless you are doing a manual file replace and know the extra steps.
    2. In the administrator open Joomla Update and choose Upload & Update (or the package upload tab).
    3. Upload the ZIP and run the installer.
    4. If upload fails immediately, raise upload_max_filesize and post_max_size, then retry.
    5. Finish with Database Fix and a cache clear.

    This bypasses the server’s outbound download. It does not bypass PHP memory during extract, so still raise memory_limit.

    Step 8: If the administrator will not load after the update

    1. Read the PHP / host error log. The class or file named there is the clue.
    2. If it is a third-party extension, rename that extension’s folder via FTP (or set enabled = 0 in #__extensions) so Joomla can boot.
    3. If it is .htaccess / mod_rewrite, rename .htaccess temporarily and follow the 500 on mod_rewrite guide.
    4. If the database is mid-schema, restore the backup rather than clicking update again.

    Step 9: After a successful update

    • Confirm the version in System Information matches the package you intended.
    • Update extensions from System → Update → Extensions.
    • Re-enable anything you disabled for the check.
    • Submit the sitemap if URLs changed (they should not on a patch update).
    • Watch the site for a day. Keep the pre-update backup until you are sure.

    When one-click update is the wrong tool

    Stop and plan a migration if any of these are true:

    • You are on Joomla 3 (or older) and want Joomla 5 or 6
    • Pre-Update Check lists many incompatible extensions you cannot replace yourself
    • The template is a heavily overridden club template with no vendor update
    • VirtueMart, K2, or custom components are business-critical
    • Two update attempts already failed and the log is unclear

    Infyways runs those as staged upgrades from $149, with a free compatibility audit. Start at Joomla Upgrade Services or contact us.

    Key takeaways

    1. Same-major updates belong in System → Update → Joomla on the Default channel.
    2. Next majors need the Joomla Next channel, current PHP, and a staging backup.
    3. Read joomla_update.php before changing random PHP settings.
    4. Raise memory to at least 256M. 96 MB is a known way to fail the download.
    5. If outbound HTTPS is blocked, Upload & Update with the official update ZIP.
    6. Always run Database Fix after the files change.

    Frequently asked questions

    How do I update Joomla to the latest version?

    Back up the site, open System → Update → Joomla, keep the Default channel for a patch, pass Pre-Update Check, then Start Update. Finish with System → Maintenance → Database if needed.

    Why is the Joomla Update menu missing?

    On current Joomla it lives under System → Update → Joomla, not always under Components. If the whole administrator menu is broken, rebuild menus from a working backup or ask your host to confirm the admin template is intact.

    Why does Joomla say there is no update when I know a new version exists?

    You may be on the wrong channel, or the server cannot reach update.joomla.org. Check Options, then the update log.

    How do I fix “failed to download the update package”?

    Allow outbound HTTPS to update.joomla.org, raise PHP memory and execution time, then retry. If the host still blocks downloads, use Upload & Update with the official ZIP.

    The update finished but the site shows database errors. What now?

    Go to System → Maintenance → Database, select the Joomla CMS item, and run the structure fix. Do not restore unless that fix fails.

    Can I update Joomla 3 to Joomla 6 from this screen?

    No. That is a multi-hop upgrade (3.10 to 4.4 to 5.4 to 6), not a single updater click. Use a staged plan.

    Is it safe to update on the live site?

    Patch updates are usually safe after a backup. Major upgrades should be proven on staging first.

    Who can fix a stuck Joomla update for me?

    Infyways handles failed updates and full version migrations. Request a Joomla upgrade audit.

  • How to Remove MooTools from Joomla

    How to Remove MooTools from Joomla

    MooTools is a JavaScript framework Joomla used from 1.5 through 3.10 for SqueezeBox popups, image captions, and older effects. Joomla 4, Joomla 5, and Joomla 6 do not ship it. Core in those versions uses the Web Asset Manager, Bootstrap 5, and media/system/js/core.js. If a current site still requests mootools-core.js, a template or extension is loading its own copy.

    People remove it to cut unused JavaScript and to stop fights with jQuery over the $ symbol. On Joomla 3 that is safe only after you replace captions and modals. Deleting every script tag, which is what a lot of old snippets do, takes jQuery and the template down with it.

    What you will learn

    • What MooTools was for, in general and inside Joomla
    • Which versions still include it, and which do not
    • Why caption.js keeps showing up on ordinary article pages
    • Why speed plugins and developers want it gone
    • How to remove only those files on Joomla 3, and what to do when Joomla 4+ still loads them

    What MooTools is

    MooTools is an open-source JavaScript library, not a Joomla extension. It gave developers a class system, DOM helpers, events, animation (Fx), and Ajax (Request). The copy Joomla 3 shipped is MooTools Core 1.4.5, plus MooTools More 1.4.0.1 when something asked for the extra effects. Official inventory: Joomla 3 JavaScript frameworks.

    The MooTools project itself stalled. Its last release line is 1.6.0 from 2016, and Joomla never moved the CMS copy up to that. You are looking at an unmaintained library frozen inside Joomla 3.

    It is not jQuery. Joomla 3 shipped both. jQuery is a separate, optional asset even on Joomla 4 and 5 (jquery in the Web Asset Manager). Removing MooTools does not remove jQuery, and you should not treat them as the same cleanup.

    What Joomla used it for

    Joomla did not load MooTools on every page by itself. A layout, template, or extension called a behavior, and that behavior added the files. These are the calls that mattered:

    Call Files it pulled What you saw on the site
    JHtml::_('behavior.framework') mootools-core.js. Pass true and it also loads mootools-more.js Nothing visible. Later scripts then use $, $$(), and window.addEvent('domready')
    JHtml::_('behavior.caption') Core plus caption.js Images with class caption get a text line under them, read from the title
    JHtml::_('behavior.modal') Core plus modal.js and modal.css SqueezeBox. Links with class modal open in a lightbox
    Template or extension addScript Whatever path they hardcoded Sliders, accordions, menus, galleries written against MooTools

    Two details explain the script tags people paste into forum posts.

    • caption.js is why MooTools appears on plain articles. Joomla 3 article and blog layouts call behavior.caption. That loads MooTools even when the page has no popup and no slideshow. Since Joomla 3.2.2 the editor inserts real figure and figcaption tags, but the old script stayed so articles written before that still got captions.
    • The file is not named mootools.js on Joomla 3. Core ships /media/system/js/mootools-core.js and /media/system/js/mootools-more.js. The single mootools.js name is the Joomla 1.5 file, or a template that copied it. Search for mootools, not one exact filename.

    Older Joomla also used MooTools for tooltips and form checks. By 3.10 most of those had moved to Bootstrap and jQuery. Modals and captions did not. SqueezeBox was still the modal implementation in 3.10. There is a long core discussion of that leftover: MooTools is still required by modals.

    Which versions include it

    Joomla MooTools in core? What to do
    1.5 Yes. It was the JavaScript framework Upgrade. Do not spend time micro-optimizing 1.5
    1.6, 1.7, 2.5 Yes Same. These releases are long out of support
    3.0 to 3.10 Yes, deprecated. Core 1.4.5 and More 1.4.0.1. Loaded only when a behavior or extension asks Remove the caller on the frontend after you replace captions and modals. Leave the files on disk
    4.0 and later No. Removed from core, along with caption.js and SqueezeBox If the file still loads, it is third-party. Update or replace that extension
    5.x and 6.x No Same as Joomla 4. Core scripts are core.js and Bootstrap, not MooTools

    Joomla 4’s own break list says caption.js is gone and captions must be figure and figcaption: Potential backward compatibility issues in Joomla 4. Joomla 5 and 6 inherited that. They did not put MooTools back.

    A compatibility plugin does not restore it either. Behaviour – Backward Compatibility covers selected PHP APIs. It does not inject mootools-core.js.

    Why people want it removed

    • Unused weight. On a Joomla 3 article page the caption behavior adds render-blocking scripts in the head. If you have no img.caption and no SqueezeBox link, the browser still downloads and parses them.
    • The $ clash. MooTools claims $. Joomla loads jQuery and then jquery-noconflict.js, which gives $ back. Whichever library runs last owns $. A template script that expects jQuery throws “is not a function”. A MooTools slider dies the other way. Removing the library you do not need is one fix. Wrapping jQuery as jQuery(function ($) { ... }) is the other, and it is safer when something still needs MooTools.
    • No upstream fixes. A 2016-era library inside a CMS that stopped at 3.10 will never get a modern browser pass or a security release of its own.
    • PageSpeed. Lighthouse flags it as unused JavaScript. The win is real only when the page still works afterward. A broken menu costs more than a few kilobytes.
    • Stack conflicts. Bootstrap, Vue, Alpine, and current templates were not written against MooTools 1.4. Old effects CSS also collides with SqueezeBox’s modal.css.
    • Migration. Joomla 4 deletes the files. A Joomla 3 site that still needs them is carrying a blocker into the upgrade. Fix the dependency before the hop, not during a failed update. Path and breakage notes: Joomla upgrade issues and Joomla 3 to 4, 5, and 6.

    What breaks if you strip it blindly

    • Captions on old articles that use <img class="caption"> instead of figcaption
    • Any class="modal" link that expected SqueezeBox
    • Template features written with Fx.Slide, Fx.Accordion, or Tips
    • Extensions that still call behavior.framework: older galleries, some menu systems, some editors’ lightbox buttons
    • The administrator, if your snippet runs there too. Joomla 3 admin modals used SqueezeBox. Never strip MooTools from /administrator
    • Inline scripts that still say SqueezeBox.initialize. The file is gone, the inline code remains, and the console fills with errors

    Do not delete media/system/js/mootools-core.js from disk on Joomla 3. Core and extensions still print that URL. You get a 404, not a faster site. Stop the request. Leave the file.

    Step 1: Confirm the Joomla version

    1. Open System → System Information, or look at the footer of the administrator.
    2. If the version is 4, 5, or 6, skip the Joomla 3 unset snippet. Core is already clean. Go to Step 3 and find the third-party file.
    3. If the version is 3.10 or older, keep reading. Take a backup before you edit the template. Method: how to backup a Joomla website.

    Step 2: See the real script URL

    1. Turn off any “combine JS” or cache plugin first. Combiners hide mootools-core.js inside one bundled file, so view-source lies.
    2. Open a frontend article, view source, and search for mootools and caption.js.
    3. In the browser Network panel, filter by mootools. The Initiator column names the document or script that requested it.
    4. Note the path.
      • /media/system/js/mootools-core.js means Joomla 3 core, pulled in by a behavior.
      • /templates/yourtemplate/js/... or /media/com_something/ means that template or extension bundles its own copy. Common on Joomla 4+ leftovers.

    Step 3: Find the caller

    Search the site files (template, then components, modules, plugins, templates) for:

    • behavior.framework
    • behavior.mootools
    • behavior.caption
    • behavior.modal
    • mootools
    • SqueezeBox

    On Joomla 3, a hit inside components/com_content is core calling captions. That one is expected. Hits inside your template and third-party extensions are the ones you can turn off. On Joomla 4+, any hit is third-party. Update that extension, disable it, or replace it. There is no core switch labeled “MooTools”.

    Step 4: Replace captions and modals first

    1. For images, use figure and figcaption. The Joomla editor has done this since 3.2.2. Re-save old articles, or run a content replace from img.caption to that markup. After the move, caption.js has nothing to do.
    2. For popups, stop using class="modal" plus a rel attribute. That syntax is SqueezeBox. Use a Bootstrap modal, or on Joomla 4+ the core dialog pattern. behavior.modal does not exist on Joomla 4.
    3. Click every slider, tab, and gallery on a staging copy. If one of them dies with $ is not a function or Fx is not defined, that feature still needs the library. Update the extension before you block the file.

    Step 5: Unset only MooTools on the Joomla 3 frontend

    The reliable hook is onBeforeCompileHead in a system plugin. It runs after extensions have added scripts and before the head is printed. Code at the top of index.php runs too early, and the usual copy-paste deletes every script, not just MooTools. That broken pattern is called out in the next section.

    This version touches MooTools and caption.js only, and it leaves the administrator alone:

    <?php
    public function onBeforeCompileHead()
    {
        $app = JFactory::getApplication();
        if (!$app->isSite()) {
            return;
        }
    
        $doc = JFactory::getDocument();
        $head = $doc->getHeadData();
        if (empty($head['scripts']) || !is_array($head['scripts'])) {
            return;
        }
    
        foreach ($head['scripts'] as $url => $attrs) {
            $path = strtolower($url);
            if (strpos($path, 'mootools') !== false || strpos($path, 'caption.js') !== false) {
                unset($head['scripts'][$url]);
            }
        }
    
        $doc->setHeadData($head);
    }
    ?>

    Clear Joomla cache and the combiner cache, then view source again. mootools-core.js and caption.js should be gone. jQuery, your template file, and analytics should still be there.

    If the console says SqueezeBox is not defined, a layout is still calling behavior.modal. Remove that call. Unsetting the file does not remove the inline startup script.

    Step 6: Test the pages that used to need it

    • An article with an image caption
    • A page that used a lightbox or class="modal"
    • The menu, the slider, and the contact form
    • One login
    • The administrator home screen, media manager, and a modal field such as the article image picker

    Check the administrator even if the plugin returns early on admin. A template edit often runs on both sides.

    Step 7: On Joomla 4, 5, or 6, update the extension

    There is no core file to unset. Use the path from Step 2.

    • Template path: switch to Cassiopeia. If MooTools disappears, the template was loading it. Update the template or drop that script include.
    • Extension path: update it to a build made for your major, or disable it. Packing MooTools in 2026 means the vendor has not moved that feature to Joomla.request, Bootstrap, or plain JavaScript.
    • Do not add the Joomla 3 unset plugin to Joomla 4 and expect it to see Web Asset Manager scripts the same way. Assets registered with $wa->useScript() are not always sitting in the old scripts array. Disable the asset or remove the include at the source.

    The snippet that removes every script

    This is the code still circulating, including on older copies of this article. Do not use it:

    foreach ($headerstuff['scripts'] as $key => $value) {
        unset($headerstuff['scripts'][$key]);
    }

    The loop has no filter. It drops jQuery, template JavaScript, captchas, and statistics, then the site feels “lighter” because half of it no longer runs. Filter on mootools and caption.js, or do not ship the change.

    What to use instead

    Old MooTools piece Replacement
    behavior.caption and caption.js figure and figcaption
    behavior.modal and SqueezeBox Bootstrap modal, or the Joomla 4+ dialog field
    window.addEvent('domready', ...) document.addEventListener('DOMContentLoaded', ...) or a defer script
    $$('.item') document.querySelectorAll('.item')
    Request.HTML fetch, or Joomla.request() from core.js on Joomla 4+
    Fx.Slide / accordion CSS, or Bootstrap collapse
    $ as MooTools Keep jQuery behind jQuery(function ($) { }) if a script still needs jQuery

    Web Asset Manager is the loader on current Joomla, not JHtml::_('behavior.framework'). A script that only needs Joomla’s helpers depends on core. Add jquery only when that file truly uses jQuery. Docs: Web Asset Manager.

    When removing it is the wrong project

    If the template, the shop, and two galleries all fatal without MooTools, you do not have a script-tag problem. You have a Joomla 3 stack. Stripping the library will not make that stack current. Plan the upgrade, replace the extensions on staging, then the file disappears because Joomla 4 does not ship it.

    Infyways runs those jumps from $149, with a compatibility audit within 12 hours. Start at Joomla Upgrade Services.

    Key takeaways

    1. MooTools powered SqueezeBox, caption.js, and older effects. It is not jQuery.
    2. Joomla 3.10 still ships Core 1.4.5. Joomla 4, 5, and 6 do not ship it at all.
    3. Article layouts load caption.js, which is why the file shows up on pages that look static.
    4. Unset only URLs that contain mootools or caption.js, on the frontend, after captions and modals have a replacement.
    5. Never delete the core file on Joomla 3, and never unset every script in the head.
    6. On a current site, update the template or extension that is still bundling the library.

    Frequently asked questions

    What is MooTools used for in Joomla?

    On Joomla 3 it opens SqueezeBox modals and builds captions for images that use the caption class. Older templates also use it for sliders and accordions. Joomla 4 and newer core do not use it.

    Does the latest Joomla still use MooTools?

    No. Joomla 4 removed it, and Joomla 5 and 6 did not bring it back. A request for mootools-core.js on those versions comes from a template or extension.

    Why do people remove MooTools?

    The usual reasons are unused JavaScript on article pages, conflicts with jQuery over $, and the fact that the library has had no real release since 2016. PageSpeed scores are a side effect, not the only reason.

    Why are mootools-core.js and caption.js on every article?

    Joomla 3 content layouts call JHtml::_('behavior.caption'). That behavior loads both files so old img.caption markup still gets a caption.

    Will my site break if I remove it?

    It breaks wherever a template or extension still calls SqueezeBox, caption.js, or MooTools effects. Test those pages. The administrator on Joomla 3 should keep the library.

    Should I delete mootools-core.js over FTP?

    No. On Joomla 3 that only creates a 404, because core still prints the URL. Stop the behavior or unset that URL. On Joomla 4+ the file is not part of core.

    Is MooTools the same as jQuery?

    No. Joomla 3 loaded both. jQuery remains an optional Web Asset Manager asset on current Joomla. MooTools does not.

    What replaces caption.js and SqueezeBox?

    Use figure and figcaption for captions. Use a Bootstrap modal, or the Joomla 4 dialog, instead of class="modal".

    Can someone remove it without breaking the template?

    Yes. That means finding the caller, replacing captions and lightboxes, then unsetting only those scripts. Request a Joomla upgrade audit if the template still depends on it.

  • Fix Class JRequest Not Found in Joomla 4, 5, and 6

    Fix Class JRequest Not Found in Joomla 4, 5, and 6

    Class ‘JRequest’ not found means your extension, template override, or custom PHP still calls the removed Joomla 1.x/2.x/3.x request helper. JRequest was deprecated for years and is gone in Joomla 4+. It is not restored by the Behaviour – Backward Compatibility plugins. Replace every call with the Joomla Input API: Factory::getApplication()->getInput() (or $this->input inside a core MVC controller).

    This is one of the most common fatals after a Joomla 3 to 4 upgrade, and it still appears on Joomla 5 and 6 when an old module, plugin, or child-template override was never updated. Official Input docs: Joomla Input.

    What you will learn

    • Why Joomla removed JRequest and why the compat plugin will not bring it back
    • Exact old → new code replacements for getVar, getInt, getCmd, and related helpers
    • How to find every remaining JRequest usage on the server
    • Controller, module, plugin, and template override patterns that stay valid on Joomla 6
    • How filters work so you do not silently break integers, HTML, or form arrays

    Why the error appears after upgrading

    On Joomla 3, JRequest::getVar('foo') still ran (with deprecation noise in newer 3.x). On Joomla 4, 5, and 6 the class file is not loaded. PHP throws a fatal error as soon as that line executes.

    Typical sources:

    • Custom components and modules written for Joomla 2.5 / 3
    • Abandoned third-party extensions
    • Template overrides copied from an old html/ folder
    • One-off scripts in the site root or a cli/ helper

    The Behaviour – Backward Compatibility plugins bridge selected later APIs. They do not reintroduce JRequest. See our Behaviour – Backward Compatibility guide for what those plugins actually restore.

    Old JRequest call Modern replacement Notes
    JRequest::getVar('x') $input->get('x', null, 'STRING') or typed helper Default filter for get() is CMD, not “anything goes”
    JRequest::getInt('id') $input->getInt('id', 0) Always pass a default
    JRequest::getCmd('task') $input->getCmd('task', '') Safe for option/task style tokens
    JRequest::getBool('check') $input->getBool('check', false) Watch string "false" quirks; prefer real booleans
    JRequest::getWord('layout') $input->getWord('layout', '') Letters and underscore only
    JRequest::getFloat('price') $input->getFloat('price', 0.0) Or getDouble where available
    JRequest::getMethod() $input->getMethod() / server method checks Prefer framework request method helpers when available
    JRequest::setVar('x', $v) $input->set('x', $v) Use def() when you only want to set if missing

    Step 1: Capture the full stack trace

    Turn on error reporting on staging (or read administrator/logs/ and the PHP / server error log). The fatal line path tells you whether to edit an extension, a template override, or a custom file.

    Example message:

    Error: Class "JRequest" not found
    Calling: templates/YOUR_TEMPLATE/html/.../default.php:42

    Fix that file first. Searching the whole tree still matters because several files may call JRequest.

    Step 2: Find every JRequest usage

    From the site root (SSH) or a project-wide search in your IDE:

    grep -R --include="*.php" -n "JRequest" .
    # or
    rg -n "JRequest" -g "*.php"

    Also search case variants and legacy imports:

    rg -n "jrequest|JRequest::" -g "*.php" -i

    Skip libraries/ core and vendor trees unless you overwrote core (you should not). Focus on components/, modules/, plugins/, templates/, and any custom src/ folders.

    Step 3: Replace with Factory::getApplication()->getInput()

    Preferred modern form (Joomla 4, 5, and forward-compatible with Joomla 6 guidance):

    use Joomla\CMS\Factory;
    
    $input = Factory::getApplication()->getInput();
    $data  = $input->get('data', '', 'STRING');
    $id    = $input->getInt('id', 0);
    $task  = $input->getCmd('task', '');

    Avoid the older property access when you can:

    // Works on many CMS installs, but the public ->input property is deprecated for new code
    $input = Factory::getApplication()->input;

    Joomla’s migration notes recommend getInput() instead of reading the input property directly. See Joomla 5.4 → 6 deprecations.

    Old code

    $data = JRequest::getVar('data');
    $id   = JRequest::getInt('id');
    $view = JRequest::getCmd('view');

    New code

    use Joomla\CMS\Factory;
    
    $input = Factory::getApplication()->getInput();
    $data  = $input->get('data', null, 'STRING');
    $id    = $input->getInt('id', 0);
    $view  = $input->getCmd('view', '');

    Step 4: Use $this->input inside MVC controllers

    If your class extends Joomla\CMS\MVC\Controller\BaseController, Input is already available:

    $id   = $this->input->getInt('id', 0);
    $data = $this->input->post->get('jform', [], 'array');

    Do not call Factory::getApplication() again unless you are outside that controller context.

    Step 5: Match filters to the old intent

    Blindly changing getVar to $input->get('name') can break values because the default filter is CMD (strips many characters). Pick the filter that matches the old third argument or helper name.

    • INT / getInt for IDs and counts
    • CMD / getCmd for option, view, task, layout tokens
    • STRING / getString for normal text (HTML tags stripped)
    • HTML when you must keep markup more carefully (still sanitize before output)
    • ARRAY for jform style posts: $input->post->get('jform', [], 'array')
    • RAW only when you fully trust and validate afterward

    Typed helpers keep code readable:

    $name = $input->getString('name', '');
    $qty  = $input->getInt('quantity', 0);
    $ok   = $input->getBool('agree', false);

    Step 6: GET vs POST vs files

    Use nested input when the source matters:

    $getOnly  = $input->get->get('p1', 0, 'int');
    $postOnly = $input->post->get('p1', 0, 'int');
    $files    = $input->files->get('jform');

    On SEF sites, routing values like option and view come from the router as well as query strings. Prefer the main $input->getCmd('view') unless you intentionally need raw GET only.

    Step 7: Fix template overrides and modules

    Overrides under templates/TEMPLATE/html/ often keep decade-old snippets. After replacing JRequest:

    1. Clear Joomla cache
    2. Reload the exact menu item that crashed
    3. Re-run the project-wide search until zero hits remain in site-owned PHP

    For modules using a modern Dispatcher, inject Input (or read it from the application) instead of static JRequest calls. The official Input manual includes a full module sample.

    Step 8: Prefer updates over patches when the vendor still exists

    If the fatal sits inside a third-party extension:

    1. Install the vendor’s Joomla 4/5/6 native package
    2. Only then patch local forks if the product is abandoned
    3. Document every local patch so the next update does not overwrite your fix blindly

    A one-line site patch is fine for an override you own. It is a poor long-term plan inside administrator/components/com_oldthing/ that you did not write.

    Situation Best action
    Your custom module / override Replace with getInput() and commit the change
    Maintained commercial extension Upgrade to the Joomla 4+ package from the vendor
    Abandoned extension Patch if small, or replace the extension
    Only one leftover JRequest in a child template Fix the override; do not hack core

    Key takeaways

    1. JRequest does not exist on Joomla 4, 5, or 6. The fatal is expected until you remove the calls.
    2. Use Factory::getApplication()->getInput() or $this->input in MVC controllers.
    3. Map old helpers to typed getters and explicit filters. Default get() uses CMD.
    4. Search the whole site tree. One fixed file is not enough if overrides still call JRequest.
    5. Compatibility plugins will not resurrect JRequest. Update the code.

    Frequently asked questions

    What does Class ‘JRequest’ not found mean in Joomla 4?

    PHP tried to call the removed JRequest class. Update that code to the Input API before the page can load.

    Does this still happen on Joomla 5 and Joomla 6?

    Yes. Any leftover JRequest call fatals on current majors the same way.

    Will Behaviour – Backward Compatibility fix JRequest?

    No. Those plugins bridge other legacy pieces. JRequest must be replaced in code.

    Is JFactory::getApplication()->input still OK?

    It often still works, but new code should call getInput(). Prefer use Joomla\CMS\Factory over legacy JFactory aliases when you touch the file.

    Why did my value become empty after switching to input->get()?

    You probably hit the default CMD filter. Use STRING, INT, or another filter that matches the old getVar intent.

    How do I read jform POST data now?

    Use $input->post->get('jform', [], 'array'), then validate in the model the same way core components do.

    Can Infyways fix this on a client site?

    Yes. If you need a Joomla 3 to 4/5/6 upgrade with extension and override cleanup, contact Infyways.

  • Fix Joomla 500 Error on mod_rewrite

    Fix Joomla 500 Error on mod_rewrite

    A Joomla 500 error on mod_rewrite is almost always Apache rejecting a directive in your root .htaccess file right after you enable Search Engine Friendly URLs or “Use URL rewriting.” The browser only shows Internal Server Error. The Apache error log names the real cause: usually Options +FollowSymLinks, a missing AllowOverride, disabled mod_rewrite, or a bad RewriteBase.

    This guide is the fix path we use on Joomla 4, 5, and 6 sites (and older 3.x still on Apache). It complements our deeper Joomla .htaccess guide and the Joomla SEF URL setup.

    What you will learn

    • How to prove the 500 is caused by .htaccess / mod_rewrite in under two minutes
    • The exact Apache log messages that map to each fix
    • How to repair FollowSymLinks, AllowOverride, mod_rewrite, and RewriteBase
    • How to rebuild a clean Joomla .htaccess from htaccess.txt
    • What to check in Global Configuration and conflicting extensions

    Why Joomla shows 500 after enabling URL rewriting

    Joomla SEF without rewriting still works with index.php in the URL. Turning on Use URL rewriting tells Joomla to drop index.php and rely on Apache mod_rewrite plus the rules in .htaccess (renamed from the shipped htaccess.txt).

    If Apache cannot apply those rules, every front-end request can return HTTP 500. The administrator may still load if you open it with a direct /administrator/ path, which is a useful clue.

    Symptom / log clue Most likely cause First fix
    Site dies only after enabling URL rewriting .htaccess active and rejected Rename .htaccess to restore the site, then fix the directive
    Options not allowed here or FollowSymLinks error Host forbids Options in .htaccess Comment out Options +FollowSymLinks
    .htaccess ignored, URLs 404 AllowOverride None Set AllowOverride All (or FileInfo Options) in the vhost
    Invalid command RewriteEngine mod_rewrite not loaded Enable the module and restart Apache
    Works in root, breaks in subdirectory Wrong RewriteBase Set RewriteBase /subfolder/
    Works until a security extension ships custom rules Broken rewrite block from a plugin Disable the extension, restore core SEF section

    Step 1: Prove it is the .htaccess file

    1. Via FTP or file manager, rename root .htaccess to .htaccess.bak.
    2. Reload the homepage.
    3. If the 500 disappears (even if SEF URLs look ugly again), the rewrite file is the culprit.

    Do not leave rewriting enabled in Global Configuration while .htaccess is missing, or you will get 404s on pretty URLs. Temporarily turn Use URL rewriting off, then continue.

    Step 2: Read the Apache error log

    Guessing wastes time. Open today’s error log (cPanel “Errors”, Plesk logs, /var/log/apache2/error.log, or your host’s equivalent) and reload the site once.

    Look for lines that mention .htaccess, Options, RewriteEngine, or AllowOverride. Match them to the table above before editing Joomla again.

    Step 3: Fix Options +FollowSymLinks (the most common 500)

    Joomla’s shipped htaccess.txt includes Options +FollowSymLinks because mod_rewrite historically needed it. Many shared hosts already set symlink policy in the virtual host and forbid changing Options from .htaccess. Apache then returns 500 with “Options not allowed here.”

    In your .htaccess, comment the line:

    # Options +FollowSymLinks

    Some hosts prefer:

    Options +SymLinksIfOwnerMatch

    Official Joomla docs note that if commenting FollowSymLinks restores the site and SEF still works, your administrator already set the option server-side and you should leave it commented. See Preconfigured htaccess and Enabling SEF URLs.

    Step 4: Confirm AllowOverride permits .htaccess

    If you control the server (VPS, dedicated, local XAMPP/WAMP), open the virtual host or httpd.conf <Directory> block for the site document root and ensure overrides are allowed:

    <Directory "/var/www/html">
        AllowOverride All
        Require all granted
    </Directory>

    On shared hosting you usually cannot edit this. If AllowOverride is None, ask support to enable .htaccess overrides for Options and FileInfo, or to enable Joomla URL rewriting for your account.

    Restart Apache after config changes.

    Step 5: Enable mod_rewrite

    On Debian/Ubuntu:

    sudo a2enmod rewrite
    sudo systemctl restart apache2

    On RHEL/Alma/CloudLinux, ensure this line is uncommented in the Apache config and restart:

    LoadModule rewrite_module modules/mod_rewrite.so

    Quick PHP check on a throwaway file (delete after testing):

    <?php
    print_r(apache_get_modules());

    If mod_rewrite is missing from the list (or apache_get_modules is unavailable under PHP-FPM), confirm with your host. Without the module, leave Joomla URL rewriting off. SEF can still run with index.php in the path.

    Step 6: Rebuild .htaccess from htaccess.txt

    Corrupt or hand-edited rewrite blocks are a frequent source of 500s. Joomla ships a known-good template as htaccess.txt in the site root.

    1. Download a fresh copy from your Joomla version package if the root file is missing.
    2. Copy htaccess.txt to .htaccess (merge carefully if you already have custom redirects).
    3. Comment Options +FollowSymLinks if Step 3 applied.
    4. Keep core SEF rules inside the <IfModule mod_rewrite.c> block.

    Core SEF section (simplified shape; prefer the full file from your Joomla version):

    <IfModule mod_rewrite.c>
    RewriteEngine On
    RewriteBase /
    
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteCond %{REQUEST_FILENAME} !-d
    RewriteCond %{REQUEST_URI} !^/index\.php
    RewriteCond %{REQUEST_URI} /component/|(/[^.]*|\.(php|html?|feed|pdf|vcf|raw))$ [NC]
    RewriteRule .* index.php [L]
    </IfModule>

    Never paste truncated snippets that smash the title or other text into the middle of a RewriteCond line. That alone will 500 the site.

    Step 7: Set RewriteBase for subdirectory installs

    If Joomla lives at https://example.com/shop/, set:

    RewriteBase /shop/

    Root installs usually use RewriteBase /. Wrong base values produce 500s or broken asset paths after rewriting is enabled.

    Step 8: Align Global Configuration

    In System → Global Configuration → Site (wording varies slightly by Joomla 4/5/6):

    • Search Engine Friendly URLs: Yes
    • Use URL rewriting: Yes only after .htaccess works
    • Adds Suffix to URL: optional
    • Unicode Aliases: as needed for non-ASCII

    Save, clear Joomla cache, then test a menu item URL. If enabling rewriting brings the 500 back, return to Steps 2 and 3. Keep SEF on and rewriting off until Apache is clean.

    Step 9: PHP-FPM Authorization line and host extras

    Some hosts need the HTTP Authorization pass-through for API or extension auth:

    RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]

    That line belongs in the core SEF section of a current Joomla .htaccess. Removing it rarely causes a 500, but a broken duplicate of it can. Also watch for host-injected blocks (LiteSpeed, Imunify, custom php_flag lines) that are invalid on your PHP handler. Comment suspect lines one at a time while watching the error log.

    Step 10: Rule out extensions and security plugins

    After the core file works, re-enable custom redirects and security rules carefully.

    • Disable recently installed SEF, security, or “firewall” extensions that write rewrite rules.
    • Check for a second .htaccess in /administrator or a subdomain docroot.
    • Restore from backup if a malware cleanup left garbage rewrite conditions.

    If the site was compromised, fix rewriting only after a clean restore. See our guide on repairing a hacked Joomla website.

    Nginx and IIS note

    mod_rewrite is an Apache module. Nginx uses try_files toward index.php. IIS uses web.config. A “mod_rewrite 500” on those stacks usually means you are reading Apache advice on the wrong server. Ask the host which web server fronts PHP before editing .htaccess.

    Key takeaways

    1. A Joomla 500 right after enabling URL rewriting is an Apache .htaccess problem until the error log proves otherwise.
    2. Commenting Options +FollowSymLinks fixes the majority of shared-hosting cases.
    3. Rename .htaccess to restore the site, then rebuild from htaccess.txt.
    4. Enable mod_rewrite and correct AllowOverride / RewriteBase before turning rewriting back on in Joomla.
    5. Keep Global Configuration rewriting off until a homepage request returns 200 with the fixed file in place.

    Frequently asked questions

    Why do I get a Joomla 500 error when I enable mod_rewrite?

    Apache is rejecting a directive in .htaccess, most often Options +FollowSymLinks, or mod_rewrite is not allowed. Check the error log, then comment FollowSymLinks and confirm AllowOverride.

    Is the administrator also down during a rewrite 500?

    Not always. /administrator/ can still load while the public site 500s. That pattern strongly points at front-end rewrite rules rather than a total PHP crash.

    Should I delete .htaccess permanently?

    No. Use a rename only to diagnose. Joomla needs a valid .htaccess for clean SEF URLs and basic exploit blocking from the core template.

    Does this apply to Joomla 5 and Joomla 6?

    Yes. The SEF and htaccess.txt flow is the same family on Joomla 4, 5, and 6. Always copy htaccess.txt from your exact version package.

    What if I am on Nginx?

    Do not chase mod_rewrite. Configure Nginx try_files $uri $uri/ /index.php?$args; (or your host’s Joomla snippet) instead of Apache .htaccess.

    Can a plugin cause a rewrite 500?

    Yes. Security and SEF extensions sometimes append invalid rules. Disable recent extensions, restore the core SEF block, then re-add custom rules one by one.

    Where can I get a clean Joomla htaccess file?

    From the htaccess.txt in your Joomla root or install package. Our htaccess for Joomla article covers version-specific notes and hardening.