Blog

  • How to Find Which Joomla Extension Is Causing a 500 Error

    How to Find Which Joomla Extension Is Causing a 500 Error

    A Joomla 500 error means PHP or the web server aborted the request. The extension name is in the log, not in the generic “Whoops” page. Read error_log (and Joomla’s log folder), turn Debug on from Global Configuration or configuration.php, then isolate the last update. On a staging copy only, you can temporarily rename a plugin folder to prove the group. Never delete production files without a backup, and never “clean up” live plugins to find a 500.

    The browser message is empty on purpose. Production hides fatals. Your job is to make the fatal visible in a log, then disable one extension, not the whole site.

    500 page with no name, error_log line pointing at plugins/system

    The HTML is a dead end. The PHP error log is the map. The path under plugins, modules, or components is the extension.

    What you will learn

    • Where hosts put error_log and where Joomla writes administrator/logs
    • How to enable Debug and Maximum error reporting when the admin still opens
    • How to set $debug and $error_reporting in configuration.php when admin does not
    • Why the last update is the first extension to disable
    • How to rename a plugins folder on staging only as a group test
    • How to disable one row in #__extensions without deleting files
    • What not to do on production

    Official: Fatal error (Joomla User Manual). If the site runs but two add-ons fight, use Joomla extension conflict instead of this 500 path.

    500 vs white screen vs “Whoops”

    Joomla 4 and 5 often show a page titled like Whoops, looks like something went wrong with an HTTP 500 status. That is still a server 500. A white screen is the same class of failure with display_errors off.

    Source What it is good for
    PHP error_log (host panel, or a file in the account) Fatals that happen before Joomla’s pretty error page
    Web server error log (Apache/nginx) .htaccess, PHP-FPM socket, permissions
    administrator/logs/ (or the path in Global Configuration) Joomla Log::add and some extension logs, not every fatal
    Debug System + Error Reporting Maximum Stack trace after Joomla has bootstrapped
    Browser Network tab Confirms 500 vs 403 vs timeout. Does not name the PHP file

    If the log line is .htaccess or mod_security, you may not have an extension problem. Fix the server rule, then come back if PHP still fatals.

    Step 1: Copy the site, then backup production anyway

    Before any rename, disable, or configuration.php edit on a live site:

    1. Snapshot or copy files and the database (host backup, or your own). If you cannot restore, do not experiment on production.
    2. Prefer a staging URL with the same Joomla and PHP versions. Do the hunt there. Deploy the known-good disable back to production.
    3. Tell the team the site may be briefly noisy if you enable Maximum error reporting on production.

    Do not delete the plugins directory on production “to see what happens.” You will take down authentication, two-factor, and SEF. You may not get admin back without a restore.

    If you need someone else to hold the copy and the log hunt: Joomla support and maintenance.

    Step 2: Read error_log before you click around

    Ask the host where PHP logs. Common places:

    • cPanel Errors or Metrics → Errors
    • Plesk PHP log
    • A file named error_log in public_html or in the account home
    • ~/logs/error.log on some VPS stacks

    Open the log at the timestamp of your test request. One line of PHP Fatal error is worth an hour of plugin guessing.

    Copy:

    • The exception class (Error, TypeError, ParseError)
    • The file path and line
    • The first few frames of the stack if present

    Map the path:

    • plugins/system/example/ → System plugin “example”
    • plugins/content/example/ → Content plugin
    • modules/mod_example/ → that module (unpublish it in Site Modules once admin works)
    • components/com_example/ → that component
    • templates/cassiopeia/ or a child → template PHP, often an override. See customize without editing core after the site is up.
    • libraries/ → core or a library package. Do not delete libraries. Restore a backup or revert the last Joomla update.

    Joomla also logs under Global Configuration → System → Path to Log Folder (default administrator/logs). Check everything.php or dated files if the host PHP log is empty. Many fatals never reach Joomla’s logger because PHP died first. That is why error_log is step 2, not step 5.

    Step 3: Debug from Global Configuration, or from configuration.php

    If administrator still loads:

    1. System → Global Configuration.
    2. System tab: Debug System = Yes.
    3. Server tab: Error Reporting = Maximum.
    4. Save. Reload the failing site URL once (and the admin URL if that is what 500s).
    5. Read the on-screen file and line. Then set Debug = No and Error Reporting = System Default. Save.

    The Debug console is configured by System – Debug. Allowed Groups can hide the console from guests. You still want Maximum reporting for the fatal text.

    If administrator is a 500 too, do not keep hitting login. Use FTP or the host file manager:

    1. Download configuration.php. Keep a copy.
    2. If the file is 444, set it to 644 long enough to edit (the manual describes this).
    3. Set public $debug = true;
    4. Set public $error_reporting = 'maximum';
    5. Save. Reload once.
    6. Put $debug back to false and $error_reporting back to 'default' or 'none' (match what you had) as soon as you have the path. Leaving Maximum on production leaks paths to visitors.

    Official steps: Fatal error.

    Optional: rename the template’s error.php on staging if that file is itself fataling and hiding the real message. Do that only on the copy.

    Step 4: Disable the last update first

    System → Update → Extensions (if admin works) or your change log:

    • Last extension update
    • Last Joomla update
    • Last PHP version change on the host (this 500s old extensions without a zip install)

    Disable in this order once you have a path, or if the log is empty but the clock matches an update:

    1. The extension named in the log.
    2. If the log names a plugin, disable that plugin in System → Plugins (or #__extensions below).
    3. If admin is down, you cannot click Plugins. Use the database: table #__extensions (your prefix), find element matching the plugin name, set enabled to 0. The user manual describes this for a faulty extension. Do not set core rows to 0 unless you know the row.
    4. If the last change was a component update, disable its plugins first (packages register several rows). Then take the component off the default menu item so it is not the Home view.

    Clear cache files on disk if page cache is on (cache/ folder) after a disable. A cached 500 is rare. A cached blank HTML is less rare. Still worth deleting cache/ on staging.

    Step 5: Staging only, rename a plugins folder to test a group

    This is a group proof, not a production technique.

    On staging:

    1. Confirm you can restore (snapshot, or a zip of plugins/ you just made).
    2. Rename one third-party plugin directory, for example plugins/system/suspect → plugins/system/suspect.off. Joomla will skip that folder. Core plugins stay.
    3. Reload. If the 500 is gone, that folder was in the path (or something it triggered was).
    4. Rename it back. Disable the plugin properly in the database or UI so the site does not fatal on the next page that autoloads it in a different way.

    You can rename a group folder on staging in an emergency, for example plugins/system → plugins/system.off, to see whether any system plugin is involved. That will break a lot of features. It is a binary test on a copy, then you put the folder name back immediately and disable one plugin at a time.

    Do not do this on production. Do not delete the folder. Do not rename plugins as a whole on a live shop. You will remove authentication plugins and lock everyone out. If you already did that on production, restore the backup from Step 1. Do not invent a “fix” by uploading empty directories.

    If you need a batch disable with the UI still up, that is the conflict article’s plugin batches, not a filesystem delete.

    Step 6: Database disable when the UI is dead

    phpMyAdmin or an SQL client, on a backup first:

    • Table: {prefix}_extensions
    • Find the row: type = plugin, element = the plugin name, folder = system/content/…
    • Set enabled = 0

    For a module, you can also unpublish in {prefix}_modules (published = 0) if the log named mod_….

    For a component Home page that 500s, change the default menu item in {prefix}_menu to a core featured or article view, or disable the component’s plugins, rather than DROP TABLE. Deleting tables is how you turn a 500 into a restore.

    When admin returns, uninstall or roll back the extension with System → Manage → Extensions if you are done with it. Uninstall is not the same as deleting folders by hand. The installer cleans #__extensions rows.

    Memory, timeouts, and logs that name PHP, not an extension

    Some 500s never mention plugins/. They still belong to an extension.

    • Allowed memory size exhausted at a line in plugins/system/example/ is that plugin (or a loop it triggered). Raise memory_limit only on staging to confirm. On production, fix the plugin or the data set it loads (a module that queries every article is a typical case).
    • Maximum execution time exceeded in a component view is that component, or a plugin that runs on that view. Do not raise max_execution_time as the only fix.
    • PHP Parse error in an override under templates/…/html/ is your copy, not the vendor zip. Restore the core layout on staging, then repair the override in a child.

    .htaccess 500s often follow a security plugin that wrote rewrite rules, or a hand edit after an extension installer. On staging, temporarily rename .htaccess to .htaccess.bak and use Joomla’s default htaccess.txt copied to .htaccess. If the 500 vanishes, the rules were the problem. Put your custom rules back one block at a time. Do that on production only after a backup, and only if you can restore via the host panel when you lock yourself out.

    Gzip in Global Configuration plus Maximum error reporting can produce odd output on some hosts. If Debug shows a fatal and the browser still shows a generic 500, disable Gzip for the test. Turn it back on later.

    After the site loads, close the hole

    1. Set $debug false and error reporting off/default.
    2. Set Preview and Debug plugins back to normal groups.
    3. Update or replace the extension. If it needs old class names on Joomla 5, that is a compatibility check on the installed but not working article, not a reason to leave Debug on.
    4. If a plugin tmpl was the fatal (parse error in an override), fix the override in a child. Plugin override.
    5. Write the extension name and version in your runbook so the next 500 is shorter.

    Checks: backup, error_log path, debug, last update, staging rename only

    Log first. Last update second. Rename plugin folders only on staging. Never delete live files to “test.”

    Key takeaways

    1. A Joomla 500 is a server abort. The extension is named in error_log (or a Debug stack), not in the Whoops HTML.
    2. Copy the site or take a full backup before you change configuration.php or plugin folders on anything you care about.
    3. Enable Debug and Maximum error reporting only for the reproduce, then turn them off.
    4. Disable the last updated extension first when the clock matches and the log agrees.
    5. Rename plugin folders only on staging, as a temporary proof. Put the names back. Disable via Plugins or #__extensions.
    6. Never delete production plugins/, components/, or libraries/ to debug. Restore from backup if you already did.
    7. Database enabled = 0 on one extension row is the safe UI-down move. Dropping tables is not.
    8. When two extensions work alone and 500 together, finish recovery then use the conflict process.

    Frequently asked questions

    How do I find which Joomla extension is causing a 500 error?

    Read the PHP error_log at the request time. The file path under plugins/, modules/, or components/ is the extension. Enable Debug if Joomla still bootstraps. Then disable that extension, starting with the last update if the log is empty.

    Can I rename the plugins folder on the live site?

    No. Use staging. On production, take a backup and disable one #__extensions row, or restore. Renaming plugins on live removes authentication and can lock out admin.

    Admin is a 500. How do I turn on debug?

    Edit configuration.php: $debug = true and $error_reporting = 'maximum'. Reload once, copy the error, then turn both back off. The user manual documents the permission change if the file is read-only.

    The error_log is empty. What next?

    Check the web server log, Joomla’s log path, and whether you are looking at the right vhost. Enable Maximum reporting on staging. If PHP dies before logging, ask the host for the FPM log.

    Should I delete the extension files to stop the 500?

    No. Disable it. Deleting files on production without a backup is how you lose the only copy of a paid extension and still leave broken #__extensions rows. Restore, then uninstall from the administrator when it loads.

    Could PHP be the “extension”?

    A host PHP upgrade can fatal old extensions. The log still names the extension file. The fix is an update of that extension, or rolling PHP back on staging to prove it.

    When is a 500 not an extension?

    Disk full, bad database credentials in configuration.php, a broken .htaccess, or a core update that failed mid-way. The log still decides. If it names libraries/ after a Joomla update, restore the update backup, do not delete libraries.

  • Joomla SMTP OAuth2: Send Mail with Microsoft 365 and Gmail in Joomla 6.2

    Joomla SMTP OAuth2: Send Mail with Microsoft 365 and Gmail in Joomla 6.2

    Short answer: Joomla 6.2, released on 13 October 2026, added OAuth 2.0 (XOAUTH2) authentication for SMTP to core. Go to System → Global Configuration → Server → Mail, set Mailer to SMTP and SMTP Authentication to OAuth 2.0. Enter the Client ID, Client Secret, Scope, Authorize URL and Token URL from your mail provider and save. Then click Get OAuth2 Token and sign in to the mailbox. Joomla stores a refresh token instead of your SMTP password and fetches a short-lived access token each time it sends mail. The feature is generic, with no built-in presets, so it works with any XOAUTH2 provider. The Joomla manual documents Microsoft 365 and Gmail / Google Workspace, and this guide covers both.

    In this guide: what 6.2 added (checked against the 6.2.0 code), why password SMTP is being retired, step-by-step setup for Microsoft 365 and Google, how to test it, a table of common errors and their fixes, and what to do if you can’t upgrade yet. Planning the upgrade itself? Start with our Joomla 6 guide.

    What did Joomla 6.2 add to the mail settings?

    The Joomla 6.2 release announcement lists “Generic XOAuth2 support for mail authentication”. It arrived through pull request #48290, which replaced an earlier proposal with provider-specific presets for Microsoft and Google with a generic version. We checked the 6.2.0 code so the field names below match what you’ll see.

    SettingWhat changed in 6.2
    SMTP AuthenticationNow a list instead of Yes/No: Disabled, Username and Password, OAuth 2.0. Existing sites keep their old setting.
    OAuth2 InformationA note with the callback URL to register at your provider and a link to the Joomla manual.
    SMTP UsernameStill used with OAuth 2.0. It’s the mailbox Joomla signs in as. SMTP Password is hidden.
    OAuth2 Client ID / Client SecretYour app’s credentials from Microsoft Entra or Google Cloud. The secret field is masked and locked once saved.
    OAuth2 ScopeThe provider permission, such as https://outlook.office.com/SMTP.Send offline_access or https://mail.google.com/.
    OAuth2 Authorize URL / Token URLThe provider’s OAuth endpoints. No presets are built in, so you paste them.
    OAuth2 TokenButtons for Get OAuth2 Token (or Reissue OAuth2 Token) and Validate Token, plus the time the token was issued.

    Under the hood, Joomla asks for consent with prompt=consent and access_type=offline, so the provider returns a refresh token. It checks a random state value against your admin session when the provider redirects back, and only a Super User (core.admin) can save the token. When it sends mail, it hands PHPMailer an XOAUTH2 token provider that swaps the refresh token for an access token and caches it until about 60 seconds before it expires.

    Which providers does it support?

    Any SMTP server that accepts SASL XOAUTH2 with the OAuth 2.0 authorization code flow. The Joomla manual gives tested values for Microsoft 365 (Exchange Online) and Gmail / Google Workspace. For other providers you need their SMTP host, OAuth endpoints and the scope that allows SMTP sending. Joomla 6.2 doesn’t support Microsoft’s app-only client credentials flow (SMTP.SendAsApp). It signs in as a real mailbox.

    Why is basic-auth SMTP being retired?

    Basic authentication means the app stores and sends the mailbox username and password. Microsoft calls it vulnerable to credential theft, phishing and brute force attacks. OAuth tokens are limited to one app and one permission, they expire, and they keep working with multi-factor authentication turned on. These are the dates the providers have published:

    Timeline of SMTP basic authentication retirement: Google 14 March 2025, Microsoft Exchange Online disabled by default end of December 2026, final date announced in second half of 2027
    ProviderWhat happensWhen
    Google (Gmail and Workspace)Access for “less secure apps” turned off for all Google Accounts. SMTP, IMAP and POP stop working with passwords. Source14 March 2025 (first-time connections blocked from summer 2024)
    Google exceptionApp passwords still work where the account allows them. Google lists them as an option for devices that can’t use OAuth.Current
    Microsoft Exchange OnlineNo change to SMTP AUTH basic authentication yet.Now until December 2026
    Microsoft Exchange OnlineSMTP AUTH basic auth disabled by default for existing tenants. Admins can still re-enable it. SourceEnd of December 2026
    Microsoft Exchange OnlineNew tenants can’t use SMTP AUTH basic auth by default. OAuth is the supported method.Tenants created after December 2026
    Microsoft Exchange OnlineMicrosoft will announce the final removal date.Second half of 2027

    Microsoft had planned to start rejecting basic-auth SMTP on 1 March 2026. It put that on hold in its 27 January 2026 update. Treat the end of December 2026 as your real deadline for Microsoft 365, and plan your switch before then.

    What do you need before you start?

    • Joomla 6.2.0 or later. Check System → System Information. On Joomla 5.4, the move to 6.2 is an upgrade, not a migration.
    • A Super User account in Joomla.
    • Admin access to the provider: a Microsoft Entra role that can register apps (and grant consent if your tenant needs it), or a Google Cloud project.
    • The mailbox Joomla will send from, with its password and MFA at hand for the one-time sign-in.
    • Your site’s exact admin URL, including https, www or not, and any subfolder. The callback URL must match it character for character.

    The callback URL Joomla uses is:

    https://www.example.com/administrator/index.php?option=com_config&task=mail.oauth2callback&format=raw

    Joomla builds it from the address you’re using to reach the administrator, so open the admin on the same host you register (for example, always www).

    Six-step Joomla 6.2 SMTP OAuth 2.0 flow: save settings, get OAuth2 token, sign in and consent, callback, refresh token saved, AUTH XOAUTH2 on every send

    How do you set up Microsoft 365 / Outlook SMTP OAuth2 in Joomla?

    Step 1: Register an app in Microsoft Entra

    1. Open the Microsoft Entra admin center and go to Identity → Applications → App registrations → New registration (Microsoft guide).
    2. Name it, for example Joomla SMTP. For one organisation, choose Accounts in this organizational directory only.
    3. Under Redirect URI, choose platform Web and paste your Joomla callback URL. You can also add it later under Authentication.
    4. Register, then copy the Application (client) ID and Directory (tenant) ID from the Overview page.

    Step 2: Add the SMTP permission and a client secret

    1. Under API permissions, add the delegated permission SMTP.Send (Microsoft’s scope string is https://outlook.office.com/SMTP.Send, per Microsoft Learn). Grant admin consent if your tenant requires it.
    2. Under Certificates & secrets → Client secrets, create a secret and copy its Value straight away. Don’t copy the Secret ID. Microsoft shows the value only once.
    3. Note the secret’s expiry date and set a reminder. When it expires, mail stops until you paste a new one and reissue the token.

    Step 3: Make sure SMTP AUTH is allowed for the mailbox

    OAuth won’t help if SMTP AUTH itself is switched off. In the Microsoft 365 admin center, go to Users → Active users, select the mailbox, then Mail → Manage email apps and tick Authenticated SMTP. Microsoft notes that if security defaults are on, SMTP AUTH is already disabled, and an organisation-wide setting can also turn it off (Microsoft Learn). In PowerShell:

    Set-CASMailbox -Identity joomla@example.com -SmtpClientAuthenticationDisabled $false
    Get-CASMailbox -Identity joomla@example.com | Format-List SmtpClientAuthenticationDisabled

    Changes to the app, permissions or Exchange can take a while to apply. The Joomla manual suggests allowing up to about an hour before you decide something is broken.

    Step 4: Enter the values in Joomla

    Joomla fieldMicrosoft 365 value
    MailerSMTP
    SMTP Hostsmtp.office365.com
    SMTP Port587
    SMTP SecuritySTARTTLS
    SMTP AuthenticationOAuth 2.0
    From Email / SMTP UsernameThe same mailbox, e.g. joomla@example.com
    OAuth2 Client IDApplication (client) ID
    OAuth2 Client SecretThe secret Value
    OAuth2 Scopehttps://outlook.office.com/SMTP.Send offline_access
    OAuth2 Authorize URLhttps://login.microsoftonline.com/TENANT_ID/oauth2/v2.0/authorize
    OAuth2 Token URLhttps://login.microsoftonline.com/TENANT_ID/oauth2/v2.0/token

    Replace TENANT_ID with your Directory (tenant) ID. Keep offline_access in the scope. Without it Microsoft doesn’t return a refresh token and Joomla shows “Failed to acquire OAuth2 refresh token.”

    Step 5: Save, then get the token

    Click Save first, because Joomla reads the saved values when it starts the sign-in. Then click Get OAuth2 Token, sign in as the SMTP Username mailbox and accept the permission. You’re sent back to Global Configuration with “OAuth2 token received and saved.” and an issue time under the button.

    Personal Outlook.com accounts: Microsoft says OAuth for SMTP works for Outlook.com too. The Joomla manual only documents the work-account setup above, though, and personal accounts need an app registration that allows personal Microsoft accounts. We haven’t covered that case here.

    How do you set up Gmail or Google Workspace SMTP OAuth2 in Joomla?

    Step 1: Configure the Google Auth Platform

    1. In Google Cloud Console, create or pick a project for this site.
    2. Open Google Auth Platform and fill in Branding (app name, support email, developer contact).
    3. Under Audience, choose Internal if every sending mailbox is in your Workspace organisation. Choose External for a personal Gmail account.
    4. Under Data Access, add the scope https://mail.google.com/. Google treats it as a restricted scope, which can mean extra verification for public apps. That usually doesn’t apply to an internal app used by your own staff.

    Step 2: Create a Web application client

    1. Go to Google Auth Platform → Clients → Create client and choose Web application. Google says to use this type for server-side apps (Google for Developers).
    2. Under Authorized redirect URIs, add the full Joomla callback URL, query string included. Just the domain isn’t enough.
    3. Copy the Client ID (it ends in .apps.googleusercontent.com) and the Client secret.

    Step 3: Watch the 7-day trap on External apps

    Google’s OAuth documentation says an External app whose publishing status is Testing gets refresh tokens that expire after 7 days. That applies to the Gmail scope. Your Joomla mail would work for a week and then stop with invalid_grant. For a personal Gmail account, add the mailbox as a test user only for the first try, then publish the app (move it to In production) before you rely on it. Workspace sites with an Internal app don’t hit this limit.

    Step 4: Enter the values in Joomla

    Joomla fieldGmail / Workspace value
    MailerSMTP
    SMTP Hostsmtp.gmail.com
    SMTP Port587
    SMTP SecuritySTARTTLS
    SMTP AuthenticationOAuth 2.0
    From Email / SMTP UsernameThe same Google mailbox
    OAuth2 Client IDYour Web client ID
    OAuth2 Client SecretYour client secret
    OAuth2 Scopehttps://mail.google.com/
    OAuth2 Authorize URLhttps://accounts.google.com/o/oauth2/v2/auth
    OAuth2 Token URLhttps://oauth2.googleapis.com/token

    Save, click Get OAuth2 Token, sign in with the same Google account and allow access. If Google shows an “unverified app” warning for your own External app, that’s expected while it’s unverified. Continue only if it’s your app.

    Joomla SMTP OAuth2 field values for Microsoft 365 and Gmail: host, port, scope, authorize URL and token URL

    How do you test that Joomla is really using OAuth?

    1. Click Validate Token. A good result reads “Token is valid. Access token expires in N seconds.” This proves the refresh token works with your client ID and secret.
    2. Click Send Test Mail. Joomla sends a message to your own Super User email address with the subject “Test mail from {your site name}”.
    3. Read the success message closely. If it says the email was sent “using PHP Mail as fallback”, Joomla didn’t use SMTP. Fix the SMTP error before you go further.
    4. Check that the message arrived and look at the headers. It should come from your provider’s servers.
    5. Test a real flow too: a contact form, a password reset or a registration email.

    Add this to your maintenance checklist: Microsoft client secrets expire, and Google revokes refresh tokens in some cases, for example if one goes unused for six months or the user changes their password while the token has Gmail scopes. The fix is the same each time: update the secret if needed, save, then click Reissue OAuth2 Token.

    What do the common SMTP OAuth2 errors mean?

    Error you seeUsual causeFix
    AADSTS50011: redirect URI doesn’t matchThe callback in Entra differs from the one Joomla sends (www vs non-www, http vs https, or a different admin path)Copy the URL from the OAuth2 Information note into Entra exactly, and use the admin on that same host
    AADSTS7000215: invalid client secretThe Secret ID was pasted instead of the Value, or the secret expiredCreate a new secret, paste its Value, save and reissue the token
    AADSTS65001 or “Need admin approval”Your tenant requires admin consent for SMTP.SendHave an admin grant consent under API permissions
    535 5.7.139 Authentication unsuccessfulSMTP AUTH is off for the tenant or mailbox, or security defaults are onEnable Authenticated SMTP on the mailbox and check the tenant setting
    535 5.7.3 Authentication unsuccessfulSMTP Username isn’t the account that signed in, or the token lacks SMTP.SendMatch the SMTP Username to the mailbox you authorised and check the scope
    554 5.2.252 SendAsDeniedFrom Email Address differs from the SMTP UsernameUse the same address, or grant Send As in Exchange
    Google Error 400: redirect_uri_mismatchThe callback isn’t in Authorized redirect URIs, or only the domain isAdd the full callback URL, query string included
    Google Error 403: access_deniedExternal app in Testing and the account isn’t a test user, or an admin blocks the appAdd the test user or publish the app; Workspace admins can trust the app
    Google invalid_grant after a weekExternal app still in Testing, so the refresh token expired after 7 daysPublish the app, then reissue the token
    admin_policy_enforcedA Workspace admin restricted Gmail access for third-party appsAsk the admin to allow or trust your OAuth client
    Joomla: “The most recent request was denied because it had an invalid security token”The callback reached a different session, for example you started on one host and came back on another, or the session timed outStart again from Global Configuration on the exact host in the callback URL
    Joomla: “OAuth2 authorize URL or client ID is missing.” or “OAuth2 token URL, client ID or client secret is missing.”A field is empty, or the values weren’t saved before you clicked the buttonFill in the fields, save, then click Get OAuth2 Token
    Joomla: “Failed to acquire OAuth2 refresh token.”No refresh token came back (on Microsoft, usually a missing offline_access)Fix the scope, save and reissue
    Joomla: “OAuth2 SMTP configuration is incomplete.”Username, client ID, secret, token URL or the stored refresh token is emptyFill in every field and get a token

    Microsoft lists every AADSTS code in its Entra error code reference. If a test mail fails and no clear error appears, turn on Debug System in Global Configuration for a moment, or check your server’s PHP error log. Turn debugging off afterwards.

    Is it safe to store the refresh token in Joomla?

    It’s safer than storing the password, but treat it the same way. Joomla 6.2 saves the client secret and refresh token with the rest of Global Configuration in configuration.php. Anyone who can read that file can send mail as the mailbox until you revoke the token. So keep the file outside public reach with strict permissions, don’t commit it to Git, and use a dedicated sending mailbox, not a person’s main account. If you think it leaked, revoke the app’s access (for Microsoft, delete the secret; for Google, remove the app from the account’s third-party access), then create new credentials. Our Joomla security guide covers file permissions and admin hardening.

    What if you can’t upgrade to Joomla 6.2 yet?

    SituationOptionTrade-off
    Joomla 5.x or 6.0/6.1Upgrade to 6.2 for core OAuthTest extensions first; 5.4 to 6.2 is an upgrade, not a migration
    Google mailbox, can’t upgrade soonA Google app password, where the account allows oneStill a stored password; Google lists it as an exception, not the goal
    Microsoft 365, can’t upgrade soonBasic-auth SMTP still works until end of December 2026Plan the switch; after that it’s disabled by default
    Any versionA transactional email service with API-key SMTPAnother vendor and DNS (SPF, DKIM) setup
    Any versionA third-party Joomla OAuth mail pluginPaid, and another extension to maintain

    Upgrades aren’t always smooth. Our Joomla upgrade issues guide tracks known 6.2 problems and their workarounds.

    Need help switching your Joomla mail to OAuth?

    Infyways has built Joomla sites since 2010 and makes 125 Joomla extensions. We can upgrade you to 6.2, set up the Entra or Google app, move your mail to OAuth, check SPF, DKIM and DMARC so messages land in the inbox, and document how to renew the secret. See our Joomla development services. Send us your site and mail provider. We reply within 12 hours.

    Sources we checked (October 2026)

    Frequently Asked Questions

    Does Joomla support SMTP OAuth2?

    Yes, from Joomla 6.2.0 (released 13 October 2026). In Global Configuration → Server → Mail, set Mailer to SMTP and SMTP Authentication to OAuth 2.0, enter your provider’s client details and endpoints, save, and click Get OAuth2 Token.

    Which Joomla version added OAuth 2.0 for email?

    Joomla 6.2. Earlier versions, including Joomla 5.x, 6.0 and 6.1, only support username and password SMTP authentication in core.

    What scope does Joomla need for Microsoft 365 SMTP?

    Use https://outlook.office.com/SMTP.Send offline_access. SMTP.Send allows sending, and offline_access makes Microsoft return the refresh token Joomla stores.

    What scope does Joomla need for Gmail SMTP?

    Use https://mail.google.com/, with the authorize URL https://accounts.google.com/o/oauth2/v2/auth and the token URL https://oauth2.googleapis.com/token.

    What is the redirect URI for Joomla SMTP OAuth2?

    Your site URL followed by /administrator/index.php?option=com_config&task=mail.oauth2callback&format=raw. Register it exactly, with the same https and www as the admin URL you use.

    Why did my Gmail OAuth stop working after 7 days?

    Google issues 7-day refresh tokens to External apps in Testing status that request Gmail scopes. Publish the app, or use an Internal app on Google Workspace, then reissue the token in Joomla.

    When does Microsoft turn off basic authentication for SMTP?

    Under Microsoft’s January 2026 timeline, SMTP AUTH basic authentication is disabled by default for existing tenants at the end of December 2026. Admins can re-enable it for now, and Microsoft will announce the final removal date in the second half of 2027.

    Do I still need an SMTP password with OAuth 2.0?

    No. With OAuth 2.0 selected, Joomla hides the SMTP Password field and uses the stored refresh token. You still enter the SMTP Username, which must match the mailbox you authorised.

  • Joomla WCAG 2.2 and ADA Compliance: What Core Gives You and What You Must Fix

    Joomla WCAG 2.2 and ADA Compliance: What Core Gives You and What You Must Fix

    Short answer: no CMS is ADA compliant out of the box, and Joomla is no exception. Joomla 5 and 6 aim for WCAG 2.1 AA, ship a default template built with accessibility in mind (Cassiopeia) and include a built-in checker (jooa11y). Even so, an independent WCAG 2.2 AA audit of Joomla core, released in August 2026, found 42 issues. For US state and local governments, the ADA Title II rule requires WCAG 2.1 AA by 26 April 2027 or 26 April 2028, depending on population. Whether your site passes depends mostly on what sits on top of core: your template, your extensions and your content.

    In this guide: a quick answer, what WCAG 2.2 adds, what Joomla core covers and what the 2026 audit flagged, the ADA rules for public entities and businesses, a 9-step audit-and-fix process, the tools to use, the truth about overlays and “ADA plugins”, and an FAQ. Selling to Europe? Read our European Accessibility Act guide as well. This article is general information, not legal advice.

    Is Joomla ADA and WCAG compliant? The quick answer

    QuestionShort answer
    Is Joomla ADA compliant out of the box?No CMS is. Joomla core aims for WCAG 2.1 AA. Your template, extensions and content decide whether your site meets it.
    Is Joomla WCAG 2.2 compliant?Not yet. The August 2026 Axess Lab audit found 42 WCAG 2.2 AA issues in core, with 27 success criteria failed. The Joomla project is now planning and merging fixes.
    Which standard should I target?WCAG 2.1 AA is the legal standard under the Title II rule. Build to WCAG 2.2 AA, which also covers 2.1 AA.
    When are the ADA Title II deadlines?26 April 2027 for public entities with 50,000+ people. 26 April 2028 for smaller entities and special district governments.
    Will a plugin make my site compliant?No single plugin will. Checkers find issues and helpers patch some of them, but people still have to test and fix.
    What should I do first?Audit each page type, fix problems at the source, then re-test after every update.

    What does WCAG 2.2 AA mean for a Joomla site?

    The Web Content Accessibility Guidelines (WCAG) are the W3C standard behind almost every accessibility law. They sit under four principles, known as POUR. Content must be Perceivable (alt text, captions, enough contrast), Operable (everything works with a keyboard, with no traps and enough time), Understandable (clear labels, predictable navigation, helpful error messages) and Robust (clean markup that assistive technology can read). Level AA means meeting every Level A and AA success criterion. AA is the level that laws, regulations and settlements usually point to.

    WCAG 2.2 became a W3C Recommendation on 5 October 2023. It adds nine success criteria to WCAG 2.1. Six of them are Level A or AA, so they count toward AA conformance; the other three are AAA. WCAG 2.2 also removes 4.1.1 Parsing as obsolete. Apart from that, the 2.1 criteria are unchanged, so building to 2.2 AA also covers the 2.1 AA standard in the Title II rule. Here are the six new A/AA criteria and where Joomla sites usually trip:

    New criterion (level)What it asksWhere Joomla sites trip
    2.4.11 Focus Not Obscured (Minimum), AAA focused element must not be completely hidden by content you added.Sticky headers, cookie banners and chat bubbles covering the focused link.
    2.5.7 Dragging Movements, AAAnything done by dragging must also work with a single click or tap.Drag-only sliders and sortable lists. The audit flagged drag-only article reordering in Joomla’s own admin list.
    2.5.8 Target Size (Minimum), AAClick targets at least 24×24 CSS pixels, or spaced far enough apart.Tiny social icons and close buttons. The audit measured a 20×20 px remove icon in core forms.
    3.2.6 Consistent Help, AHelp options (contact details, chat, FAQ link) stay in the same relative order on every page.Contact links or chat widgets that move between templates and menu layouts.
    3.3.7 Redundant Entry, ADon’t make people type the same information twice in one process.Checkout and booking forms that ask for the address again.
    3.3.8 Accessible Authentication (Minimum), AANo memory test or puzzle to log in unless there’s an alternative or help.Login forms that block paste or password managers, and puzzle CAPTCHAs with no alternative.

    The full WCAG 2.2 table and copy-paste template fixes are in our European Accessibility Act guide, so we won’t repeat them here.

    What does Joomla core give you, and what must you fix yourself?

    Joomla has made accessibility a priority since version 4. The Joomla Accessibility Project puts it carefully: Joomla “currently aims for WCAG 2.1 AA conformance since Joomla 4, but this has never been independently validated.” This table shows where core helps, where the 2026 audit found gaps in core itself, and what stays your job.

    AreaWhat core gives youGaps the 2026 audit found in coreYour responsibility
    TemplatesCassiopeia (site) and Atum (admin), both built with accessibility as a goalNo skip link in Cassiopeia by default; current-menu and focus indicators below 3:1 contrast; undefined focus styles in AtumThird-party templates, page builders, child templates, overrides and any colours you change
    Content editingAlt-text fields with a decorative-image option; the jooa11y checker in the article editorMedia Manager not usable by keyboard (critical); editor can disappear while scrolling on small viewports (critical)Real alt text, heading order, link text, captions and tagged PDFs in every article
    Forms and loginCore login, registration and multi-factor authentication (MFA)Calendar date picker not keyboard or screen-reader accessible; password rules not tied to the field; MFA QR code without alt text (critical)Contact, booking and checkout extensions, CAPTCHAs and error messages
    InteractionCore Skip-To plugin (on for the administrator by default) and the “Additional Accessibility Features” visitor toolbarInaccessible tooltips; dialogs don’t return focus; sessions time out without warningMenus, sliders, popups, cookie banners, chat widgets and maps
    Admin screensAtum accessibility settings for backend usersExtension list not usable by keyboard (critical); low-contrast checkboxesMatters if staff with disabilities manage your site

    A quick fix for the skip link: the core Skip-To plugin is enabled for the administrator by default and can also be switched on for the site. You can do that under System → Plugins, or add a “Skip to main content” link in a Cassiopeia child template.

    What did the 2026 independent audit of Joomla find?

    Open Source Matters commissioned an independent audit from Axess Lab as Milestone 1a of the Joomla Accessibility Project, which is funded through the Sovereign Tech Fund. Eric Eggert tested Joomla in July and August 2026 against WCAG 2.2 Level AA, and the audit report was released on 17 August 2026. The scope covered Atum, Cassiopeia, login and MFA, the Media Manager, the installer and update flows, backend list and edit views, frontend user forms, and configuration and permissions.

    • 42 issues: 4 critical, 15 serious, 16 moderate and 7 minor, plus one best-practice suggestion.
    • Success criteria: 27 failed, 17 passed, 8 not applicable and 3 not tested.
    • The four critical issues: the Media Manager, the editor vanishing on small viewports, the extension list not working by keyboard, and an MFA QR code with no text alternative.
    • Recurring themes: keyboard operation, contrast, tooltips, dialog focus and session time-outs.
    • The auditor’s verdict: the number of findings is “better than average for a project like this”.

    A separate audit against ATAG 2.0, the guidelines for authoring tools, found five issues. It matters if your editors have disabilities, because Joomla is the tool they use to create content. The Joomla Community Magazine summary covers both audits.

    What happens next? Milestone 1b runs from 1 September to 31 October 2026 and is listed as in progress on the project milestones page. It covers a prioritised remediation backlog and quick-win fixes merged into Joomla core. The Joomla feature tracker also lists WCAG 2.2 AA compliance for Joomla 6.x as in planning. Joomla 6.2, released on 13 October 2026, is the latest version. Check each release’s notes for which audit fixes have shipped. Until a fix lands in the version you run, that gap is yours to work around.

    What does the ADA require for websites?

    The Americans with Disabilities Act covers state and local governments (Title II) and businesses open to the public (Title III). According to the Department of Justice, it has “consistently taken the position” that the ADA applies to web content since 1996. What changes between the two titles is how specific the technical rules are.

    Title II: state and local government websites

    The DOJ final rule was published in the Federal Register on 24 April 2024. It sets WCAG 2.1 Level AA as the technical standard for web content and mobile apps from state and local governments. That includes public schools, colleges and universities, libraries, courts, transit agencies, public hospitals and special districts. An Interim Final Rule published on 20 April 2026 extended the compliance dates:

    Public entityCompliance date
    Total population of 50,000 or more26 April 2027
    Total population under 50,00026 April 2028
    Special district governments (any size)26 April 2028
    Timeline: WCAG 2.2 published 5 Oct 2023, ADA Title II rule 24 Apr 2024, interim final rule 20 Apr 2026, deadlines 26 Apr 2027 for 50,000+ and 26 Apr 2028 for smaller entities
    • Vendors are covered. Content that a contractor builds or posts for a public entity must meet WCAG 2.1 AA. DOJ’s own example is a county parks page made by a local web design company. If your agency builds Joomla sites for cities, schools or libraries, your work is in scope.
    • Third-party tools the entity adds are covered too: calendars, maps, reservation systems and payment forms.
    • School districts use the population of their city or county, or a Census estimate for independent districts, to find their date.

    The rule has limited exceptions. Each one has conditions, and none removes the duty to give a person with a disability an accessible version when they ask:

    • Archived content: created before the compliance date, kept only for reference, stored in an archive area and unchanged since.
    • Preexisting documents: PDFs, Word, presentation and spreadsheet files posted before the compliance date, unless people still use them to apply for or access a service.
    • Third-party posts: content posted by members of the public, not by the entity or its contractors.
    • Individualised, password-protected documents such as a resident’s water bill.
    • Preexisting social media posts made before the compliance date.

    Title III: businesses open to the public

    Title III requires businesses open to the public to give people with disabilities full and equal enjoyment of their goods and services, and DOJ applies that to websites. But DOJ guidance also says the Department “does not have a regulation setting out detailed standards”. Businesses have flexibility in how they comply, and DOJ points to WCAG and the Section 508 Standards as helpful guidance. The same guidance page lists DOJ website settlements with businesses including H&R Block, Peapod and Rite Aid.

    In practice, WCAG is the benchmark commonly referenced in private ADA website lawsuits, demand letters and settlements. For a US business running Joomla, WCAG 2.1 AA is the minimum sensible target and WCAG 2.2 AA is the better one. Outcomes vary from case to case, so we don’t quote lawsuit counts here.

    Section 508: federal agencies and their suppliers

    Federal agencies follow Section 508 of the Rehabilitation Act. The Revised 508 Standards require electronic content to conform to WCAG 2.0 Level A and AA. A Joomla site built to WCAG 2.1 or 2.2 AA covers those 2.0 criteria as well.

    Selling to the EU or UK too?

    If you sell to consumers in the EU, the European Accessibility Act can apply wherever your business is based. Our European Accessibility Act guide covers who it applies to, EN 301 549 and the UK rules.

    General information, not legal advice. Whether and how the ADA applies to your organisation is a question for a qualified attorney.

    How do you audit and fix a Joomla site for WCAG 2.2 AA?

    This is the process we use on Joomla sites for US owners and agencies. It works whether you do it in-house or hire help. The test steps mirror the screen-reader and browser pairs the Joomla Accessibility Project uses for core.

    Nine-step Joomla WCAG 2.2 AA audit: inventory, automated scan, keyboard pass, screen reader check, contrast and target size, prioritise, fix at source, accessibility statement, re-test

    1. Inventory your page types

    You don’t test 2,000 URLs. You test each type of page and each extension that renders something. List these: home page, category blog and list views, a typical article, contact and other forms, login and registration, search results, checkout or booking, an events calendar if you have one, embedded video and maps, and your most-downloaded PDFs. Note which template layout and which extension produces each one.

    2. Run automated scans

    • Turn on jooa11y (System → Plugins → “System – Joomla Accessibility Checker”). It has been a core plugin since Joomla 4.1. Use the Accessibility Check button on your key articles. As the Joomla manual says, it identifies problems but doesn’t fix them.
    • Run WAVE and axe DevTools on every page type from step 1. Our free accessibility checker gives a quick second opinion.
    • Export or screenshot the results. They become your baseline.

    3. Do a keyboard-only pass

    Put the mouse away. Use Tab, Shift+Tab, Enter, Space, the arrow keys and Escape through the menu, search, forms, popups, the cookie banner and checkout. Check that focus is always visible, follows a logical order, never gets trapped, isn’t hidden under a sticky header (2.4.11), and returns to the trigger when a modal closes. Our keyboard navigation tester helps you record what you find.

    4. Spot-check with a screen reader

    Use NVDA with Chrome or Firefox on Windows and VoiceOver with Safari on macOS or iOS. Pull up the headings list and the landmarks. Tab through a form and listen: does every field have a label, and is every error announced? Do icon buttons have names? These are the problems scanners can’t judge.

    5. Check contrast and target size

    Check that normal text has at least 4.5:1 contrast, and that large text, icons, form borders and focus indicators have at least 3:1. Interactive targets should be at least 24×24 CSS pixels or well spaced. Use our free contrast checker for colours and the PDF accessibility checker for documents.

    6. Map findings to WCAG and prioritise

    Log every issue with its WCAG success criterion, the page type, its severity, and its source: template, extension, content or Joomla core. Fix blockers first, meaning anything that stops someone navigating, logging in, submitting a form or paying. Low-contrast footer text can wait a sprint; an inaccessible checkout can’t.

    7. Fix at the source

    • Template: use a child template and layout overrides, so fixes survive template updates. Our European Accessibility Act guide has the skip-link, focus and contrast snippets.
    • Extensions: update first. Ask the vendor about accessibility, for example whether they publish a conformance report (often called a VPAT or ACR). Then patch the output with an override, or replace the extension.
    • Content: write real alt text, fix heading order, rewrite “click here” links, add captions and tag your PDFs.
    • Joomla core: keep current with Joomla 6.2 updates and work around known core gaps, such as enabling the Skip-To plugin on the site.

    8. Publish an accessibility statement and a feedback route

    Add an “Accessibility” page linked in the footer. It should say which standard you aim for (for example WCAG 2.2 AA), when you last tested, any known limitations, how to request content in another format, and how to report a problem by email or phone. DOJ guidance notes that a way to report accessibility problems helps site owners fix them. Don’t write “fully ADA compliant”; describe what you tested and what you’re doing.

    9. Re-test after every update and keep a log

    Accessibility breaks quietly. A template update, a new slider or a Joomla release can undo past fixes. Re-test the affected page types after each change, have editors run jooa11y before they publish, and keep a dated log of what you tested and fixed. If a complaint arrives, that log shows your good-faith work.

    Which tools should you use to test a Joomla site?

    Use automated tools to find the easy problems fast, then use people to find the rest:

    ToolCostBest forLimits
    jooa11y (Joomla Accessibility Checker)Free, in core since Joomla 4.1Article content: alt text, headings, link text, captions, PDF linksChecks content, not your whole template; finds problems, doesn’t fix them
    WAVE (WebAIM)Free browser extensionVisual markers on the page; good for learningAutomated checks only
    axe DevTools (Deque)Free extension, paid tiersDeveloper-grade rule checks for each page typeAutomated checks only
    LighthouseBuilt into ChromeA quick accessibility score next to performance and SEOA subset of checks; a perfect score doesn’t mean the site is accessible
    Keyboard testFreeFocus order, traps, menus, modals, checkoutNeeds a person
    NVDA / VoiceOverFreeWhat screen-reader users actually hearTakes some practice
    Infyways free toolsFreeContrast, keyboard and PDF spot checks; more on our accessibility tools pageSpot checks, not a full audit

    “A ‘clean’ report does not necessarily mean everything is accessible.” The US Department of Justice, in its web accessibility guidance, which recommends pairing automated checkers with a manual check.

    You’ll see many different percentages quoted for how much automated tools catch. The estimates vary with the method, and we haven’t found a primary source we trust, so we don’t quote one. The practical rule holds either way: scan first, then test by hand.

    Do overlays or a “Joomla ADA plugin” make your site compliant?

    No. An overlay adds a script and a toolbar on top of your page. It doesn’t change the template, extension or content that actually fails. Regulators have acted on claims like these. In January 2025 the US Federal Trade Commission proposed an order requiring accessiBe to pay $1 million over claims that its accessWidget could make any website WCAG-compliant. The FTC approved the final order on 22 April 2025. It bars the company from claiming its automated products can make any website WCAG-compliant, or keep it compliant over time, unless it has evidence to support the claim. DOJ’s guidance makes the same general point: automated checkers and overlays “need to be used carefully”.

    Visitor toolbars can still help some people with text size, spacing, contrast or a reading guide. Joomla core even ships one, the “Additional Accessibility Features” plugin. As the Joomla Community Magazine notes, it doesn’t solve any accessibility problem your site has. Treat a toolbar as a comfort feature on top of an accessible site, not as a fix.

    So what is the best Joomla accessibility plugin?

    It depends on the job, because each type of tool does a different one:

    Comparison of accessibility checkers, source-fix helpers, visitor toolbars and overlay widgets: none replaces a manual audit
    • To find issues: jooa11y (free, in core), plus WAVE and axe.
    • To patch mechanical gaps: self-hosted helper plugins that fix the HTML your site sends. For example, our own Easy WCAG (we make it, so weigh that) adds missing lang, alt and iframe titles, labels icon links and form fields, adds a skip link and reports what still needs a person. It doesn’t replace an audit.
    • To give visitors preferences: a self-hosted toolbar, such as Joomla’s core plugin or our Easy Accessibility module. It’s useful for comfort, but it isn’t a compliance tool.
    • To avoid: anything that promises “instant ADA compliance” or a compliance certificate.

    When should you bring in a Joomla accessibility team?

    A small brochure site on the default template can often work through the checklist above in-house. It’s worth getting help when:

    • You’re a public entity, or a vendor to one, facing the April 2027 or April 2028 Title II date on a large site.
    • Your site uses a third-party template or page builder, or lots of extensions.
    • You run checkout, booking, membership or application forms, where one barrier blocks a whole task.
    • You have years of PDFs and media to triage.
    • You also need to upgrade to Joomla 6.2. Fixing accessibility during the upgrade avoids doing the template work twice.

    Infyways has been around since 2010 and makes 125 Joomla extensions, so we know how templates and extensions render under the hood. Our Joomla development team audits against WCAG 2.2 AA (mapped to 2.1 AA for Title II), fixes templates and overrides, repairs or replaces extensions, cleans up content and PDFs, drafts your accessibility statement and re-tests after the fixes. We often pair this with performance optimisation, because clean, well-structured pages also tend to load faster. We don’t sell certificates or legal guarantees. We remove barriers and document the work.

    Tell us your site and deadline; a senior engineer replies within 12 hours. Prefer to add capacity to your own team? See how to hire Joomla developers.

    Sources we checked (October 2026)

    Frequently Asked Questions

    Is Joomla ADA compliant?

    No CMS is ADA compliant on its own. Joomla 5 and 6 aim for WCAG 2.1 AA in core and ship an accessible default template and a built-in checker. But your template, extensions and content decide whether your site meets WCAG, which is the benchmark ADA rules and settlements use.

    Is Joomla WCAG 2.2 compliant?

    Not fully yet. An independent WCAG 2.2 AA audit of Joomla core by Axess Lab, released on 17 August 2026, found 42 issues (4 critical) and 27 failed success criteria. The Joomla Accessibility Project is now turning them into a remediation plan and core fixes.

    What WCAG level does the ADA require?

    For state and local governments, the DOJ Title II rule requires WCAG 2.1 Level AA. For private businesses under Title III, DOJ has no technical regulation. It points to WCAG and Section 508 as guidance, and WCAG 2.1 or 2.2 AA is the commonly used benchmark.

    When is the ADA Title II website deadline?

    After DOJ’s Interim Final Rule of 20 April 2026, the deadline is 26 April 2027 for public entities with a population of 50,000 or more. It’s 26 April 2028 for smaller entities and all special district governments.

    Is there a Joomla ADA or WCAG plugin that makes my site compliant?

    No plugin can guarantee compliance. The built-in jooa11y checker finds content issues, and self-hosted helpers can patch some mechanical gaps such as missing alt text or labels. Templates, forms and content still need manual fixes and testing.

    Do accessibility overlays work?

    They can add visitor preferences, but they don’t fix your site’s underlying code. In April 2025 the FTC finalised an order requiring accessiBe to pay $1 million over claims that its widget could make any website WCAG-compliant.

    How do I check my Joomla site’s accessibility?

    Run jooa11y on your articles and WAVE or axe on each page type. Then test everything by keyboard and spot-check with NVDA or VoiceOver. Automated tools find only part of the issues, so the manual checks matter most.

    Does the European Accessibility Act apply to my US Joomla site?

    It can. If you sell covered services, such as online shopping, to consumers in the EU, the EAA can apply wherever you’re based. See our Joomla European Accessibility Act guide for details.


    Disclaimer: This article is general information about US and international accessibility standards as of October 2026. It is not legal advice, and following it does not guarantee compliance with the ADA or any other law. Check your obligations with a qualified attorney.

  • Joomla Extension Conflict: How to Find the Problem

    Joomla Extension Conflict: How to Find the Problem

    A Joomla extension conflict is two (or more) extensions changing the same request, often by listening to the same plugin event, until the site misbehaves or PHP fatals. The last thing you installed is the first suspect. The reliable find is a binary search: disable third-party plugins in batches on a staging copy, then re-enable until the clash returns. Do not disable core plugins at random on production.

    A conflict is not “the zip failed to install.” If the package never registered, use Joomla extension installed but not working. If the whole site is a 500, capture the log first: Which Joomla extension is causing a 500 error. This page is for the site that still runs, but SEF, login, cache, editor, or a component view breaks once two add-ons are enabled together.

    Two plugins hooked to the same event, one request, broken output

    Same event, two listeners, undefined order. The second plugin sees HTML or a routing state the first already changed.

    What you will learn

    • How to tell a conflict from a single broken extension
    • Why “what did we install last” is the fastest start
    • How to read a PHP error as a file path under plugins/
    • How to disable third-party plugins in batches without taking core down
    • What “two plugins on the same event” looks like in practice
    • When to stop and use a maintained staging copy instead of live trial and error

    Official fatal-error guidance (debug and isolate an extension): Joomla User Manual, Fatal error. Plugin events (what “same event” means): Plugin events.

    What a conflict looks like (and what it does not)

    You see Conflict pattern Different job
    Feature A works until you enable extension B Two listeners, or B assumes A’s HTML B is simply incompatible (still isolate B)
    Blank module after enabling a system plugin Plugin rewrites output too late or too early Module position mismatch
    Login, SEF, or language switch flaps System plugins on routing / user events Language assignment on one module
    PHP fatal naming a file in plugins/system/x and plugins/system/y Both loaded, one fatals on the other’s result Single extension 500
    Admin works, site does not (or reverse) client_id / site vs admin plugins Template only

    Conflicts cluster in system and content groups because those events run on almost every request: onAfterInitialise, onAfterRoute, onAfterRender, onContentPrepare, cache, and SEF.

    Two SEF plugins, two “security / firewall” plugins, a page cache plugin plus a plugin that needs cookies, an editor-xtd button plus a content filter that strips the same tag: those are classic pairs.

    Do not “fix” a conflict by editing the vendor’s PHP on production. The next update restores the clash. If you must change HTML a plugin prints, use a layout override when it has tmpl: Joomla plugin override. If you must change behaviour, disable one extension or replace it. Keep core files stock: Customize Joomla without editing core.

    Step 1: Write down what changed last

    Before you disable anything, record:

    • Last extension installed or updated (name, version, date).
    • Last Joomla or PHP change on the host.
    • Last time someone enabled a plugin that had been off.
    • Whether the failure is site, administrator, or both.

    If the failure started in the same hour as a package, disable that package first (its plugins, then its modules, then the component). Many “conflicts” are one bad release fighting core, not two third parties. You still confirm by turning it off.

    If nothing was installed, look at System → Manage → Extensions, sort by Date, and at host changelogs (PHP 8.2 to 8.3 is a common silent change).

    Work on a staging copy when you can. Disabling plugins on a live shop during business hours is how you create a second incident. If you have no staging, take a full backup (files and database) before batch disables. Infyways can hold that process for you: Joomla support and maintenance.

    Step 2: Turn the PHP error into a path

    A conflict often announces the file.

    1. On staging (or briefly on production if you must): System → Global Configuration → System set Debug System to Yes. Server set Error Reporting to Maximum. Save.
    2. Reproduce once. Read the message. Turn Debug off and Error Reporting back to System Default when you finish. Do not leave Maximum on a public site.
    3. If the administrator is already down, you cannot use that UI. Use the 500 article: configuration.php $debug and $error_reporting, plus the PHP error_log.

    The path is the clue:

    • plugins/system/cache/… vs plugins/system/yourcdn/…
    • plugins/content/emailcloak/… vs a content plugin that already wrapped emails
    • plugins/behaviour/… plus a third-party system plugin that still calls removed class names

    If PHP names one file only, start there. It may still be a conflict (that file fatals because another plugin changed state). If the stack lists two extension folders, you have the pair.

    Empty error with a “wrong” page only: might not be PHP. Might be two plugins rewriting HTML. Batch disable still works.

    Step 3: Disable third-party plugins in batches

    Goal: prove the site works with only core, then add half the third-party plugins back, then half of that half. That is a binary search. It is faster than one-by-one on a site with forty plugins.

    Rules:

    • Do this on staging first.
    • Do not disable Joomla core plugins you do not understand (Authentication, User, Behaviour, System – Language Filter on a multilingual site, System – SEF if you rely on it). If you disable Language Filter on a live multilingual site, you will create a worse outage than the conflict.
    • Prefer the administrator: System → Plugins. Filter Site vs Administrator if needed. Filter by author or by a search that excludes Joomla!.
    • Unpublish (disable) a batch of third-party system plugins first. Reload the broken page. If the bug is gone, the conflict is in that batch. Re-enable half. Repeat until one name remains.
    • If system plugins are not the cause, batch content plugins next, then other groups (user, authentication, extension, privacy, and so on).

    A practical batching order:

    1. Everything third-party in system that is not your payment or firewall must-keep list.
    2. Third-party content plugins (filters, shortcodes, related items).
    3. Third-party user / authentication if the bug is login.
    4. Modules last. A module rarely conflicts with another module the way two system plugins do. It can still break a page if both output the same JS global. Unpublish the extras in System → Site Modules if the binary search on plugins did not land.

    If administrator login dies after a disable, you went too far (often authentication or a behaviour plugin). Restore from backup or set #__extensions.enabled = 1 for that plugin in the database. The fatal-error manual describes that table. Do not guess core rows.

    When one plugin is identified, leave it disabled and re-enable the rest. Confirm the site is healthy. Then enable the suspect alone on a clean plugin set. If it fails alone, it is a broken extension, not a pair. If it fails only with one other plugin, you have the conflict pair.

    Step 4: Check two plugins on the same event

    Once you have two names, confirm they share a hook.

    You do not need to be a developer. Open each plugin’s main PHP file on staging (read only) and search for onAfterRender, onAfterRoute, onAfterInitialise, onContentPrepare, onContentAfterDisplay, or similar on* methods. If both implement the same function, they both run. Order is the Ordering column in System → Plugins.

    What to try, in this order:

    1. Change Ordering so the plugin that should see original HTML runs first (or last, depending on the job). Save. Test. Ordering is a real fix when one plugin must wrap output the other already built.
    2. If both claim to be “the” SEF, cache, or security layer, you cannot order your way out. Keep one. Uninstall or leave the other disabled.
    3. Look for a setting on one plugin: “don’t process admin,” “exclude component,” “don’t run on POST.” Use those before you write custom PHP.

    Events for custom fields and content are documented in the content events manual. Two content plugins both rewriting onContentPrepare is how shortcodes disappear or how {field} output gets double-escaped.

    Do not edit the vendor files to comment out a method. That is a core-style hack on an extension. Use disable, order, or a replacement.

    Step 5: Components, modules, and “it only happens on one view”

    If plugins are clean and com_example plus com_other fight:

    • Open each component’s menu item. Note query vars.
    • Disable one component’s modules and plugins (packages install all three). A “component conflict” is often its system plugin.
    • Test the view with a stock Cassiopeia style to rule out a template JS conflict. Template JS vs extension JS is still a conflict. Put scripts in user.js on a child if you own them: Add custom JavaScript to Joomla.

    Page builders plus core com_content fields, two backup plugins running cron, two Google Analytics plugins injecting gtag twice: isolate by disable, not by stacking more extensions.

    Cache, SEF, and language plugins (the usual trio)

    If the “conflict” is wrong URLs, mixed languages, or a page that is stuck in time, check this trio before you batch forty content plugins:

    • System – SEF (core) plus a third-party SEF or router plugin. Keep one rewriter. Two of them is the most common routing conflict.
    • System – Page Cache (or a full-page cache extension) plus a plugin that varies output by user, cart, or language. Cache serves the first visitor’s HTML to the second. That looks like a random conflict. Exclude the component, or disable page cache on staging while you test.
    • System – Language Filter plus a third-party language or translate plugin. On a multilingual site, disable the extra translator first. Do not disable Language Filter on production as your first move.

    A cookie or privacy plugin that strips scripts, plus a plugin that injects those scripts on onAfterRender, will clash until one of them has an allow list. Ordering can help. Two products that both claim to own the footer usually cannot.

    When you finish a batch search, write the two names in a site runbook. The next admin who enables both because both were paid for will recreate the outage.

    Step 6: After you know the pair

    1. Keep a note: names, versions, event, whether order fixed it.
    2. Check each vendor for a Joomla 5 / 6 build. An old Joomla 3 plugin on Joomla 5 is a conflict with core, not with your other add-on.
    3. Uninstall the one you will not keep, or leave it disabled with a comment in your runbook so someone does not “helpfully” enable it.
    4. Clear cache. Reload logged out.
    5. Turn Debug off.

    If the pair is required for business (payments plus a tax plugin) and order does not help, that is a development or vendor ticket, not more toggling. Maintenance retainers exist for that: Joomla support and maintenance.

    Do not confuse a conflict with a template override that fatals only when a plugin injects extra HTML. If the stack names templates/ and plugins/, disable the plugin first on staging. If the page recovers, the override assumed markup the plugin changed. Diff the override against core and put the repaired copy in a child. That is still a conflict. The durable fix is a plugin you can update plus an override you own, not a patched vendor file.

    Checks: last install, PHP path, batch disable, same event, ordering

    Last change first. Then a PHP path if you have one. Then batch disable on staging. Then confirm the shared event.

    Key takeaways

    1. A conflict is two extensions on one request, often the same plugin event. Isolate with disables, not with core hacks.
    2. Start with the last installed or updated package. Many clashes are one bad release.
    3. A PHP error that names a file under plugins/ is a gift. Read the path before you guess.
    4. Batch-disable third-party plugins on staging (binary search). Do not randomly disable core authentication or language filter on production.
    5. When two plugins share onAfterRender or onContentPrepare, try Ordering, then keep only one SEF/cache/security layer.
    6. Packages include plugins. Disable those before you uninstall a component you still need.
    7. Restore Debug and Error Reporting when you finish. Maximum error output is for the hunt.
    8. If you cannot take production down, copy the site and hunt there. That is cheaper than an hour of live outage.

    Frequently asked questions

    How do I find a Joomla extension conflict?

    Reproduce the failure, note the last install, then disable third-party plugins in batches on staging until the failure stops. Re-enable half at a time until one plugin (or a pair) is left.

    Should I disable all plugins including core?

    No. Core authentication, user, and (on multilingual sites) language filter keep the site usable. Batch third-party system and content plugins first.

    Two plugins listen to the same event. What then?

    Change Ordering and test. If both try to own SEF, cache, or security, disable one. You cannot merge two full-page rewriters.

    Why did this start after an update, not an install?

    The update changed one listener’s HTML or PHP. The other plugin still expects the old output. Same conflict method: last changed extension first, then batches.

    Can a module conflict with a plugin?

    Yes, usually through JavaScript or through a plugin that rewrites module HTML on onAfterRender. Unpublish the module to test, then the plugin.

    Is editing the plugin PHP a valid fix?

    Not on production, and not if you want updates. Disable, order, override a tmpl if one exists, or replace the extension.

    When should I use a maintenance team?

    When you have no staging, when administrator login is at risk, or when two business-critical extensions fail together after you isolate the pair.

  • Joomla 6 Compatibility Check: Scan Every Extension on Your Site for Free

    Joomla 6 Compatibility Check: Scan Every Extension on Your Site for Free

    Updated 14 October 2026 · By Abhilash Sahoo, Infyways

    To check whether your Joomla extensions are compatible with Joomla 6, install the free Migration Scanner from JoomlaX on a staging copy of your site, click Scan site, and read the Dashboard. It inventories every enabled third-party component, module, plugin and template, scans their PHP and XML files, and labels each extension Will not run, Needs review or Ready. For every problem it shows the file, the line number and the replacement code. The scan is read-only and never runs extension code.

    In short: Migration Scanner is a free Joomla administrator component for Joomla 4.4, 5 and 6 (PHP 8.1+). It answers one question before you upgrade: which installed extensions will break on my target Joomla version, and where exactly?

    Why do you need a Joomla 6 compatibility check?

    Most Joomla upgrades do not fail because of Joomla core. They fail because of a third-party extension or template that still uses old Joomla 3-era code, such as JFactory, JText, JRequest or JHtml behaviours.

    Joomla keeps many of these old names alive through its backward compatibility plugin (plg_behaviour_compat on Joomla 4/5, plg_behaviour_compat6 on Joomla 6, where the Classes Aliases option is off by default). Everything compat6 covers is scheduled for removal in Joomla 7. For the exact settings per version, see our Joomla backward compatibility plugin guide; for what changed in the release itself, see what’s new in Joomla 6.

    So an extension that “works” today may only be working because a compatibility layer is propping it up. A compatibility check tells you which extensions are genuinely ready, which are leaning on the plugin, and which will not run at all.

    What is the JoomlaX Migration Scanner?

    Migration Scanner is a free, read-only Joomla administrator component that finds legacy PHP APIs and incomplete manifests before you move a site to Joomla 6. It is built and maintained by Infyways under the JoomlaX brand.

    Details
    Price Free (no checkout)
    Installs on Joomla 4.4, 5.x and 6.x
    PHP 8.1 or later
    Database MySQL or MariaDB
    What it reads PHP and XML files of enabled, non-core components, modules, plugins and templates
    What it skips Joomla core, disabled extensions, JavaScript, CSS and SQL files (this release)
    Changes your files? No. It does not execute extension PHP or run extension SQL
    Target version Auto (Joomla 6) by default, or choose 4 or 5
    Output Dashboard plan, extension list, per-extension findings, JSON export, printable site report
    Version 1.0.0, released 12 October 2026

    You can try it first on the live demo.

    Who is it for?

    • Site owners planning a Joomla 3, 4 or 5 to Joomla 6 upgrade who want to know what will break before they start.
    • Agencies that need a printable, shareable report of every blocker on a client site.
    • Developers who maintain custom or abandoned extensions and need a file-and-line list of what to rewrite.

    What does Migration Scanner detect?

    The scanner token-scans PHP and checks XML manifests for a namespace. Each finding is grouped by API, given a severity, and tagged with the compatibility layer it depends on.

    Status for each extension

    Status Meaning
    Will not run Uses APIs the compatibility plugin cannot save. Must be rewritten for the target version
    Needs review Still depends on compat6 aliases or similar layers
    Ready Nothing blocking for the chosen target version

    Finding types (chips)

    • Needs aliases: old class names such as JText or JFactory that only work while Classes Aliases are enabled in compat6.
    • Needs legacy classes: code that depends on legacy classes the compatibility plugin still ships.
    • Needs asset stubs: references to removed assets that the plugin stubs out.
    • Will not run: calls the compatibility plugin cannot rescue.

    Severity

    Findings are ranked Critical, High, Medium and Low, so you fix what will stop the site first.

    Grouped, not duplicated

    If JText appears 48 times in one component, you see one group (“JText · Needs compat6 aliases, 48 times”) instead of 48 separate lines. You fix a pattern, not a pile of duplicates. Expand a group to see why it matched and what to put instead.

    Migration Scanner findings for one component: a Will not run badge, 176 findings split by severity (41 Critical, 129 High, 6 Medium), filter chips for Needs aliases, Needs legacy classes, Needs asset stubs and Will not run, and grouped APIs such as JText and JFactory

    For the replacement pattern behind each API, see our Joomla Migration Reference. For example, JFactory and application changes, JRequest and Input, HTML helpers (JHtml), JTable and database and deprecated JavaScript (MooTools/jQuery).

    How do I install Migration Scanner?

    1. Download MigrationScanner_UNZIP.zip free from the Migration Scanner page.
    2. Unzip it on your computer. Inside you will find pkg_jxmscanner_*.zip (the file you install) and ReadMe.txt.
    3. In the Joomla administrator, go to System > Install > Extensions and upload pkg_jxmscanner_*.zip.
    4. Open Components > Migration Scanner to confirm the Dashboard loads.
    5. Clear the cache: System > Maintenance > Clear Cache.

    You need a Super User or administrator account. You do not need jQuery, a CLI or any extra plugins. Updates use the same steps, and previous scan results stay in the database.

    Tip: Do not install the outer _UNZIP file in Joomla. Install the inner pkg_jxmscanner_*.zip.

    Still on Joomla 3? How to use the Migration Scanner

    The Migration Scanner extension needs Joomla 4.4 or later, so it cannot be installed on a Joomla 3 site. You have two options: scan each extension or template ZIP now with our free online Joomla Migration Scanner, or upgrade a staging copy to Joomla 4.4 and install the extension there. Joomla’s official path is 3.10 → 4.4 → 5.4 → 6; you cannot skip Joomla 4.

    Option A: scan ZIP packages online (no upgrade needed)

    1. Collect the installation ZIPs of your third-party extensions and template (from the developer, or zip the folders from your site).
    2. Drop each ZIP into the online Joomla Migration Scanner. It reads Joomla 3 code, so it works before you upgrade anything.
    3. Use the results to decide what to update, replace or rewrite. This is the best route for custom or abandoned extensions that have no newer version.

    Option B: upgrade a staging copy, then run the extension

    1. Clone the live site to staging. The live site stays on Joomla 3 until the copy works.
    2. On the copy, update to the latest Joomla 3.10.
    3. Migrate the copy to Joomla 4.4 with the Behaviour – Backward Compatibility plugin enabled.
    4. Install Migration Scanner on the copy, scan, and fix what it flags.
    5. Continue the copy to Joomla 5.4 and then 6, rescanning at each step, before you touch production.
    Online ZIP scanner Staging copy + extension
    What it checks One extension or template package at a time Every enabled third-party extension on the site
    What you need The ZIP files only A staging copy upgraded to Joomla 4.4+
    Best for Joomla 3 sites, custom or abandoned code, checks before upgrading A full, site-wide plan once the copy runs Joomla 4.4 or later

    For every step of the version jumps, follow our Joomla 3 to 6 upgrade guide. If you would rather have it done for you, see our Joomla upgrade service.

    How do I run a Joomla compatibility scan?

    Run it on a staging copy of your site. The scan is read-only, but a large site can take several minutes and is easier to review away from production.

    1. Open Components > Migration Scanner.
    2. Read the host banner. It tells you whether plg_behaviour_compat or plg_behaviour_compat6 is enabled, and whether Classes Aliases, Legacy Classes and Removed asset stubs are on.
    3. (Optional) Open Configuration and set the Target Joomla version and Files per step.
    4. Click Scan site and wait until the live status pill shows Idle.
    5. Use the Dashboard plan, then open an extension marked Will not run.
    Migration Scanner Dashboard in the Joomla administrator with Scan site, Pause, Export JSON and Site report buttons, a green banner showing plg_behaviour_compat is enabled with Classes Aliases, Legacy Classes and Removed asset stubs set to Yes, and a completed scan of 5,775 of 5,775 files

    Configuration: target version and files per step

    Migration Scanner Configuration screen with Target Joomla version set to Auto, which uses Joomla 6 as the migration target, and Files per step set to 40
    • Target Joomla version: Auto targets Joomla 6. Pick 4 or 5 if you are staging an upgrade to that version.
    • Files per step: how many files each scan step reads (default shown: 40). Lower it if the scan hits PHP max_execution_time on cheap hosting.
    • Permissions tab: Super Users can set component permissions.

    Save, then run a new scan so the counts match the new target.

    How do I read the results?

    1. Dashboard: the plan

    The Dashboard shows four site-wide counts: All extensions, Will not run, Needs review and Ready. Do this first lists the blockers, and Needs work first is a short table of the worst extensions. From the header you can Scan site, Pause, Export JSON and open the Site report.

    2. Extensions: the inventory, worst first

    Components > Migration Scanner > Extensions ranks every third-party component, module, plugin and template from worst to best. Filter by status or type, search by name or element (for example com_example), and open a row for its findings. Joomla core never appears here.

    Migration Scanner Extensions list showing 327 third-party extensions: 4 Will not run, 120 Needs review and 203 Ready, split into 37 components, 95 modules, 193 plugins and 2 templates, with columns for Will not run, Needs compat6 aliases and Findings

    3. Findings: file, line and replacement

    Open one extension to see All APIs, the alias, legacy and asset-stub layers, and the Will not run items. Each finding names the file path, the line and the replacement. After you edit files, click Scan this extension to re-check just that one; you don’t need to rescan the whole site.

    4. Share it

    • Export JSON: a machine-readable export that includes bc_layer, bc_param and removed_in for each finding.
    • Site report: a printable view for agencies, developers and clients.

    How do I fix the issues it finds?

    Work from the top of the Dashboard plan:

    1. Update first. Check whether the developer has released a Joomla 5/6 version. Updating often clears dozens of findings at once. Rescan afterwards.
    2. Replace abandoned extensions. If the developer has stopped updating the extension and it is marked Will not run, look for a maintained alternative.
    3. Fix “Needs aliases” items. Replace old names with namespaced classes, for example JText with Joomla\CMS\Language\Text and JFactory::getApplication() with Joomla\CMS\Factory::getApplication(). Our migration reference groups show the before/after code for each API.
    4. Rewrite “Will not run” code. These need real changes: namespaced MVC, Web Asset Manager instead of JHtml behaviours, event subscribers, Bootstrap 5 markup in templates. See components and MVC, plugins and events, media and assets and templates and layouts.
    5. Rescan the extension until it shows Ready. Then, on staging, test with the Classes Aliases option off so you know the code no longer leans on compat6.

    For the full upgrade sequence (backups, PHP version, pre-update check, staging cutover), follow our Joomla 3 to 6 upgrade guide. If something breaks after the upgrade, see common Joomla upgrade issues and fixes.

    Migration Scanner vs Joomla’s pre-update check vs manual checks

    Joomla’s own pre-update check (System > Update > Joomla, with the update channel set to the next major version) checks required settings. For a Joomla 5 to 6 update it requires the old compatibility plugin to be disabled and Backward Compatibility 6 to be enabled. Its Extensions list relies on what each developer declares, so treat it as a high-level indicator, not proof that the code works.

    Joomla pre-update check Manual check Migration Scanner
    Looks at extension code No (relies on developer update data) Only if you read the code yourself Yes: PHP tokens and XML manifests
    File and line of each problem No Slow and error-prone Yes, with replacement
    Shows reliance on compat6 aliases / legacy classes No Hard to tell Yes, per finding
    Covers templates Partly Yes Yes (enabled non-core templates)
    Site-wide ranked plan No No Yes, worst first
    Shareable report No Your own notes JSON + printable report
    Cost Built in Your time Free

    They work best together: use Migration Scanner to find the code problems, fix them, then run Joomla’s pre-update check before the actual update.

    Whole site or single ZIP: which scanner should I use?

    We also run a browser-based Joomla Migration Scanner that checks one package. You drop a single extension or template ZIP into it, and it is useful before you install anything or when you only have the package. The JoomlaX extension scans the installed site: every enabled third-party extension at once, with a Dashboard plan and per-extension rescans. Use the online tool for one package, and the extension for a whole site.

    DIY or hire help?

    Do it yourself if the scan shows mostly Ready or Needs review extensions that have updates available, and you are comfortable editing PHP on staging.

    Get help if you have Will not run extensions that are custom-built or abandoned, a Joomla 3 template, or no developer time. Migration Scanner has a Paid support tab for this. It is optional, and the scanner stays free.

    Migration Scanner Paid support screen explaining three steps: scan the site and open the extension that will not run on Joomla 6, send the extension name and target Joomla version, and get a quoted paid rewrite or upgrade
    1. Open Components > Migration Scanner > Paid support, or click Ask for paid support on the Dashboard or an extension report.
    2. Name the extension and your target Joomla version.
    3. Infyways quotes a rewrite. You only pay if you want the fix.

    For a full site upgrade, done on staging with your sign-off before production, see our Joomla upgrade service and Joomla extension upgrade.

    Troubleshooting

    • Scan never finishes: lower Files per step, check PHP max_execution_time on staging, and start again.
    • Old results showing: the Dashboard uses the newest scan. Run Scan site again after installing or updating extensions.
    • An extension is missing: only enabled third-party extensions are inventoried. Core and disabled items are skipped.
    • JavaScript files not listed: this release reads PHP and XML only.
    • Menu still says Preferences: clear the cache and open Configuration from the component submenu or the cog.

    If a result does not match what you see in the files, open a ticket at support.joomlax.com. Include your Joomla and PHP versions, the extension element, and a JSON export or a screenshot of the finding.

    Frequently asked questions

    How do I check if a Joomla extension is compatible with Joomla 6?

    Install the free Migration Scanner on a staging copy, leave the target on Auto (Joomla 6) and click Scan site. Each enabled third-party extension is marked Will not run, Needs review or Ready, with file-and-line findings. Also check the developer’s site for a Joomla 6 release.

    Is Migration Scanner free?

    Yes. The scanner is free to download and use. Paid support is optional and only applies if you want Infyways to rewrite an extension.

    Which Joomla versions does it support?

    It installs on Joomla 4.4, 5 and 6 and needs PHP 8.1 or later. You can target Joomla 4, 5 or 6 in Configuration.

    Can I use the Migration Scanner on Joomla 3?

    Not the extension: it installs on Joomla 4.4 or later. On a Joomla 3 site, scan each extension or template ZIP with our free online Joomla Migration Scanner, or upgrade a staging copy to Joomla 4.4 and install the extension there.

    Can I upgrade from Joomla 3 straight to Joomla 6?

    No. Joomla’s official path is 3.10 → 4.4 → 5.4 → 6. Each major upgrade requires the latest release of the previous version, so you cannot skip Joomla 4 or 5. Do every step on a staging copy first.

    How do I check Joomla 3 extensions for Joomla 6 compatibility?

    Upload each extension or template ZIP to the free online Joomla Migration Scanner, which reads Joomla 3 code. For a site-wide check, upgrade a staging copy to Joomla 4.4, install the Migration Scanner extension, and set the target to Joomla 6.

    Does it change or break my extensions?

    No. The scan is read-only. It does not execute extension PHP or run extension SQL, and it does not need write access to extension files.

    Should I run it on a live site?

    Run it on a staging copy. It is safe to run, but a large site can take several minutes, and the results are easier to review off production.

    What files does it scan?

    PHP and XML in enabled, non-core components, modules, plugins and templates. Joomla core, disabled extensions, JavaScript, CSS and SQL files are not scanned in this release.

    What does “Needs compat6 aliases” mean?

    The extension uses old class names (such as JText or JFactory) that only resolve while the Behaviour – Backward Compatibility 6 plugin has Classes Aliases turned on. It may work today, but compat6 is scheduled for removal in Joomla 7, so the code should be updated.

    Download Migration Scanner free

    Find out what will break before you upgrade, not after. Download Migration Scanner free from JoomlaX, read the documentation, and run your first Joomla 6 compatibility check on staging today.

    If the scan shows work you would rather not do yourself, talk to our Joomla upgrade team.

  • Joomla Custom Fields Not Showing: How to Fix It

    Joomla Custom Fields Not Showing: How to Fix It

    Joomla custom fields are not showing when a display gate is closed: Automatic Display is off or pointed at a slot the view never renders, the field is unpublished or not assigned to the article’s category, Access hides it, an override never prints the fields block, or cache is serving a page from before the field existed. Values can sit in the article editor and still never reach the public HTML. This page is troubleshooting only. The feature how-to is Joomla custom fields.

    If you have not created the field yet, stop and use that how-to. If the Fields tab has a value and the frontend does not, stay here.

    Custom field value in the article, empty public article layout

    Admin can show a value while the public view never fires After Title, After Display, or your override. Treat display as a separate pipeline.

    What you will learn

    • How to prove the value exists before you touch templates
    • What After Title, Before Display Content, After Display Content, and Do not automatically display actually inject
    • Why Assigned Categories All skips Uncategorised
    • How unpublished fields, ACL, and Display When Read-Only hide output
    • How article context vs category context sends you to the wrong Fields list
    • How a layout override or CSS can remove fields that Joomla did render
    • Why cache makes a fixed field look broken for hours

    Official parameters: J5.x Adding custom fields, parameters and the user manual Field parameters. Events: Content events (programmers).

    Split the problem before you edit PHP

    Symptom What it usually is What it is not
    Field missing on the article edit form Category assignment, unpublished field, wrong context (Category vs Article), plugin off Automatic Display
    Value on the form, missing on the public article Automatic Display, ACL, override, cache “Joomla deleted the field”
    Shows on the article, missing on the blog Blog layouts often do not run the same display events the same way Category assignment alone
    Shows for Super Users, not for guests Field Access or Display When Read-Only Template chrome
    Shows in HTML, not on screen CSS, or label hidden and value empty-looking Unpublished

    Do not start in html/com_content/article/default.php. Start in Content → Fields.

    Step 1: Confirm the value and the plugins

    1. Content → Articles. Open the article. Open the field group tab (or Fields). Confirm the value is saved. If the input is missing in admin, this is assignment or context, not frontend display. Jump to Step 3 and Step 5.
    2. System → Plugins. Search Fields. System – Fields must be enabled. Field type plugins (Fields - Text, Fields - Calendar, and the type you used) must be enabled. If you disable Fields - Media, media fields stop.
    3. Content → Articles → Options → Integration. Custom Fields must be enabled for articles. Contacts and Users have their own Options.

    If editors cannot type a value, that can be Edit Custom Field Value (core.edit.value) inherited as Not Allowed. Grant it on Content → Articles → Options → Permissions for the right group, or on the field. That is an admin ACL issue. Super Users still see values. Guests never will if Access on the field is Special.

    Step 2: Set Automatic Display (After Title, After Display, or none)

    On Content → Fields, open the field. Find Automatic Display:

    Setting Event Where it usually appears
    After Title onContentAfterTitle Under the title, before intro
    Before Display Content onContentBeforeDisplay Above the body
    After Display Content onContentAfterDisplay Below the body
    Do not automatically display none of the above Nowhere, until {field ID} or an override prints it

    Do not automatically display is the number one “not showing” after a careful setup. It is also the correct choice when you print fields in a child template layout. If you expected automatic output and left this on, change it to After Title or After Display Content, save, clear cache.

    A whole group renders as one block in field order. If one field in the group is unpublished, the others can still show.

    {field 12} in the article body needs the field id, not the name. Wrong id prints nothing useful. The Content – Fields plugin (or the editor Field button) inserts the syntax. If you type {field price} Joomla will not guess.

    Blog (category) views and some third-party layouts do not call the same events, or they call them in a list context where you chose not to show fields. If the single article is fine and the blog is empty, Automatic Display is working. The blog layout is not a full article view. Use an override on html/com_content/category/ or accept fields only on the article.

    Step 3: Fix category assignment (All does not mean Uncategorised)

    The docs are explicit: the default All for Assigned Categories does not include Uncategorised.

    If the article is in Uncategorised, the field can be absent from the editor and from the frontend. Assign Uncategorised explicitly, or move the article into a category you did tick.

    Other assignment misses:

    • You ticked “News” but the article is in “News / 2026” as a child. Child categories are not automatic. Tick the child, or tick every category that should show the field.
    • You assigned the field to one category, then moved the article. The value may still exist in the database. The form and display rules follow the current category.
    • New articles: the Fields tab stays empty until a category is chosen. That is normal. Joomla waits so it can apply assignment.

    After a K2-style migration, Uncategorised is common. The how-to covers the happy path: Joomla custom fields.

    Step 4: Unpublished, Access, and read-only display

    On the field:

    • Status must be Published. Unpublished fields are hidden in the editor for normal users and do not render on the site. Archived is the same idea with a different filter in Fields.
    • Access (Public, Guest, Registered, Special) applies to viewing the value on the frontend. A field set to Registered will not show to a guest. That is not a template bug.
    • Display When Read-Only: if the visitor cannot access the value, Yes still shows it, No hides it. Inherit follows the parent. A guest hitting a Registered field with Display When Read-Only = No sees nothing.
    • Language on the field: same trap as modules. A field set to French will not attach to an English article the way you expect.

    ACL on the article can also stop the whole page. If the article is not viewable, fields are a side issue. Test logged out in a private window.

    Step 5: Article fields vs category fields vs contacts

    Content → Fields has a context switch: Article, Category, Contact, User (wording depends on what is installed).

    If you created the field in Category context, it lives on the category edit form, not on the article. The article page will not print it as an article field. You will hunt Automatic Display forever.

    If you created it under Contacts, articles will never show it.

    Open Fields, set the filter to Article, and confirm your field is in that list. Title collisions across contexts are possible. Use the id in the URL when you edit.

    Step 6: Overrides and CSS that hide fields

    Automatic Display injects HTML when com_content (or contact) dispatches those content events in the view. A custom article layout that never triggers them will never print automatic fields.

    Typical override failures:

    • html/com_content/article/default.php copied from an old template or a page builder, then stripped to $this->item->text only. Events never run. Fields vanish even with After Title set.
    • A html/layouts/joomla/content/ override that removed the after-title output.
    • A html/layouts/com_fields/field/render.php (or field render) override that returns empty, or wraps output in a class your CSS sets to display: none.
    • Alternative layout on the article (a different default_foo.php) that you never updated for fields.

    Fix path: put overrides in a child, not in Cassiopeia core. Customize Joomla without editing core. If the field type uses a plugin tmpl, plugin overrides apply. Diff your default.php against the core file in components/com_content/tmpl/article/default.php. If core still calls the events and your copy does not, restore those calls.

    CSS: inspect the public page. Classes like field-entry, field-label, field-value (exact names depend on layout) may be in the HTML. If they are, Joomla showed the field. Your user.css or the template hid it. If they are not in the HTML, you are still on Steps 2 to 5, not CSS.

    Empty values: Automatic Display typically prints nothing useful when the value is empty. A required field that was never saved on old articles will look like “not showing.” Open the article and save a value.

    Step 7: Cache, and then a frontend proof

    After every field or override change:

    1. System → Maintenance → Clear Cache.
    2. If System – Page Cache is enabled, clear that too, or disable it on staging while you test.
    3. CDN / host cache: purge the article URL.
    4. Hard-refresh the public article logged out.

    Joomla can cache the article HTML from before Automatic Display was set. You will swear the setting does nothing. The cached page is the old page.

    Conservative caching of modules does not usually store article field HTML, but page cache does.

    Checks: value saved, automatic display, category, ACL, override, cache

    If the editor has no input, fix assignment and context. If the editor has a value, fix Automatic Display, Access, override, then cache.

    Label hidden, empty value, and unpublished groups

    Automatic Display can “work” and still look like a blank article.

    • Show Label is off and the value is a short code or a boolean that CSS does not style. Inspect the HTML. If a field-value (or the layout’s equivalent) is there, the field showed. You are in CSS or design, not in Fields.
    • The article never saved a value. Old articles created before the field existed stay empty until you open and save them. A default on the field applies to new items more reliably than to a thousand legacy rows.
    • Field groups have their own published state. An unpublished group can hide the tab in the editor, which looks like the field “vanished.” Publish the group, then the field.

    Media and calendar fields fail in a specific way: the value is a path or a date Joomla cannot render in that layout. Open the article, confirm the media picker still points at a file that exists. After a migration, broken paths are common. That is data, not Automatic Display.

    If you use {field ID} and the id is from a different context (you copied the id from a contact field onto an article), the shortcode will not fill. Use the Article fields list id.

    Blog vs article, and third-party views

    Single article (com_content article view) is where After Title / After Display are designed to run.

    Category blog, featured, and tag views may show intro text only. Fields will not appear in the list unless the layout prints them. That is expected. Do not “fix” Automatic Display for a blog card. Override the blog item layout in a child, or keep fields on the full article.

    Third-party components that are not com_content do not gain article fields by magic. They need their own field context or their own templating. A directory extension is not “Joomla custom fields not showing.” It is a different component.

    Key takeaways

    1. Troubleshooting starts in Content → Fields and the article form, not in random PHP.
    2. Do not automatically display means the public page stays empty unless you use {field ID} or an override.
    3. After Title and After Display Content only work in views that fire those content events.
    4. Assigned Categories All skips Uncategorised. Tick it or move the article.
    5. Unpublished fields, non-Public Access, and Display When Read-Only hide frontend output on purpose.
    6. A field created in Category or Contact context will never show as an article field.
    7. Article default.php overrides that drop content events remove automatic fields. Keep overrides in a child and diff against core.
    8. Clear page cache after you change display. Old HTML is the most convincing fake bug.

    Create and assign fields using the companion article: Joomla custom fields. If a production template override is swallowing fields after an update, Joomla support and maintenance.

    Related Joomla troubleshooting

    Frequently asked questions

    Why are my Joomla custom fields not showing on the article?

    Automatic Display is often Do not automatically display, the article category is not assigned (Uncategorised is the usual miss), Access is not Public, or an article override never fires the content events. Confirm the value in the editor first.

    What is the difference between After Title and After Display?

    After Title injects on onContentAfterTitle (under the title). After Display Content injects on onContentAfterDisplay (after the body). Before Display Content sits above the body. None of these run if you choose Do not automatically display.

    Why does All categories not include Uncategorised?

    That is core behaviour, documented on the custom fields parameters page. Assign Uncategorised explicitly or move the article.

    Do custom fields show on the category blog?

    Not unless that layout prints them. Automatic Display is built around item views that dispatch the content events. Use a category override if list cards must show a field.

    Can an unpublished field still hold data?

    The value can remain in the database. Unpublished means the field is hidden from normal editing and from frontend display. Publish it to use it again.

    How do I show a field only in an override?

    Set Automatic Display to Do not automatically display, then print the field in a child template layout. If you leave After Title on, you will get automatic output plus your override.

    Could cache hide a field I just added?

    Yes. Page cache and CDNs store the article HTML. Clear Joomla cache and the URL at the edge, then test logged out.

  • Joomla and the European Accessibility Act: What Site Owners Must Do (2026)

    Joomla and the European Accessibility Act: What Site Owners Must Do (2026)

    Short answer: If your Joomla site sells products or services to consumers in the EU, such as an online shop, a booking system or a consumer banking portal, the European Accessibility Act (EAA) has applied to it since 28 June 2025, unless you are a microenterprise providing services (fewer than 10 staff and no more than €2 million in annual turnover or balance sheet total). In practice, you meet the EAA by following the harmonised standard EN 301 549. Its current legal version (V3.2.1) points to WCAG 2.1 Level AA, and the new V4.1.1, published in September 2026, moves to WCAG 2.2 AA. Joomla 5 and 6.2 (the latest version) give you a solid start, with an accessible default template and a built-in content checker. But an independent 2026 audit still found issues in core, and most real-world failures come from templates, extensions and content. So you need to audit, fix at the source and publish an accessibility statement. An overlay widget on its own won’t make you compliant.

    In this guide: who the EAA covers, which WCAG version to target, what Joomla core already does (and where it falls short), a practical checklist with native fixes, how to handle the problems core can’t, and an FAQ. This article is general information, not legal advice. Check your own obligations with a qualified adviser.

    What Is the European Accessibility Act?

    The European Accessibility Act is Directive (EU) 2019/882. It sets common accessibility requirements for certain products and services sold in the EU. Each member state wrote it into national law. Germany did this with the Barrierefreiheitsstärkungsgesetz (BFSG), and Italy, France, the Netherlands and Poland have their own transposing acts. That’s why enforcement and penalties differ from country to country.

    For website owners, these are the parts that matter:

    • Since 28 June 2025 it applies to services provided to consumers. That includes e-commerce services, consumer banking services, e-books, electronic communications, access to audiovisual media, and websites, apps and e-ticketing for passenger transport (Article 2).
    • The directive defines e-commerce services broadly: services provided at a distance, through websites and mobile apps, at a consumer’s request, with a view to concluding a consumer contract. If visitors can buy, book or subscribe on your Joomla site, assume you’re in scope.
    • Microenterprises providing services are exempt. That means fewer than 10 employees and an annual turnover or balance sheet total of no more than €2 million (Article 2(23) and Article 4(5)). Microenterprises dealing in products get lighter rules but aren’t exempt.
    • Some content is excluded. That includes pre-recorded audio and video and office files (PDF, DOCX) published before 28 June 2025, archived content that hasn’t been edited since that date, and third-party content you don’t fund or control (Article 2(4)).
    • Location doesn’t matter. A US, UK, Swiss, Australian or Canadian company that sells to consumers in the EU must comply for those EU services.
    • Service providers must explain how the service meets the requirements and make that information public in an accessible format (Article 13 and Annex V). In practice, that’s an accessibility statement.

    Does the EAA apply to my Joomla site? A quick test

    Your Joomla site… EAA likely applies?
    Runs a shop (VirtueMart, HikaShop, J2Commerce, etc.) selling to EU consumers Yes (e-commerce service)
    Takes bookings or paid subscriptions from EU consumers online Very likely (contract concluded online)
    Is a brochure or blog site with a contact form only Usually not directly, but see the other laws below
    Is a B2B portal that only sells to businesses Usually not (the EAA covers consumers)
    Belongs to a business with fewer than 10 staff and ≤ €2M turnover/balance sheet Exempt for services, but still encouraged
    Belongs to an EU public-sector body Covered by the Web Accessibility Directive, which uses the same EN 301 549 standard
    Table of which Joomla sites the European Accessibility Act applies to

    Even when the EAA doesn’t apply, accessibility rules elsewhere often do. Examples include the UK Equality Act 2010, the US ADA, Australia’s Disability Discrimination Act and Ontario’s AODA. They all point to WCAG in one form or another, so a single WCAG 2.2 AA approach covers every market.

    WCAG 2.1 or WCAG 2.2: Which Should Joomla Sites Target?

    The EAA states its requirements in functional terms. A service that conforms to a harmonised standard cited in the EU Official Journal is presumed to conform (Article 15). That standard is EN 301 549:

    • EN 301 549 V3.2.1 (2021) is still the legal reference today. Its web requirements match WCAG 2.1 Level AA.
    • EN 301 549 V4.1.1 was adopted on 24 August 2026 and published in September 2026. It moves the baseline to WCAG 2.2 Level AA, adds an annex mapping the standard to the EAA, and adds requirements about respecting users’ accessibility preferences. It only becomes the legal reference once the Commission cites it in the Official Journal. The expected date varies by source, with late 2026 being the usual estimate.
    Timeline: EAA from 28 June 2025, EN 301 549 V3.2.1 WCAG 2.1 AA now, V4.1.1 WCAG 2.2 AA next

    Our recommendation: build and audit against WCAG 2.2 AA now. WCAG 2.2 is backwards compatible with 2.1, so meeting 2.2 AA also meets 2.1 AA. And any redesign you start today will go live after the new standard is cited.

    What WCAG 2.2 adds (Level A and AA)

    According to W3C’s “What’s New in WCAG 2.2”, these are the six new A/AA success criteria. 4.1.1 Parsing has been removed.

    Criterion Level What it means on a Joomla site
    2.4.11 Focus Not Obscured (Minimum) AA Sticky headers, cookie banners and chat widgets mustn’t completely hide the element that has keyboard focus
    2.5.7 Dragging Movements AA Sliders, carousels, sortable lists and map pins need a non-drag alternative (buttons, arrows)
    2.5.8 Target Size (Minimum) AA Clickable targets must be at least 24×24 CSS px or well spaced. Watch social icons, pagination and tag links
    3.2.6 Consistent Help A Help options (contact link, phone, chat) appear in the same place on every page
    3.3.7 Redundant Entry A Multi-step forms and checkouts shouldn’t ask for the same information twice
    3.3.8 Accessible Authentication (Minimum) AA Login and registration can’t depend on a cognitive test. Allow paste and password managers, and offer alternatives to puzzle CAPTCHAs

    What Joomla 5 and 6 Already Give You

    Joomla has taken accessibility seriously since version 4. Here’s what core gives you:

    • Cassiopeia, the default site template. The Joomla documentation describes it as “an excellent general purpose accessible and responsive template”. It uses semantic HTML5 landmarks (header, nav, main, footer). The docs also warn that colours you choose must still have enough contrast.
    • Atum, the administrator template. Your editors work in Atum, and it includes accessibility settings. The audit below found issues there too, which matters if staff with disabilities manage content.
    • The Joomla Accessibility Checker (jooa11y). This core system plugin has been included since Joomla 4.1. After you save an article, an Accessibility Check button runs more than 50 tests: missing or weak alt text, skipped or empty headings, unclear link text, missing captions, PDF links and more. Optional checks cover contrast, form labels and readability. You’ll find it under System → Plugins → “System – Joomla Accessibility Checker”. As the Joomla manual puts it, it identifies problems but doesn’t fix them.
    • Language attributes are set from the content language, and multilingual sites can mark up each language.
    • Alt-text fields in core media (intro and full-text images) and a “No description” option for decorative images.

    We tested the checker on a real Joomla 5.4 site. We published a deliberately broken article (an image with no alt text, “click here” links, a skipped heading level, low-contrast text and a table with no header cell) and ran the built-in checker. It immediately flagged 6 errors and 3 warnings, pinpointing each one on the page. The same checker ships in Joomla 6.2, the latest version.

    Joomla Accessibility Checker flagging 6 errors and 3 warnings on a test article

    We also ran axe-core against a clean default Cassiopeia page and it reported no violations — a useful reminder that an empty default install looks fine, but real sites fail on content, templates and extensions, which is exactly what the audit below and the checklist address.

    Where core still falls short: the 2026 audit

    In 2026 the Joomla project commissioned an independent WCAG 2.2 AA audit by Axess Lab. It covered Atum, Cassiopeia, login and MFA, the Media Manager, the installer and update process, and forms. According to the Joomla Community Magazine summary and the published report, it found 42 issues. The ones that matter for a typical public website include:

    • No skip link in Cassiopeia by default. Keyboard-only users have to tab through the whole menu on every page.
    • Low contrast for focus states and the current menu item (below 3:1).
    • Tag links without context for screen-reader users.
    • Undefined focus styles in Atum’s navigation, plus Media Manager issues with roles, states and keyboard use.

    The good news is that the Joomla project is publishing this openly and working through the fixes. Until those fixes ship in a release you’re running, these gaps are yours to close.

    Keep in mind that core is rarely the main problem. On most Joomla sites we audit, the failures come from third-party templates, page builders, sliders, popups, cookie banners, forms and years of content.

    The Joomla Accessibility Checklist (Native Fixes First)

    Work through these in order. Each item says how to fix it with what Joomla already offers.

    1. Audit before you change anything

    • Turn on the jooa11y plugin and check your most-visited articles.
    • Run a free automated scan (for example WAVE or axe DevTools) on your home page, a category page, an article, a form page and your checkout or booking flow.
    • Test by keyboard: unplug the mouse and use Tab, Shift+Tab, Enter and Escape through the menu, forms, popups and checkout.
    • Do a quick screen-reader check (NVDA on Windows, VoiceOver on Mac or iOS).
    • Automated tools only catch part of the issues. W3C’s Evaluating Web Accessibility overview explains why manual checks are essential.
    Free accessibility testing toolkit: jooa11y, axe, WAVE, keyboard and screen reader

    2. Template: skip link, focus and contrast

    • Add a “Skip to main content” link in a child template of Cassiopeia (or your own template), as the first focusable element and pointing to <main id="main">.
    • Make focus visible. Add a clear :focus-visible outline in user.css with at least 3:1 contrast against its background.
    • Check colour contrast for body text (4.5:1), large text (3:1) and UI parts such as buttons, form borders and the current menu indicator (3:1). Use the WebAIM Contrast Checker.
    • Make sure sticky headers don’t cover focused elements (WCAG 2.2 2.4.11). Add scroll-padding-top equal to the header height.

    3. Images and media

    • Give every meaningful image real alt text that describes its purpose, not “image of…”. Mark decorative images as decorative.
    • Linked images need alt text that describes where the link goes.
    • Videos need captions. Audio needs a transcript.
    • Add a title attribute to every YouTube, Vimeo or map iframe.

    4. Headings and content structure

    • One H1 per page (usually the article title), then H2 and H3 in order with no skipped levels.
    • Use real lists, not lines starting with dashes. Don’t use bold paragraphs as headings.
    • Write link text that makes sense out of context. Avoid repeated “Read more” links pointing to different pages. Joomla’s “Read more” layout can include the article title in a template override.
    • Warn users when a link opens in a new tab or points to a PDF.

    5. Forms, login and checkout

    • Every input needs a visible <label>. A placeholder isn’t a label.
    • Error messages must say what went wrong and how to fix it, and they must be announced to screen readers.
    • Mark required fields in text, not only with colour or an asterisk.
    • Allow paste into password fields and don’t block password managers (WCAG 2.2 3.3.8). Offer a CAPTCHA alternative.
    • In checkout, don’t ask for the same address twice. Offer “same as billing” (3.3.7).

    6. Menus, sliders, popups and cookie banners

    • Drop-down menus must open with the keyboard and expose aria-expanded.
    • Carousels need pause controls and keyboard and button navigation, not drag-only (2.5.7). Avoid auto-rotating hero sliders.
    • Popups and modals must move focus inside, keep focus there, close with Escape and return focus when closed.
    • Cookie banners are a common blocker. They must be keyboard-operable, readable by screen readers and must not hide focused content.

    7. Documents

    • PDFs published or edited since 28 June 2025 should be accessible (tagged, with reading order and alt text), or have an HTML alternative.

    8. Publish an accessibility statement

    • Create a Joomla article (or menu item) called Accessibility and link it in the footer. Say which standard you target (EN 301 549 / WCAG 2.2 AA), known limitations, the date of your last review, and how users can report problems and get content in another format. The EU’s model accessibility statement for public-sector sites is a useful template, and Annex V of the EAA lists what service providers must explain.

    9. Keep it compliant

    • Make accessibility part of your publishing workflow. Editors should run jooa11y before they publish.
    • Re-test after every template, extension or Joomla update.
    • Keep a short log of what you tested, when and what you fixed. If a regulator or customer asks, it’s your evidence.
    Joomla EAA and WCAG 2.2 AA compliance checklist by area with source-level fixes

    Compliance checklist at a glance

    AreaFix at the sourceWCAG hooks
    TemplateSkip link, visible focus (≥3:1), colour contrast, scroll-padding-top1.4.3, 2.4.1, 2.4.7, 2.4.11
    Images & mediaReal alt text, decorative images marked, captions, transcripts, iframe titles1.1.1, 1.2.x
    Headings & structureOne H1, no skipped levels, real lists, meaningful link text1.3.1, 2.4.4, 2.4.6
    Forms, login & checkoutVisible labels, clear announced errors, allow paste, no redundant entry3.3.1, 3.3.2, 3.3.7, 3.3.8
    Menus, sliders, popups, cookie bannersKeyboard operable, non-drag alternative, focus trap + Escape, don’t obscure focus2.1.1, 2.4.11, 2.5.7
    DocumentsTag PDFs or provide an HTML alternative1.3.1, 1.1.1
    Statement & processPublish an accessibility statement; re-test after every updateEAA Annex V

    Why an Overlay Widget Alone Won’t Make You Compliant

    “One-line” accessibility overlays promise instant compliance. Regulators don’t accept that claim. In January 2025 the US Federal Trade Commission ordered accessiBe to pay $1 million over claims that its AI widget could make any website WCAG-compliant. The final order bars it from making such claims without evidence.

    FTC accessiBe one million dollar order: an overlay widget alone will not make a site compliant

    The reason is simple. WCAG is about the HTML, structure and behaviour of your site. If your form has no labels, your slider traps focus or your checkout repeats fields, a floating toolbar doesn’t change that. Fixes have to happen in the page itself.

    A visitor toolbar can still help people. Text size, contrast, dyslexia-friendly fonts and read-aloud tools are genuinely useful to some visitors. Just treat it as an extra on top of a site that’s already accessible, not as a replacement for one.

    Fixing What Core Can’t: A Practical Path

    Template overrides and careful editing will get you a long way. But on a site with hundreds of articles, many extensions and many editors, fixing everything by hand is slow and easy to break on the next update. That’s the gap we built two tools for at JoomlaX:

    • Easy WCAG fixes common accessibility gaps in the HTML Joomla sends to the browser. It adds missing alt and iframe titles, names icon-only links and buttons, sets the page lang, labels unlabelled inputs, adds a skip link and new-window warnings. It then reports what still needs a human. Your articles in the database stay untouched, and it runs on your own server with no overlay script and no third-party CDN. It’s deliberately honest: it doesn’t claim WCAG AA certification, because no plugin can.
    • Easy Accessibility is a self-hosted visitor toolbar with text size, contrast, Read Mode, a dyslexia-friendly font, on-device read-aloud and more. You can sort or remove any tool. Use it alongside source-level fixes, as described above.

    Both run on Joomla 4, 5 and 6.

    If you’d rather have it done for you, our Joomla development team runs accessibility audits against WCAG 2.2 AA, fixes templates and overrides, cleans up content and writes your accessibility statement. We often combine this with a Joomla 6 upgrade or performance optimisation, because accessible, well-structured pages also tend to load faster and rank better.

    Accessibility Rules Beyond the EU (Quick Reference)

    Market Main rule Technical benchmark
    EU (DE, IT, NL, FR, PL…) EAA (private, consumer services); Web Accessibility Directive (public sector) EN 301 549 → WCAG 2.1 AA now, 2.2 AA next
    United States ADA. For state and local government, the DOJ Title II rule requires WCAG 2.1 AA (compliance dates now April 2027 and April 2028). US site owners: see our Joomla WCAG and ADA compliance guide. WCAG 2.1 AA (Title II); WCAG is widely used in private-sector cases
    United Kingdom Equality Act 2010; public sector accessibility regulations WCAG 2.2 AA is the UK government benchmark for the public sector
    Canada Accessible Canada Act (federal); AODA (Ontario) WCAG 2.0 AA under AODA; EN 301 549 referenced federally
    Australia Disability Discrimination Act 1992 WCAG is the accepted reference
    Switzerland Disability Discrimination Act (BehiG) at home; EAA applies when selling to EU consumers eCH-0059 / WCAG

    Because nearly all of these point to WCAG, one WCAG 2.2 AA programme covers every market you sell in.

    What happens if you don’t comply?

    The EAA is enforced by each EU member state, so penalties are set in national law and vary by country rather than by the directive itself. Enforcement typically means a complaint to a national authority, an order to fix the service, and fines or a suspension of the service if you don’t. Germany’s transposing law (the BFSG), for example, provides for fines and, as a last resort, having a non-compliant service taken down. Because the exact amounts and procedures differ per country, treat “it’s only a small fine” as a risky assumption and check the rules in each market where you sell. Beyond regulators, inaccessible checkouts also lose real customers.

    Frequently Asked Questions

    Is Joomla WCAG compliant out of the box?

    Not fully, and no CMS is. Joomla 5 and 6 ship an accessible default template (Cassiopeia) and a built-in checker (jooa11y). But the independent 2026 WCAG 2.2 AA audit found 42 issues across core, including a missing skip link and low-contrast focus states in Cassiopeia. Compliance also depends on your template, extensions and content. For US ADA rules and a step-by-step audit, see our Joomla WCAG and ADA compliance guide.

    When did the European Accessibility Act start applying to websites?

    On 28 June 2025. It covers e-commerce and other consumer services provided after that date. Some existing content is excluded, such as pre-recorded media and office files published before that date, and archived content that hasn’t changed since.

    Does the EAA apply to small businesses?

    Microenterprises providing services, meaning fewer than 10 employees and no more than €2 million in annual turnover or balance sheet total, are exempt from the service requirements. Small and medium-sized businesses above that threshold aren’t exempt.

    Does the EAA apply to companies outside the EU?

    Yes, if they provide covered services, such as online sales, to consumers in the EU. Where your company is based doesn’t matter.

    Should I aim for WCAG 2.1 or WCAG 2.2?

    Aim for WCAG 2.2 AA. EN 301 549 V3.2.1 (WCAG 2.1 AA) is still the legal reference, but V4.1.1, published in September 2026, moves to WCAG 2.2 AA. And meeting 2.2 AA also meets 2.1 AA.

    Will an accessibility plugin or overlay make my Joomla site compliant?

    Not on its own. Plugins that fix the HTML at the source and report what’s left can save a lot of time, but a person still has to test keyboard use, forms and content. Toolbar-only overlays don’t fix the underlying code, and the US FTC has fined a vendor for claiming they do.

    How do I check my Joomla site’s accessibility for free?

    Turn on the core “System – Joomla Accessibility Checker” plugin, run WAVE or axe on key templates, then test every page type by keyboard and with a screen reader. The automated tools find a share of the issues, and manual testing finds the rest.

    Do I need an accessibility statement on my Joomla site?

    Under the EAA, service providers must publicly explain how their service meets the accessibility requirements, and an accessibility statement is the standard way to do that. Public-sector sites in the EU must publish one under the Web Accessibility Directive.


    Disclaimer: This article is general information about accessibility standards as of October 2026. It is not legal advice. National implementations of the EAA differ, so check your obligations with a qualified adviser in each market where you operate.

  • How to Import and Export Users in Joomla (CSV & Excel Guide)

    How to Import and Export Users in Joomla (CSV & Excel Guide)

    Short answer: Joomla 4, 5 and 6 have no built-in tool to bulk import or export users. Your options are a database import or export through phpMyAdmin, which works but skips Joomla’s own save logic, or a user import/export extension such as JoomlaX User Import Export, which handles CSV, Excel, JSON and XML files with field mapping, validation and password options. This guide walks through both, step by step.

    In this guide: what Joomla can and can’t do natively, the manual phpMyAdmin method and its risks, step-by-step import and export with an extension, a ready-to-use CSV template, troubleshooting, best practices and an FAQ.

    Does Joomla Have a Built-in User Import or Export?

    No. In Joomla 4, 5 and 6, Users: Manage lets you create, edit, block, activate, delete and batch-process existing users (for example, adding them to a group), but there is no Import or Export button. You can’t upload a CSV of new accounts, and you can’t download your user list as a spreadsheet.

    The closest core feature is the Privacy component, which can export the data held about a single user in response to a data request. That’s built for privacy compliance, one person at a time, not for bulk migration or reporting.

    That leaves two practical routes:

    • Manual database work with phpMyAdmin or another MySQL tool.
    • A dedicated extension that imports and exports from the Joomla administrator.
    NeedJoomla corephpMyAdmin / SQLUser import/export extension
    Bulk import new users from CSV or ExcelNoYes, if you match the table structure yourselfYes
    Export users to a spreadsheetNoYes, raw table dataYes, with chosen fields and filters
    Map your own column namesNoNo, columns must match the tableYes
    Assign user groupsOne user at a time, or batch existing usersSeparate mapping tableYes, from a column or a default group
    Custom fields and profile dataEdit per userSeparate tables, manual joinsSupported
    Validation before importN/ANoneYes
    Runs Joomla user plugins on saveN/ANoDepends on the extension
    Skill levelN/AComfortable with databasesJoomla administrator

    Option 1: Import and Export Users With phpMyAdmin

    If you’re comfortable with databases, you can move users directly between Joomla’s tables. The Joomla documentation page on bulk uploading users describes this approach. It was written for older Joomla versions, so treat it as a concept, not a recipe for Joomla 5 or 6.

    Which tables hold Joomla users?

    Your table prefix will differ from the #__ placeholder below:

    • #__users: core account data such as name, username, email, password hash, block status and registration date.
    • #__user_usergroup_map: one row per user and group pair (user_id, group_id).
    • #__user_profiles: profile plugin data such as address and phone, if the User – Profile plugin is enabled.
    • #__fields_values: values of user custom fields.

    Exporting with phpMyAdmin

    1. Open phpMyAdmin from your hosting control panel and select the Joomla database.
    2. Select the #__users table and open the Export tab.
    3. Choose CSV (or SQL if you’re moving to another database) and download the file.
    4. Repeat for #__user_usergroup_map if you need group memberships, then join the data in a spreadsheet.

    Importing with phpMyAdmin

    1. Take a full backup of the site and database first.
    2. Prepare a CSV whose columns exactly match #__users, with unique usernames and emails.
    3. Import it into #__users using phpMyAdmin’s Import tab.
    4. Add matching rows to #__user_usergroup_map so every user belongs to at least one group (usually Registered). Without a group, the account won’t behave like a normal user.
    5. Log in as a test user to confirm the account works.

    The catches with the database method

    • Passwords. Joomla stores password hashes, not passwords. You can’t import plain-text passwords into #__users. Either copy hashes from a compatible Joomla source or leave them unusable and have users reset their password.
    • No validation. Nothing checks for duplicate emails, invalid addresses or missing fields before rows go in.
    • Joomla plugins don’t run. Writing to the database skips Joomla’s user save events, so integrations that react to new users, such as newsletter subscriptions or welcome emails, never fire.
    • Groups, profiles and custom fields live elsewhere. You have to build and import each related table yourself and keep the user IDs aligned.
    • Easy to break. One wrong column on a live site can lock out users. Always test on a staging copy.

    The database route is fine for a one-off copy between two Joomla sites you control. For spreadsheets from clients, repeated imports or anything with custom fields, an extension is safer and faster.

    Option 2: Import and Export Users With JoomlaX User Import Export

    JoomlaX User Import Export is a Joomla component (we build it at Infyways) that brings import, export, field mapping, validation, password handling, saved templates and operation logs into the Joomla administrator. The steps below follow the official documentation.

    TaskSupported formats
    Export usersCSV, Excel (XLSX), JSON, XML, SQL
    Import usersCSV, Excel (XLSX/XLS), JSON, XML

    Requirements and installation

    • Joomla 5.x or 6.x
    • PHP 8.1 or higher (8.2+ recommended)
    • MySQL 5.7+ or MariaDB 10.3+
    • Excel (XLSX) files need the PhpSpreadsheet library. Without it, CSV still works fully.

    Install it like any Joomla extension: go to System > Install > Extensions, upload com_userimportexport.zip, then open Components > User Import Export. The dashboard shows user statistics, quick Import and Export buttons, and recent operations. Before your first import, open Options to review password handling, log retention and access permissions.

    How to Import Users Into Joomla From CSV or Excel

    Step 1: Prepare your import file

    Put column headers in the first row and save the file as UTF-8 so accented characters survive. At minimum, each row needs a username and an email, and a name is recommended. On the Import page you can click Download Sample Template to get a pre-formatted CSV. See the template section below for the full column list.

    Step 2: Upload the file

    Go to Components > User Import Export > Import and drag your CSV, XLSX, XLS, JSON or XML file onto the upload area, or click to browse. CSV delimiters (comma, semicolon, tab or pipe) are detected automatically, which helps with spreadsheets saved in European regional settings.

    Step 3: Map your columns to Joomla fields

    Click Auto-Detect to map columns by their header names. Common variations are recognized, so email, e-mail and mail all map to Email. Then check each dropdown and fix any column that should go somewhere else. You can map to:

    • Core fields such as username, email, name and block status
    • User groups
    • Profile fields, using profile_ columns such as profile_phone or profile_city
    • Joomla user custom fields that store a single value (text, list, radio and similar), listed under “Custom Fields” in the mapping dropdown

    Step 4: Choose the import mode

    This decides what happens when a row matches an existing account. Existing users are matched by email or username.

    Import modeWhat it doesUse it when
    Add New OnlyCreates new users and skips existing onesOnboarding a fresh list without touching current accounts
    Update Existing OnlyUpdates matching users and skips new onesCorrecting emails, groups or profile data in bulk
    Add and UpdateCreates new users and updates existing onesSyncing a master spreadsheet with your site

    You can also set a Default User Group for rows that don’t have a groups column.

    Step 5: Decide how passwords are handled

    • Generate Random: creates a secure password for each new user. Leaving the password cell empty also triggers this.
    • Import from File: plain-text passwords in the file are hashed on import. Pre-hashed bcrypt values, for example from another Joomla site, are detected and kept as they are.
    • Require Reset: forces users to set a new password on their first login.

    There’s also a Send email option. When it’s on, each new user gets one welcome email with their username and either the generated password or a link to set one. When it’s off, imported users get no email.

    Step 6: Validate before you import

    Click Validate. The component checks email formats, username rules, required fields, duplicates inside the file and users that already exist on the site, and lists row-by-row errors and warnings. Fix problems in your source file and upload it again. It’s much easier than cleaning up bad accounts later.

    Step 7: Run the import and review the log

    Click Import and watch the progress. The result shows how many users were created, updated and skipped. If rows were skipped or failed, open the Logs view, click Report to see each row and the reason (for example, “User already exists (add-only mode)”), and download the report as a CSV. Users that imported successfully stay in place, so fix the remaining rows and re-import them with Update Existing or Add and Update.

    After the import, the component runs Joomla’s normal user-save event, so plugins that react to new users, such as newsletter list rules, run as if you’d saved each user by hand. Imported and updated users are also recorded in the User Actions Log when your site logs Users events.

    How to Export Joomla Users to CSV or Excel

    Step 1: Open Export and choose a format

    Go to Components > User Import Export and click Export. Pick the format for the job:

    • CSV for spreadsheets and other systems, with a comma, semicolon, tab or pipe delimiter.
    • Excel (XLSX) for reports, with styled headers, auto-sized columns, a frozen header row and filters.
    • JSON for APIs and applications.
    • XML for systems that expect XML.
    • SQL for database migration, as INSERT statements.

    Step 2: Select the fields

    Include only what you need: core fields (ID, username, name, email, registration date, last visit, block status), user groups, profile data, administrator user notes and any custom fields created for users.

    Step 3: Filter the users

    Narrow the export by name, username or email, user group, activation or blocked status, registration date range or last-visit date range. For example, export only the Registered group, or users who haven’t logged in this year.

    Step 4: Set password handling

    Choose to exclude passwords (best for reports), include the hash (only for moving users to another Joomla site), or use a placeholder. Plain-text passwords can never be exported, because Joomla only stores hashes.

    Step 5: Preview, export and save as a template

    Click Preview to see the first 10 matching records, then Export to download the file. If you’ll run the same export again, click Save as Template. Saved templates keep the format, fields, filters and options, and you can run them again from the Templates menu. Previous export files can also be downloaded again from the Logs until the retention period you set clears them.

    Joomla User Import CSV Template

    This example comes from the extension’s documentation. Copy it into a text editor, save it as a .csv file in UTF-8, and replace the sample rows with your own:

    username,email,name,password,groups,block,profile_phone,profile_city
    johndoe,john@example.com,John Doe,ChangeMe123!,Registered,0,+1234567890,New York
    janedoe,jane@example.com,Jane Doe,SecurePass456!,"Registered, Author",0,+0987654321,Los Angeles
    bobsmith,bob@example.com,Bob Smith,,Registered,0,,London
    ColumnWhat it holdsRequired
    usernameUnique login name, 3 to 150 charactersYes
    emailUnique, valid email addressYes
    nameFull display nameRecommended
    passwordPlain text (hashed on import). Leave empty to auto-generateOptional
    groupsGroup names, comma-separated inside quotes for more than oneOptional
    block0 = active, 1 = blockedOptional
    profile_*Profile fields such as profile_phone or profile_cityOptional

    JSON imports use an array of user objects, for example [{"username": "johndoe", "email": "john@example.com", "name": "John Doe", "groups": ["Registered"]}]. XML imports use a <users> root with one <user> element per account.

    How to Migrate Users From One Joomla Site to Another

    1. Back up both sites.
    2. On the old site, export users with core fields, groups, profile data and custom fields, and choose include hashed passwords.
    3. On the new site, create the same user groups and user custom fields, so the names match.
    4. Import the file with Add and Update and Import from File for passwords. The bcrypt hashes are detected and kept, so users can log in with their existing passwords.
    5. Validate first, fix any errors, then import and check the log.
    6. Log in as a few test users and confirm their groups and access levels.

    If you’re moving the whole site, not just users, follow our guide to transferring a Joomla site to a new server. If you’re coming from Joomla 3, read how to upgrade Joomla 3 to Joomla 6 first, because a full upgrade carries users over without any import.

    Troubleshooting Joomla User Imports and Exports

    The file upload fails

    Check PHP’s upload_max_filesize setting, make sure the file type is CSV, XLSX, XLS, JSON or XML, and confirm the file isn’t corrupted.

    Columns don’t auto-map

    Headers must be in the first row. Remove special characters from header names and use standard names like username, email and name.

    Validation errors on usernames or emails

    Usernames must be unique and 3 to 150 characters long. Emails must be valid and unique, both inside the file and against existing users.

    Excel export isn’t available

    XLSX export needs the PhpSpreadsheet library (composer require phpoffice/phpspreadsheet). Use CSV in the meantime.

    The export file is empty

    Your filters are probably too narrow. Make sure at least one field is selected and that users exist in the chosen groups.

    Large imports time out

    Reduce the batch size in Options, raise PHP’s max_execution_time, or split the file into smaller batches.

    Special characters look broken

    Save the file as UTF-8. Excel’s default CSV encoding can mangle accented names.

    Best Practices for Bulk User Imports

    1. Back up first. See how to back up a Joomla website.
    2. Test on staging with a small, representative batch before the full file.
    3. Clean the source file: remove duplicates, fill required fields and fix invalid emails.
    4. Create groups and custom fields first so mapped values have somewhere to go.
    5. Choose the import mode on purpose. Add New Only is the safest default.
    6. Treat exports as sensitive. Exclude passwords unless you’re migrating, store files securely and delete them when you’re done.
    7. Read the log after every run instead of assuming every row went in.

    FAQ

    Can Joomla import users from CSV without an extension?

    Not from the administrator. Joomla 4, 5 and 6 have no user import feature. Without an extension, you’d have to import into the database tables with phpMyAdmin, which skips validation and Joomla’s user plugins.

    How do I export all users from Joomla to Excel?

    Core Joomla can’t do it. Use an extension like JoomlaX User Import Export and choose Excel (XLSX) or CSV, or export the #__users table from phpMyAdmin as CSV and open it in Excel.

    Can I import users with their existing passwords?

    Yes, if the hashes come from a compatible source such as another Joomla site. JoomlaX User Import Export detects bcrypt hashes and keeps them, so users can log in with their current passwords. Hashes from incompatible systems won’t work, so use Require Reset instead.

    How do I add imported users to specific user groups?

    Add a groups column with group names, separated by commas for more than one, or set a Default User Group in the import options.

    Can I update existing Joomla users in bulk?

    Yes. Use the Update Existing Only or Add and Update import mode. Users are matched by email or username.

    Are Joomla custom fields included?

    Yes. User custom fields can be exported, and single-value custom fields can be imported and mapped to your file’s columns.

    Will imported users get a welcome email?

    Only if you enable Send email during the import. Each new user then gets one email with their username and a password or a link to set one.

    Which Joomla versions does JoomlaX User Import Export support?

    The documentation lists Joomla 5.x and 6.x, with PHP 8.1 or higher.

    Need Help Moving Your Joomla Users?

    For a simple list, the steps above are all you need. For migrations from other platforms, complex custom fields or sites with thousands of members, our Joomla development team can plan and run the move, or you can hire a Joomla developer for the project. If your site needs ongoing care afterwards, see our Joomla support and maintenance plans.

    Ready to try it? See JoomlaX User Import Export and the documentation.

  • Joomla Module Showing on the Wrong Pages

    Joomla Module Showing on the Wrong Pages

    A Joomla module shows on the wrong pages when its Menu Assignment does not match the menu item Joomla used for that request (the Itemid). “On all pages except those selected,” a Home menu item that is not the URL you think, the Language Filter, and duplicate module copies are the usual causes. The module is published and the position works. The page map is wrong.

    This is not an empty position. If the slot never renders on any page, read Joomla module position not showing first. Here you already see the module. You see it on Home when it should only be on Contact, or on every article when you ticked one menu item, or in two languages at once.

    Menu Assignment options: all pages, selected pages, all except selected

    Joomla does not assign modules to URLs. It assigns them to menu items. Get the Itemid wrong and the module follows the wrong page.

    What you will learn

    • The four Menu Assignment values and what each actually does
    • Why Home is a menu item, not “the slash URL”
    • What happens on articles that have no menu item of their own
    • How Language Filter hides or doubles modules
    • How duplicate copies (Save as Copy) produce “it is everywhere”
    • A click order that fixes the map without guessing

    Official assignment help: How do you assign a module to specific pages? and the Joomla 4/5 user manual Module display by menu item.

    How Joomla decides “this page”

    Every frontend request Joomla can map has an Itemid: the id of a menu item. Modules in System → Site Modules look at that Itemid, plus Access and Language.

    They do not look at the article id first. They do not look at the SEF path as a string. If you open an article from a blog, a tag list, a search result, or a module link, Joomla may reuse Home’s Itemid or another nearby item. The module then follows that Itemid, not the article you have in your head.

    That is why “I assigned it only to News / Article / My Story” still shows the login module on that story: the request never used that article’s menu item.

    Assignment What Joomla does Typical mistake
    On all pages Every Itemid You meant “all except Home”
    No pages Never Left over from a test. Looks like unpublished.
    Only on the pages selected Only ticked menu items You ticked a hidden duplicate, not the item in the main menu
    On all pages except those selected Every Itemid except the ticks You ticked nothing, so except-nothing means everywhere

    Default for a new module is On all pages. Save as Copy keeps that unless you change the tab.

    Step 1: Read the Menu Assignment tab on the live module

    1. System → Site Modules.
    2. Filter by Position so you are not editing a draft copy.
    3. Open the module that actually appears on the wrong page (title in the frontend chrome if titles are on).
    4. Open Menu Assignment.

    Write down:

    • The Module Assignment dropdown value.
    • Which menus are expanded. A collapsed tree hides ticks.
    • Whether Home is ticked. Home is often not the first row. It can sit in a second menu named “Hidden” or “System.”

    If Assignment is On all pages, Joomla is doing what you asked. Change the dropdown before you blame Language or the template.

    Use Expand: All so you see every item, including unpublished and hidden-menu items. Hidden menus still have Itemids. Pages that use them still count.

    Step 2: Fix “On all pages except” the way the manual describes

    The user manual’s breadcrumbs example is the pattern: On all pages except those selected, then tick only the pages that must not have the module.

    For “everywhere except Home”:

    1. Set Assignment to On all pages except those selected.
    2. Click None on Assign to Menu Items so the tree is clear.
    3. Tick Home (the default menu item, star in Menus).
    4. Save. Check the site.

    If you tick Home and leave other items ticked from an earlier “Only on selected” pass, “except” now excludes those too. Clear the tree first.

    If you wanted “only Contact” and you used “except” by accident, the module appears on Home, blog, and everything else. Switch to Only on the pages selected and tick Contact only.

    Official breadcrumbs walkthrough: Module display by menu item.

    Step 3: Treat Home as a menu item, not as “the homepage URL”

    Home is whichever menu item has Default (the star). It can be:

    • Featured Articles
    • a single article
    • a blog category
    • a component view (search, a directory, a shop front)

    The public URL can be / and still be that Itemid. Assigning a module to a different item titled “Home” in another menu does nothing for /. Assigning to the article that is also the default Featured layout does nothing unless that article has its own menu item and the visitor used it.

    Checks:

    1. Menus → All Menu Items. Filter Default or look for the star. That row is Home.
    2. Confirm you ticked that row, not a similarly named item in a second menu.
    3. If you have two languages, you have one default per language. Tick the Home for the language you are testing, or both, depending on the goal.

    A module set to “only Home” will also appear on many orphan pages (next step) because those requests keep Home’s Itemid. That looks like “wrong pages.” It is Itemid inheritance.

    Step 4: Pages with no matching menu item inherit an Itemid

    This is the bug operators hit after they “assigned it to the article menu item.”

    You created Menus → Hidden → My Article (single article). You assigned the banner Only on the pages selected → My Article. It shows when you click that hidden item. It does not show when you click the same article from a category blog, from Featured, or from a related-articles module. Those requests never used My Article’s Itemid.

    The reverse: a module assigned only to Home appears on that same blog article because the blog used Home’s Itemid (or the category blog item, if that is what you clicked).

    Fix, pick one:

    • Put a real menu item on every page that must have unique modules, including a hidden menu used only for Itemid. Assign modules to those items.
    • Assign the module to the blog or category item visitors actually click, not to a hidden single-article item they never use.
    • For “this article only,” a hidden single-article item works only if every link to that article includes that Itemid (menu, or a URL that still carries it). Do not expect /index.php/my-article without Itemid to stay unique.

    Aliases: an Alias menu item is a pointer. Assignment to the alias and assignment to the target are different Itemids. Tick the item whose URL the visitor actually opens.

    Step 5: Language Filter and the module Language field

    On a multilingual site, System → Plugins → System – Language Filter is usually enabled. Each module has a Language field (right side of the Module tab): All, or one content language.

    Rules that produce “wrong pages”:

    • Module Language is English. You are viewing the French Home. The module is absent there (correct) and you think assignment is broken.
    • Module Language is All. You duplicated the module for French but left the original on All. Both copies can show on French pages if assignment also matches.
    • You assigned the English module to French menu items. Menu items are per language. Ticking a French item while the module is English still fails the language check.

    Also check Menus for the same item in each language. “Only on Home” must tick English Home and French Home if the module is All and you want both homepages. If the module is English-only, tick English Home only.

    Language strings in the module chrome (titles) are a different tool: Joomla language overrides. Overrides do not change which pages load the module.

    Step 6: Find duplicate modules before you rewrite assignment

    Save as Copy is how “I fixed assignment and it is still on every page” happens.

    1. System → Site Modules.
    2. Search the title. Sort by Position.
    3. Look for the same module type in the same position: mod_custom twice in sidebar-right, or Login twice.

    One copy is On all pages. One copy is Only on Contact. You edited the Contact copy. The All copy is what you still see on Home.

    Unpublish or delete the extra copy after you confirm which id is in the URL of the module edit screen (id=).

    Duplicates also come from:

    • A template sample-data module you forgot (Cassiopeia “Site” custom modules).
    • A language pack workflow that copied modules per language, then someone set Language back to All.
    • Two login modules, one Guest and one Registered, both assigned to all pages. That is access, not assignment, but it looks like “the module is on the wrong page” after login.

    Step 7: Do not confuse Access, Status, and cache with assignment

    Quick exclusions so you stay on this job:

    • Unpublished never appears. Wrong-pages means it does appear, just not where you wanted.
    • Access (Public, Guest, Registered, Special) changes who sees it, not which Itemid. Guest modules vanish after login. That can look like “it disappeared on this page” when you actually changed user state.
    • Cache: System – Page Cache or conservative cache can keep a Home HTML payload on another URL for a short time. Clear cache after assignment changes (System → Maintenance → Clear Cache). If a CDN sits in front, purge that too.
    • Template style per menu item can change positions. The module still “shows on the wrong page” as in “the sidebar exists on Shop but not on Home” because Shop uses a different style. That is still a layout map. Confirm styles under the menu item, then read the position article if the slot is missing entirely.

    Custom HTML in the module is not assignment. If you need different markup per section, use assignment plus two modules, or a child template override, not one module and a PHP hack in core.

    A worked map (so the options stick)

    Goal: promo banner on all pages except Home, and a different banner only on the Shop menu item.

    Module Position Assignment Ticks
    Promo default top-a On all pages except those selected Home only (the real default item)
    Promo shop top-a Only on the pages selected Shop (and Shop’s language twins if multilingual)

    If Shop is a blog and products are opened without a Shop Itemid, the shop banner will not follow into the product. Add a hidden menu structure for product Itemids, or assign the shop banner to every item in the shop menu tree (Expand, then tick the parent and children).

    Print, feeds, and “component only” pages

    Some URLs are still Joomla menu items (or inherit Itemid) but you do not think of them as pages:

    • Print and email article views often keep the article’s Itemid. A module assigned only to Home should stay off those views if the article has its own item. If print uses Home’s Itemid, the Home modules appear on print. That is the same inheritance as Step 4.
    • Smart Search or search results may use the Search menu item. Assign modules to that item if the search layout should have them, or exclude it with On all pages except.
    • A component with no site template modules in its own index is rare. More often the component uses the site template and still runs jdoc positions. If a shop checkout must be module-free, assign those modules with On all pages except and tick the checkout items.

    Do not fight this with CSS display: none on every extra module. Assignment is the control. CSS hide still downloads the HTML and still runs the module PHP.

    Checks: assignment dropdown, Home star, language, then duplicate copies

    Read the dropdown first. Then Home. Then Language. Then search for a second module in the same position.

    Key takeaways

    1. Modules follow menu Itemid, not the article title in the browser tab.
    2. New modules default to On all pages. Change Menu Assignment or they will be global.
    3. On all pages except requires a clean tree, then ticks only on the pages to exclude. Empty ticks mean everywhere.
    4. Home is the default menu item (star). Tick that row. A second item named Home does not control /.
    5. Articles opened from blogs, tags, or modules often keep Home or blog Itemid. Hidden single-article items do not apply unless the visitor used them.
    6. Language Filter plus module Language All plus a copied module is the usual double-display on multilingual sites.
    7. Search Site Modules for duplicate titles and positions before you rebuild the assignment tree.
    8. Clear cache after you save. Stale page cache looks like assignment did nothing.

    If the layout is right on some menu items and the slot is empty on others because those items use another template, go to module position not showing. For ongoing assignment and multilingual cleanup on a production site, Joomla support and maintenance.

    Related Joomla troubleshooting

    Frequently asked questions

    Why is my Joomla module showing on the wrong pages?

    Menu Assignment does not match the Itemid of the request. The dropdown is still On all pages, you ticked the wrong Home, Language Filter disagrees, or a duplicate module is still global.

    How do I show a module on all pages except the home page?

    Set Module Assignment to On all pages except those selected, clear the tree, tick only the default Home menu item, save, then clear cache. Confirm you ticked the starred Home, not a namesake.

    Why does a module assigned to one article still show on other articles?

    Those other URLs are not using that article’s menu Itemid. They are using Home or the category blog item. Create a menu item for each page that needs unique modules, or assign to the blog item visitors actually click.

    Can Language Filter make a module appear in the wrong language?

    Yes. A module set to All can show beside a language-specific copy. A module set to English will not show on French Itemids. Align Language on the module with the menu items you tick.

    Does Access change which pages a module appears on?

    No. Access changes which users see it on the pages where assignment already allows it. Guest vs Registered is not a substitute for Menu Assignment.

    What does No pages do?

    The module never displays, even if it is published. Use that only as a parking state. It is easy to confuse with unpublished.

    Should I assign modules to alias menu items?

    Assign to the item whose URL the visitor opens. An alias has its own Itemid. If people click the alias, tick the alias. If they click the target, tick the target.