Blog

  • Benefits of Joomla Migration

    Benefits of Joomla Migration

    The benefits of Joomla migration are concrete: you leave an unsupported major (especially Joomla 3 after August 2023), land on a release that still receives security fixes, run on PHP 8.x hosting hosts still sell, and unlock core features that used to need third-party extensions. In project language, a migration is a major structural hop (typically 3.10 to 4.4). A upgrade is the smoother path the project documents for 4.4 to 5 and 5.4 to 6. Both are what buyers mean when they search for Joomla migration benefits.

    Most articles on this topic stop at “security and speed,” or they stop at Joomla 5. Official docs explain why to migrate. Agency posts list three to ten reasons. Almost none combine official terminology, the full 3 through 6 hop map, Joomla 6 auto-updates, support end dates, when you should wait, the Behaviour – Backward Compatibility 6 rules, cleanup ROI, and a staging plan in one place. That is what this guide does, plus how Infyways runs the work from $149 with a free audit within 12 hours.

    What you will learn

    • Migration versus upgrade versus patch update (with the hop order that actually works)
    • Every major benefit: security, PHP and hosting, performance, admin UX, SEO, accessibility, multilingual, core features, Joomla 6 auto-updates
    • Official support windows so you know when urgency is real versus marketing panic
    • Why migration is also a cleanup project (the angle official docs emphasize)
    • What you lose by waiting on Joomla 3 or early 4, and when Joomla 5 owners can wait
    • How to start with Infyways without treating “click Update” as a plan

    Migration, upgrade, or patch: use the right word

    Confusion here is why thin competitor posts mislead people into a one-click 3 to 6 fantasy.

    Change Official framing Example What you should expect
    Patch Update 5.4.2 to 5.4.3 Same major. Use System → Update → Joomla. See update errors
    4.4 to 5.x Upgrade (not a full migration) 4.4.x to 5.4.x Many extensions work; Behaviour – Backward Compatibility helps. Plan on staging
    5.4 to 6.x Upgrade 5.4 to 6.0+ Disable Behaviour – Backward Compatibility (no number). Keep Behaviour – Backward Compatibility 6 enabled. See compat plugin guide
    3.10 to 4.4 Mini-migration / migration 3.10 to 4.4 Template and extension triage. Protostar does not survive
    3.x toward 5 or 6 Multi-hop migration 3.10 → 4.4 → 5.4 → 6 Never a single updater click. Path: 3 to 4, 5, and 6

    Primary sources: Why Migrate, 4.4 to 5 planning, 5 to 6 planning, and the Joomla 6.0 / 5.4 announcement.

    Support windows that decide urgency

    Scare posts skip dates. The Joomla roadmap and project announcements make urgency measurable:

    Line Bugfix / regular support Security-only support What that means for migration
    Joomla 3.10 Ended August 2023 Ended August 2023 Migrate now. There is no official patch line left
    Joomla 4.x Ended (security ended 14 October 2025) Ended Treat as EOL. Move to 5.4 then plan 6
    Joomla 5.4.x Through 13 October 2026 Through 12 October 2027 Safe to stay while extensions catch up for J6, if you are already on 5.4
    Joomla 6.x Through 17 October 2028 Through 16 October 2029 Active feature line. Finish here when staging is green

    So: Joomla 3 and 4 owners have a real security deadline. Joomla 5.4 owners have a planning window, not a midnight panic, unless the host or an abandoned extension forces the move sooner.

    Benefit 1: Security support that still exists

    Joomla 3.10 reached end of life in August 2023. The site does not magically shut off. Official security patches stop. That is the first benefit of migrating: you are on a maintained line again.

    • Core CVEs ship on current 5.x and 6.x.
    • Abandoned Joomla 3 extensions stop being a permanent attack surface once you replace or rebuild them.
    • Hosts and insurers increasingly treat EOL CMS stacks as unacceptable risk.

    Thin “3 reasons” posts mention security once. The operational point is this: every month on EOL core is a month where your risk grows and your vendor options shrink.

    Benefit 2: PHP and database versions you can still buy

    Hosts retire PHP 7 and old MySQL. Joomla 5 needs PHP 8.1 or newer. Joomla 6 needs PHP 8.3 or newer (8.4 recommended), with MySQL 8.0.13+ / MariaDB in the supported range or PostgreSQL 14+ class. Requirements: Joomla technical requirements.

    Target PHP Why migration unlocks hosting
    Joomla 5 8.1+ Matches mainstream shared hosting in 2026
    Joomla 6 8.3+ (8.4 recommended) Keeps the next renewal cycle viable

    Official docs also warn that hosts will not keep ancient stacks forever. Migration is often forced by the server long before the marketing team asks for new features.

    Benefit 3: Performance without the legacy JS tax

    Current Joomla uses modern PHP, a cleaned codebase, and the Web Asset Manager so templates load scripts only when needed. Core no longer ships MooTools. Default templates are built for current Core Web Vitals expectations.

    The caveat competitors skip: speed appears when the template and bloated extensions move with the core. Migrating the CMS and keeping a Joomla 3 club template untouched does not deliver the performance benefit. Related: remove MooTools from Joomla.

    Benefit 4: An administrator people will actually use

    From Joomla 4 onward the back end is a different product: clearer navigation, Guided Tours, a usable media manager (including AVIF on modern releases), and Dark Mode that editors notice. Magazine writers call out the adjustment period from Joomla 3, then the productivity gain. That matches what we see on client handovers.

    Modern Joomla media manager after migration with drag and drop uploads

    Benefit 5: Core features that replace paid extensions

    This is the benefit Why Migrate stresses and most agency blogs underwrite. Current Joomla can cover work that used to need a stack of third-party tools:

    • Custom fields for structured content
    • Workflows for editorial approval
    • Tags and Smart Search instead of legacy Search
    • Media manager improvements instead of a separate DAM for small sites
    • Cassiopeia child-style customization on recent releases without forking the whole template

    Migration is the moment to uninstall unused modules, kill “great ideas” that never launched, and reduce license sprawl. That lowers cost after go-live, not only risk.

    Benefit 6: SEO you can defend

    Joomla does not rank higher because the version number changed. You benefit because:

    • Modern routing and SEF stay maintainable
    • You can keep aliases and ship a 301 map when something must change
    • Schema and accessibility improvements support how Google evaluates pages
    • The site stays fast enough and online during crawl windows

    Rankings die on broken SEF, 500s after a botched live update, or months of downtime. Staging protects that. Troubleshooting: Joomla upgrade issues and Joomla SEO.

    Benefit 7: Accessibility, multilingual, and compliance

    • Accessibility: current admin and Cassiopeia-oriented front ends take WCAG-oriented patterns seriously. Public sector and education RFPs increasingly require that.
    • Multilingual: language handling and related tooling are stronger than on Joomla 3-era stacks, which matters for EU and multi-region sites.
    • Support window: majors follow a planned lifecycle (on the order of multi-year support per major). You get time to plan the next hop instead of living in permanent panic.

    Benefit 8: Joomla 6 features worth finishing the path for

    Posts that stop at “move to Joomla 5” are already dated. From 5.4 into 6 you also gain reasons to complete the journey:

    • Automatic core updates with the secure update framework introduced across 5.4 and 6.0
    • Behaviour – Backward Compatibility 6 so more extensions survive the hop while vendors catch up
    • Extended versioning that reaches further into custom fields and related content structures
    • Language file caching and media manager improvements
    • Editor updates (TinyMCE on the current 6.x line) for day-to-day publishing
    • Child templates and richer content tools that reduce forking Cassiopeia for small design changes

    Before the hop: prove every third-party extension runs on Joomla 5.4 with the older Behaviour – Backward Compatibility plugin disabled. Then upgrade with Behaviour – Backward Compatibility 6 enabled. After vendors ship native J6 builds, disable BC6 to drop the compatibility overhead. Full rules: 5 to 6 planning.

    Product overview: Joomla 6. Community write-up: What is new in Joomla 6.0.

    Benefit 9: The cost of not migrating

    If you stay on What usually happens next
    Joomla 3 No official security line, vendors gone, PHP upgrades break the site
    Early Joomla 4 on PHP 8.0 hosts Host forces PHP up; site fatals; emergency weekend work
    Joomla 5 without a 6 plan You miss auto-update and lifecycle planning; the next hop becomes a fire drill
    Heavy abandoned extensions Every delay makes rebuild cost higher, not lower

    Waiting rarely saves money. It concentrates risk into a single emergency project.

    Who benefits most (urgency map)

    Situation Main benefit Urgency
    Still on Joomla 3 Security + PHP + vendors High
    Joomla 4, host retiring PHP Stay online High
    VirtueMart / custom components Commerce on supported builds High if vendors dropped your major
    Government / education Supported CMS for audits High
    Joomla 5.4, PHP 8.3+, extensions J6-ready Joomla 6 features + lifecycle Upgrade on staging now
    Joomla 5.4, critical extensions not J6-ready Stay secure on 5.4 while vendors catch up Medium: schedule, do not freeze forever
    Agencies with many client sites One standard stack, fewer snowflake servers High for white-label ops

    What thinner articles leave out

    Topic Typical competitor post This guide
    Versions covered Joomla 3 to 5, or 5 to 6 only 3 through 6 with hop order
    Migration vs upgrade Mixed or wrong Official project language in a table
    Support end dates Vague “EOL soon” Roadmap dates for 3, 4, 5.4, and 6
    Joomla 6 auto-updates Often missing Called out as a finish-line benefit
    BC6 plugin rules Skipped or one line Disable old BC, keep BC6, retire later
    When waiting is OK Rarely said J5.4 security window through October 2027
    Cleanup / core replacements Mentioned lightly Tied to Why Migrate and cost reduction
    Staging + SEO cutover Generic “take a backup” Steps, Pre-Update Check, 301 map, Search Console
    Commercial next step Vague contact form Audit in 12 hours, packages from $149

    Step 1: Inventory version, PHP, and extensions

    1. System → System Information: Joomla, PHP, database.
    2. Export or screenshot Manage → Extensions.
    3. Mark each extension: has a current build, needs rebuild, or can be replaced by core.
    4. Pick only the next hop from the table above.

    Step 2: Back up with a restore test

    A migration benefit is worthless without rollback. Take files + database, store a copy off-server, and confirm restore once. Method: how to backup a Joomla website.

    Step 3: Prove it on staging

    Joomla Pre-Update Check used when planning a migration on staging
    1. Clone production to staging.
    2. Run Pre-Update Check. Fix or replace blockers.
    3. Complete the hop. Run Database Fix. Clear caches.
    4. Click through login, forms, multilingual switchers, and checkout if you have a store.
    5. Only then book the production window.

    When something breaks, use the issue map: common Joomla upgrade issues.

    Step 4: Cut over with SEO and support intact

    • 301 map ready for any alias that must change
    • Search Console checked in week one
    • CDN and page cache purged
    • 30 days of watch for extension edge cases

    How Infyways delivers those benefits

    We are not a generic “we love Joomla 5” essay. We migrate production sites:

    • Free compatibility audit within 12 hours (credentials optional for the first pass)
    • Fixed packages from $149 small / $299 medium / custom enterprise and stores
    • 100+ JED extensions in-house, so rebuilds are normal work, not a surprise
    • Staging-first cutover and 30 days of post-launch support on migration defects

    Start: Joomla Upgrade Services.

    Key takeaways

    1. Migration benefits are security, hosting, performance, admin UX, fewer extensions, SEO resilience, accessibility, and Joomla 6 lifecycle features.
    2. Use official words: 3 to 4 is a migration; 4.4 to 5 and 5.4 to 6 are upgrades.
    3. Hop order is 3.10 → 4.4 → 5.4 → 6. No shortcuts.
    4. Urgency follows support windows: EOL on 3/4 is immediate; 5.4 still has a security lane into late 2027.
    5. Cleanup is part of the ROI: drop unused extensions and replace them with core where you can.
    6. Speed and SEO appear only when template and extensions move with the CMS.
    7. Waiting on EOL core increases cost. Fixed-price staging work is cheaper than an emergency rebuild.

    Frequently asked questions

    What are the benefits of Joomla migration?

    You regain security updates, PHP 8 hosting, a modern administrator, vendor-supported extensions, better performance potential, stronger accessibility and multilingual options, and a path into Joomla 5 and 6 features such as automatic core updates.

    Is Joomla 4 to 5 a migration or an upgrade?

    The Joomla project treats 4.4.x to 5.x as an upgrade, not a full migration. Extension checks and staging are still required.

    Is Joomla 5 to 6 a migration?

    No. From 5.4.x it is an upgrade, with Behaviour – Backward Compatibility 6 involved. From Joomla 3 it is still a multi-hop migration.

    Do I need to upgrade from Joomla 5 to Joomla 6 immediately?

    No. Joomla 5.4 remains on a security path through 12 October 2027. Upgrade when templates and extensions are J6-ready and staging is green, not because a headline says “now or never.”

    What is the Behaviour – Backward Compatibility 6 rule before upgrading?

    On Joomla 5.4, disable the older Behaviour – Backward Compatibility plugin (no number in the name) only after extensions run without it. Keep Behaviour – Backward Compatibility 6 enabled for the move into Joomla 6. Disable BC6 later when every extension is native.

    Does my Joomla 3 site stop working after end of life?

    No. It keeps running without official security fixes while hosts and vendors move on.

    Will migration improve Google rankings by itself?

    No. It protects the technical baseline (uptime, SEF, modern HTML performance). Content and links still decide rankings.

    Can core Joomla replace some of my extensions after migration?

    Often yes. Custom fields, workflows, tags, and Smart Search cover many older third-party use cases. That is a deliberate benefit of migrating now.

    How much does Joomla migration cost with Infyways?

    Packages start at $149 for small sites and $299 for medium sites. Enterprise and stores are custom after the free audit.

    How long does it take?

    Small brochure sites can finish in days after staging is ready. Stores and custom components take longer. The audit sets the timeline.

    Where do we start?

    Request a Joomla upgrade audit or contact Infyways.

  • How to Disable Right Click in Joomla

    How to Disable Right Click in Joomla

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

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

    What you will learn

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

    What disabling right click does

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

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

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

    Plugin versus custom code

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

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

    Step 1: Decide the scope

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

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

    Step 2: Install Right Click Disable

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

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

    Step 3: Configure for your content type

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

    Step 4: Test before you call it done

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

    Why template hacks fall apart

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

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

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

    Accessibility, UX, and SEO

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

    When to skip right-click disable

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

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

    Key takeaways

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

    Frequently asked questions

    How do I disable right click in Joomla?

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

    Does disabling right click protect my images?

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

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

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

    Can I disable right click on images only?

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

    Will this hurt SEO?

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

    Why not paste JavaScript into the template instead?

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

    Where do I download Right Click Disable?

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

  • Caching in Joomla

    Caching in Joomla

    Caching in Joomla means storing rendered HTML, component views, and module output so the next guest request skips most database and PHP work. In Joomla 4, 5, and 6 you control three layers: Global Configuration System Cache (Off, Conservative, or Progressive), the System – Page Cache plugin for whole guest pages, and per-module Advanced caching. Handlers decide where copies live (File, APCu, Redis, or Memcached).

    Official docs explain the switches. Deep technical posts explain com_cache internals. LiteSpeed magazine pieces cover one host stack. This guide is the operator map: which mode to pick by site type, what breaks Progressive and Page Cache, Redis and Memcached setup gotchas, how to clear and purge safely, and when caching alone cannot fix a slow EOL site. Infyways upgrades and tunes production Joomla from $149 with a free audit within 12 hours.

    What you will learn

    • The three cache layers and the order they win
    • Conservative vs Progressive vs Page Cache with a decision table
    • File, APCu, Redis, and Memcached: when each handler is right
    • Exclusions for carts, forms, login, and personalised modules
    • Clear vs purge, CLI clean, and stale-content fixes
    • How LiteSpeed (or another edge cache) should sit beside Joomla cache
    • A staging checklist and when to call Infyways

    How Joomla caching is layered

    Think of three increasing levels of aggressiveness. The first layer that can answer usually wins.

    Layer Where you set it What it caches Who it serves
    System Cache (Conservative or Progressive) System → Global Configuration → System → Cache Settings Component views and modules (rules differ) Mostly guests for core content views; access levels are part of the cache id
    Module Advanced tab Each module → Advanced That module only (Use global or No caching) Respects Conservative; ignored for guests under Progressive
    System – Page Cache plugin System → Manage → Plugins Whole HTML page by URL Guests only. Fastest built-in option

    Primary sources: Joomla Cache user guide, caching views and modules (manual), and the LiteSpeed Cache and Redis magazine article.

    Important: turning System Cache to Conservative does not by itself cache the full page. Full-page guest caching needs the System – Page Cache plugin enabled separately.

    Conservative vs Progressive vs Off

    Mode What happens Use when Avoid when
    Off No view or module cache from Global Configuration Debugging, template work, chasing a stale bug Busy production brochure sites
    Conservative (recommended default) Caches eligible component views and modules that allow caching. Module “No caching” is respected Almost every site: membership, forms, stores, multilingual Never the wrong starting point
    Progressive For logged-off users, all modules are cached. Module “No caching” has no effect. Module output often shares a com_modules group file Static brochure sites after careful staging tests Menus that change by page, random modules, login-aware chrome, anything that must differ per Itemid

    Myth to kill: Progressive is not “caching for logged-in users.” Official docs are explicit that core view cachability rules do not flip that way. Progressive is more aggressive module caching for guests.

    Classic Progressive failure: the wrong module appears on the wrong page because one cached module blob was reused across Itemids. If you see that, switch back to Conservative immediately.

    Joomla Global Configuration Cache Settings showing System Cache and Cache Handler

    System – Page Cache plugin

    This is the fastest built-in path. On a hit, Joomla can return stored HTML before most of the site boots. It only serves guests. Logged-in visitors always get a fresh build so names, carts, and private menus stay private.

    Enable System Page Cache plugin in Joomla Plugins manager
    • Enable: System → Manage → Plugins → System – Page Cache
    • It uses the same handler and Cache Time as Global Configuration
    • Exclude menu items and URL patterns for anything dynamic
    • Use Browser Caching sends browser cache headers. Leave it off unless you understand that visitors can keep a page after you clear server cache
    System Page Cache plugin options including excluded menu items and browser caching

    Always exclude (or never page-cache): contact and other forms, search results, login and registration, carts and checkout, tokenised or one-time pages, and any URL that must reflect the current session. Editing an article does not always clear every page that embeds it. Clear the page cache group after content launches that must be instant.

    Cache handlers: File, APCu, Redis, Memcached

    Handler Stores in Best for Watch outs
    File cache/ and administrator/cache/ Default on shared hosting and most single servers Many tiny files on slow disks; purge expired regularly
    APCu PHP shared memory Single server speed win for small items Not shared across nodes; cleared on PHP restart
    Redis Redis server or Unix socket Clusters, high traffic, LiteSpeed object cache stacks Wrong host or socket causes 500s; change handler before killing Redis
    Memcached Memcached server or socket Shared cache across web nodes Often labelled experimental in host UIs; test persistence settings

    Modern Joomla no longer relies on old handlers such as XCache or eAccelerator. If a host guide still lists them, ignore that part.

    Redis tip from real support threads: if you disable System Cache while Redis is already unreachable, you can still get connection errors until you switch the handler back to File (or a working Redis), save, then turn caching off. Flush cache after handler changes.

    Global Configuration fields that matter

    Setting Meaning Practical default
    System Cache Off / Conservative / Progressive Conservative
    Cache Handler Where items are stored File, then Redis on capable hosts
    Platform Specific Caching Adds device type into the cache id No, unless desktop and mobile HTML truly differ on the same URL
    Cache Time Lifetime in minutes (default 15) 15 for mixed sites; lower for news; higher for static brochures
    Path to Cache Folder Custom file path Leave blank unless you know why

    Module Cache Time is in seconds. Global Cache Time is in minutes. Mixing those units is a common misconfiguration.

    Per-module caching

    • Open the module → Advanced → Caching: Use global or No caching
    • Set No caching for login status, live counters, random quotes, carts, and anything personal
    • Under Progressive for guests, No caching is ignored. That is why Progressive breaks dynamic chrome
    • Some modules declare a cache mode in code (static, itemid, and similar). A badly coded static mode can freeze wrong content even on Conservative

    Breadcrumbs is a safe module to use when testing Conservative caching on staging.

    Decision guide by site type

    Site type System Cache Page Cache plugin Handler Notes
    Brochure / marketing Conservative (try Progressive only after tests) On, with form pages excluded File or Redis Biggest easy win
    Membership / ACL content Conservative On for public pages only; exclude member areas File or Redis Access levels belong in cache ids; still exclude personal dashboards
    Multilingual Conservative On File or Redis Language is part of identity; clear cache after language or SEF changes
    VirtueMart / Hikashop / carts Conservative On only for static CMS pages; exclude cart, checkout, account File or Redis Page Cache on cart URLs causes classic “empty cart” bugs
    Heavy community / logged-in traffic Conservative Limited; focus on guest landing pages Redis preferred on busy hosts Page Cache helps guests only
    LiteSpeed host Conservative Often rely on LiteSpeed full-page; keep Joomla Conservative Redis as object cache when offered Magazine guidance: Conservative with LiteSpeed + Redis reduces conflicts

    LiteSpeed, CDN, and Redis together

    Edge page cache (LiteSpeed Cache for Joomla, Cloudflare, or a reverse proxy) sits in front of Joomla. Redis or Memcached as the Joomla cache handler speeds object and view cache behind that. Do not stack three aggressive full-page systems without a purge story.

    • Prefer Conservative when an external full-page cache is already on
    • Let the edge plugin purge on article save when it supports automatic purge
    • Use Redis for shared or high-traffic object cache, not as a substitute for excluding dynamic URLs
    • ESI and logged-in edge features vary by LiteSpeed edition. Test on staging

    Clear Cache vs Clear Expired Cache

    Action Path Removes Use when
    Clear Cache System → Maintenance → Clear Cache Selected groups or everything After template, override, or extension updates; stale homepage; debugging
    Clear Expired Cache System → Maintenance → Clear Expired Cache Only past-lifetime items Routine housekeeping so File handler folders do not fill forever
    CLI clean php cli/joomla.php cache:clean All (or expired with the expired argument) Deploy scripts and cron

    With the File handler you can also empty cache/ via SFTP if the admin is down. That is equivalent to a full clear. Joomla cache is not a database table.

    Step 1: Set a safe baseline on staging

    1. Clone production to staging.
    2. System → Global Configuration → System → Cache Settings: System Cache = ON – Conservative caching, Handler = File, Platform Specific Caching = No, Cache Time = 15.
    3. Save. Browse as a guest. Confirm pages load and dynamic modules still update.
    4. Only then introduce Redis or Progressive on a second staging pass.

    Step 2: Enable Page Cache with exclusions

    1. Enable System – Page Cache.
    2. Exclude contact, search, login, cart, checkout, and account menu items.
    3. Leave Use Browser Caching off for the first week.
    4. As a guest, load a public article twice. Confirm a cache/page entry appears when using the File handler.
    5. Edit that article, clear the page group, and confirm the front end updates.

    Step 3: Tune modules and handlers

    1. Set personal or random modules to No caching (Conservative only).
    2. If the host offers Redis, set handler to Redis, enter socket or host, port 0 for Unix sockets when required, save, then Clear Cache.
    3. Retest guest and logged-in paths, forms, and checkout.
    4. Optional: try Progressive only on a static brochure clone. Revert at the first wrong-module symptom.

    Step 4: Production cutover and monitoring

    • Apply the proven staging settings during a low-traffic window
    • Clear Cache after deploy
    • Watch Core Web Vitals and server CPU for a week
    • Schedule Clear Expired Cache or CLI purge if you stay on File
    • Document exclusions so the next editor does not enable Page Cache on checkout

    Troubleshooting stale or broken cache

    Symptom Likely cause Fix
    Old article text on guests Page Cache still holding URL Clear page group; shorten Cache Time if launches are frequent
    Wrong module on a page Progressive guest module cache Switch to Conservative; clear com_modules
    Empty cart or stuck form Page Cache on dynamic URLs Exclude those menu items and URLs; clear page cache
    Redis connection 500 after “turning cache off” Handler still Redis while server is down Set handler to File while Redis is up, save, then disable caching
    Logged-in users see no speed gain from Page Cache By design Rely on Conservative + Redis; Page Cache is guest-only
    Mobile gets desktop chrome Platform Specific Caching off while serving different HTML Enable only if HTML truly differs; prefer one responsive template

    Related reading: Joomla upgrade issues and fix Joomla update errors when cache problems appear after a version hop.

    When caching is not enough

    Cache multiplies a healthy stack. It does not replace an unsupported Joomla 3 site, an abandoned template full of blocking scripts, or PHP that the host is about to retire. If Time to First Byte stays poor after Conservative + Page Cache on staging, fix the CMS and template path first.

    Infyways runs that path as a service:

    • Free compatibility and performance audit within 12 hours
    • Fixed packages from $149 small / $299 medium / custom for stores and clusters
    • 100+ JED extensions in-house when a cache-hostile extension needs a rebuild
    • Staging-first cutover and 30 days of post-launch support on defects we introduce

    Start: Joomla Upgrade Services.

    What thinner articles leave out

    Topic Typical post This guide
    Versions Joomla 3 or 4 screenshots only Joomla 4 / 5 / 6 settings that still apply
    Conservative vs Progressive One paragraph or a myth about logged-in users Decision table + Progressive failure mode
    Page Cache “Turn the plugin on” Guest-only rule, exclusions, browser caching warning
    Handlers File only, or outdated APC lists File, APCu, Redis, Memcached with cluster notes
    Edge cache Missing or vendor-only LiteSpeed + Redis layering with Conservative default
    Operations Clear Cache button Clear vs purge, CLI, deploy hygiene
    Site types Generic speed claims Brochure, ACL, multilingual, cart matrix
    Next step Affiliate plugin link Staging steps + Infyways audit from $149

    Key takeaways

    1. Start with Conservative caching. Add System – Page Cache for guests with strict exclusions.
    2. Progressive is optional and dangerous for dynamic modules. It is not “logged-in caching.”
    3. Full-page cache is a separate plugin. Global System Cache alone is not full-page cache.
    4. File is fine for most sites. Redis or Memcached help clusters and high traffic.
    5. Global Cache Time is minutes. Module Cache Time is seconds.
    6. Clear the page group after launches that must be instant. Purge expired on File hosts.
    7. Edge cache plus Joomla Conservative plus Redis is a common modern stack. Test purge behaviour.
    8. If the site is EOL or template-bound, upgrade first. Cache cannot patch an unsupported core.

    Frequently asked questions

    What is caching in Joomla?

    It is storing views, modules, or whole guest pages so repeat requests skip most PHP and database work. You control it with System Cache, module Advanced settings, and the System – Page Cache plugin.

    Should I use Conservative or Progressive caching?

    Use Conservative for almost every site. Use Progressive only on static brochure sites after staging tests, because guest modules are force-cached and “No caching” is ignored.

    Does System Cache cache the whole page?

    No. Conservative or Progressive cache views and modules. Whole-page guest caching needs the System – Page Cache plugin.

    Does Page Cache work for logged-in users?

    No. The plugin serves guests only so personalised HTML is never shared between users.

    Is Progressive caching for logged-in users?

    No. That is a common myth. Progressive changes how guest modules are cached. Core view rules for logged-in users stay separate.

    What cache handler should I choose?

    File for standard shared hosting. APCu for a fast single server. Redis or Memcached when you need shared memory cache across nodes or your host recommends it with LiteSpeed.

    Why is my cart empty after enabling cache?

    Page Cache is almost certainly covering cart or checkout URLs. Exclude those menu items and clear the page cache group.

    How do I clear Joomla cache from the command line?

    Run php cli/joomla.php cache:clean from the site root. Use the expired variant for purge-only cleanup in cron.

    Will caching fix a slow Joomla 3 site by itself?

    No. It can help guests, but unsupported core, old PHP, and abandoned templates still need an upgrade path. See benefits of Joomla migration.

    How much does Infyways charge to tune or upgrade a slow Joomla site?

    Packages start at $149 for small sites and $299 for medium sites. Stores and multi-node setups are custom after the free audit.

    Where do we start?

    Request a Joomla upgrade audit or contact Infyways.

  • Disable cookies for visitors in Joomla websites

    Disable cookies for visitors in Joomla websites

    Disabling cookies for visitors on a Joomla website does not mean deleting the core session cookie. That cookie is strictly necessary for forms, CSRF tokens, and login safety. What site owners usually need is to stop non-essential cookies (analytics, marketing, embeds, preference trackers) until the visitor gives informed consent under GDPR, ePrivacy, and similar laws. On Joomla 4, 5, and 6 the practical path is a consent module such as Easy Cookie Alert by Infyways, not a core hack that turns sessions off.

    Thin “7 steps to disable cookies” posts still tell people to kill Global Configuration settings that do not exist, or to patch index.php so guests have no session. That breaks forms and security. This guide is the operator correction: cookie categories, what Joomla core actually sets, how to gate third-party tags, how to configure Easy Cookie Alert, and how to verify the result without inventing a free DIY banner that fights your template.

    What you will learn

    • Necessary vs optional cookies on a real Joomla site
    • Why you should not disable the guest session cookie
    • How consent, Reject all, and prior blocking differ from an information-only bar
    • Step-by-step setup with Easy Cookie Alert on Joomla 4, 5, and 6
    • Google Consent Mode v2, embed freeze, and consent proof
    • How to test in DevTools and what still fails if tags stay in the template

    What Joomla sets by default

    Core Joomla is not an ad network. The Joomla Project’s own cookie policy treats the random session cookie as strictly necessary. It ties the browser to a server-side session so CSRF tokens and forms work. Official core does not ship Google Analytics or marketing pixels. Most compliance risk comes from extensions, template scripts, GTM, and embeds you add later.

    Cookie / data Typical source Consent needed? What to do
    Session cookie (random name) Joomla core No (strictly necessary) Keep it. Document it in your privacy policy
    Session metadata for guests Global Configuration → Session No for the cookie itself You can reduce guest metadata tracking for performance; the session still exists
    _ga, _gid, marketing IDs Analytics / ads / GTM Yes before set Load only after Analytics or Marketing consent
    Social / chat widgets Third-party scripts Usually yes Gate with Functional or a custom category
    YouTube, Maps, Vimeo embeds Articles and modules Often yes (third-party cookies) Freeze embeds until the required category is allowed

    Primary references: Joomla cookie policy, the long-running discussion that core does not ship a full cookie manager, and EU ePrivacy rules that require consent before non-essential storage on the device.

    Do not disable the guest session cookie

    Older forum advice suggests editing index.php to start the site application with session => false for guests, or hacking session table inserts. That belongs in the museum next to Joomla 1.5 tips.

    • Sessions power form tokens. No session means weaker CSRF protection and broken logins.
    • Bots and humans still hit login URLs even if you hide the menu item.
    • Security vendors (including Akeeba guidance historically) treat guest session cookies as required for safe forms.
    • “Disable cookies” in a privacy sense means do not set tracking cookies, not “run a CMS without sessions.”

    If your goal is fewer database writes from guests, use Session settings such as limiting session metadata for non-registered users where your Joomla version supports it. That is a performance tweak. It is not a consent solution and it does not remove the cookie.

    What “disable cookies for visitors” should mean

    Goal Wrong approach Correct approach
    Stop tracking until opt-in Information-only bar that never blocks scripts Prior blocking + Reject all + category prefs
    GDPR / ePrivacy readiness Kill Joomla session Keep necessary cookies; gate optional ones
    CCPA / CPRA “Do Not Sell” EU-only banner copy Optional Do Not Sell link and prefs for US traffic
    GTM / GA4 Fire tags in the template head always Consent Mode v2 default denied, then update on choice
    Embeds Paste iframes freely Freeze until Analytics / Marketing / Functional is allowed

    Why lead with Easy Cookie Alert

    Infyways builds Easy Cookie Alert for Joomla 4, 5, and 6. It is a module (vanilla JS, no jQuery) with Accept all, Reject all, Cookie settings, layouts (Bar, Floating, Modal, Overlay), category script slots, Google Consent Mode v2, embed blocking, optional consent proof logging, and CCPA Do Not Sell support. Full setup notes: Easy Cookie Alert documentation.

    Vendor CMP suites and generic “paste this banner” snippets can work, but on Joomla they often fight template assets or leave tags in index.php. A native module that owns the script slots keeps the consent decision and the tags in one place.

    Step 1: Inventory cookies and scripts

    1. Open the site as a guest in a private window.
    2. DevTools → Application → Cookies. Note first-party and third-party names.
    3. Network tab: find analytics, ads, chat, and social hosts.
    4. List every extension or template feature that injects those tags.
    5. Write a short privacy policy section that names necessary cookies and optional categories.

    If the inventory is mostly session cookies and nothing else, you may only need a clear policy statement. The moment you add GA4, Meta Pixel, Hotjar, or third-party embeds, you need consent gating.

    Step 2: Install and publish Easy Cookie Alert

    1. Download the package from the JED listing and unzip it.
    2. System → Install → Extensions → upload mod_cookiealert_…zip.
    3. Content → Site Modules → Easy Cookie Alert.
    4. Status: Published. Hide Title.
    5. Assign a module position (debug is fine; the banner portals to the document body).
    6. Assign menu items for every public page that needs consent.
    7. System → Clear Cache.

    Step 3: Configure content, layout, and categories

    • Content: message, privacy policy link, Accept / Reject / Settings labels, optional CCPA Do Not Sell copy
    • Layout: start with Bar Bottom; use Overlay or Modal with Force consent when choice must happen first
    • Categories: Necessary stays on; enable Analytics, Marketing, Functional, and custom categories you need
    • Consent days: how long a choice is remembered
    • Consent version: bump when the policy changes so returning visitors are asked again

    Reject all must be as easy as Accept all. A banner that only offers OK is not enough for modern EU expectations.

    Step 4: Move tags into category scripts

    1. Remove GA / ads / chat snippets from the template head and from “custom code” plugins that always fire.
    2. Paste each tag into the matching category script slot in Easy Cookie Alert.
    3. If you use Google Tag Manager, enable Consent Mode v2 so defaults are denied in the head before tags run, then update after the visitor chooses.
    4. Turn on embed blocking if articles include YouTube, Vimeo, or Maps.
    5. Optional: enable consent proof logging when you need anonymised receipts.

    If tags remain hard-coded in the template, the banner cannot undo them. Consent UI without prior blocking is theatre.

    Step 5: Verify as a guest

    1. Private window, no prior consent cookie.
    2. Confirm Reject all leaves analytics and marketing cookies unset.
    3. Confirm Accept all (or category save) loads only what was allowed.
    4. Submit a contact form and confirm it still works (session cookie present).
    5. Reopen Cookie settings from the floating control and change a choice.
    6. Bump consent version on staging and confirm the banner returns after a policy change.

    Multilingual, shops, and logged-in users

    Site type Extra care
    Multilingual Separate Easy Cookie Alert modules per language filter, with translated copy and the same category ids
    VirtueMart / Hikashop Keep checkout and cart cookies in the necessary / functional story; never page-cache checkout; gate only marketing tags
    Membership Logged-in users still need session cookies; consent still applies to marketing tags on public pages
    Heavy GTM Consent Mode v2 first; do not duplicate the same tags in both GTM and module slots

    What thinner articles get wrong

    Claim Reality
    “Turn off cookies in Global Configuration” There is no master switch that removes the session cookie while keeping a safe dynamic site
    “Disable sessions for guests in index.php” Breaks CSRF and forms; outdated advice
    “A notice bar is enough” Non-essential cookies need prior consent and a real Reject path
    “Joomla core tracks users like an ad platform” Core session is necessary; tracking usually comes from what you installed
    “HTTP Headers plugin manages cookies” System – HTTP Headers is for security headers (CSP, HSTS), not consent UI

    When you also need an upgrade

    Consent modules expect a current Joomla 4 / 5 / 6 stack and PHP 8. If the site is still on Joomla 3 with abandoned analytics plugins, fix the platform first. Infyways runs migrations from $149 with a free audit within 12 hours: Joomla Upgrade Services.

    Key takeaways

    1. Do not disable the Joomla session cookie for visitors. It is strictly necessary.
    2. “Disable cookies for visitors” means block non-essential cookies until consent.
    3. Use Accept all, Reject all, and category preferences with prior blocking.
    4. Move analytics and marketing tags out of the template and into consent-controlled slots.
    5. Easy Cookie Alert covers Joomla 4, 5, and 6 with Consent Mode v2, embed freeze, and optional proof logs.
    6. Verify in a private window. A banner that never changes the Network panel is not compliance.

    Frequently asked questions

    Can I fully disable cookies for Joomla visitors?

    No, not if you want a safe dynamic site. Keep the necessary session cookie. Disable or delay optional tracking cookies until consent.

    Does Joomla core require a cookie consent banner by itself?

    Often no, if you only use the session cookie and document it. Yes as soon as you add analytics, ads, or many third-party embeds.

    Is an information-only cookie bar enough for GDPR?

    No. Visitors need a real choice, including Reject all, and non-essential scripts must not run first.

    Will Reject all break my contact form?

    It should not. Forms rely on the necessary session cookie, which stays available.

    What is Google Consent Mode v2 in this context?

    It tells Google tags to default to denied until the consent module updates the choice, so tags do not behave as if consent already existed.

    Where do I get Easy Cookie Alert?

    From the Joomla Extensions Directory listing. Setup details are in the JoomlaX documentation.

    Does System – HTTP Headers disable cookies?

    No. That plugin manages security headers such as CSP and HSTS. It is complementary hardening, not a consent manager.

    How do I re-ask visitors after a policy change?

    Increase the consent version in the module so stored choices are invalidated and the banner shows again.

    Where do we start if the site is old and full of abandoned trackers?

    Request a Joomla upgrade audit, then install a current consent module on the upgraded stack.

  • How to add custom JavaScript to Joomla

    How to add custom JavaScript to Joomla

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

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

    What you will learn

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

    Pick the right place for your JavaScript

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

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

    Why not paste scripts into the template head

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

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

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

    Step 1: Install and enable Easy Includes

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

    Step 2: Add a JavaScript file or CDN URL

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

    Step 3: Inline JavaScript only when you must

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

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

    Step 4: Exclude pages that must stay clean

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

    Step 5: Verify Easy Includes in the browser

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

    Path B: DIY with Web Asset Manager

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

    Step 6: Create the JS file in template media

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

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

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

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

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

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

    Step 8: Enable the script in template PHP

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

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

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

    Step 9: DIY for one view only

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

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

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

    Step 10: DIY inline script and PHP options

    Tiny dynamic snippets:

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

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

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

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

    How to remove custom JavaScript from Joomla

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

    Step 11: Remove scripts added with Easy Includes

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

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

    Step 12: Remove DIY template or override scripts

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

    Step 13: Hunt leftover hard-coded tags

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

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

    Custom JavaScript vs cookie consent

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

    What thinner articles leave out

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

    When the platform is the real problem

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

    Key takeaways

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

    Frequently asked questions

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

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

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

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

    What is the Web Asset Manager?

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

    Should I still use Document::addScript?

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

    Can I add JavaScript to a single Joomla article?

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

    What is the difference between Defer and Async?

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

    Where should Google Analytics go?

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

    Will Easy Includes work on Joomla 6?

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

    How do I stop my script on checkout pages?

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

    How do I remove custom JavaScript from Joomla?

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

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

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

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

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

  • Disable deprecated Joomla messages

    Disable deprecated Joomla messages

    Disabling deprecated Joomla messages means stopping PHP E_DEPRECATED notices (and often Joomla “Log Deprecated API” noise) from flooding the front end, administrator, or log files. On Joomla 4, 5, and 6 the safe first move is Global Configuration → Server → Error Reporting set to None on production (or Simple while you triage), with Debug System off. Hiding messages is not a substitute for updating the extension or template that still calls old APIs.

    Thin guides still tell you to paste error_reporting(…) at the bottom of configuration.php. That file is a PHP class of settings, not a free-form bootstrap script, and Joomla already maps Error Reporting into $error_reporting. This guide shows the admin path, the correct DIY edits when the admin is locked, PHP host filters, what Maximum does on PHP 8, and when you should fix the real code instead of silencing it.

    What you will learn

    • What deprecated messages are (PHP vs Joomla API logging)
    • Production vs staging Error Reporting choices
    • How to turn off Log Deprecated API and Debug System
    • DIY: edit $error_reporting in configuration.php when the admin is down
    • DIY: php.ini / .htaccess filters when System Default inherits a noisy host
    • Why Maximum + PHP 8 can make a site unusable, and how to recover
    • When silencing is wrong and you need an upgrade instead

    Two different “deprecated” problems

    Source What you see Control
    PHP E_DEPRECATED Yellow/red notices on the page, or entries in the server error log Error Reporting + PHP error_reporting / display_errors
    Joomla deprecated API log Growing deprecated.php under the log path Global Configuration → Logging → Log Deprecated API
    Debug System overlays Extra debug chrome and stack traces for developers Global Configuration → System → Debug System

    Primary references: Global Configuration guide, Joomla logging, and the long PHP 8 discussion around Error Reporting set to Maximum (joomla-cms#36171).

    Error Reporting levels (what each one does)

    Setting Typical effect Use when
    System Default Uses the host php.ini / FPM value You control PHP and want one source of truth
    None No PHP errors displayed to visitors Production. Default recommendation
    Simple Basic errors (roughly errors, warnings, parse). Filters many notices and deprecations Quick triage without drowning in E_DEPRECATED
    Maximum Forces a very high reporting level (effectively all errors) Staging only. Can flood PHP 8+ sites with deprecations
    Development Full developer reporting Local clone only

    Security note: production should not display PHP errors to the public. Prefer None for visitors, and read server logs or a staging clone when you need detail.

    Step 1: Set Error Reporting in Global Configuration

    1. Log in to Administrator.
    2. System → Global Configuration → Server tab.
    3. Error Reporting: choose None for live sites, or Simple if you still need basic faults visible to admins on staging.
    4. Save & Close.
    5. Reload the front end and administrator. Deprecated banners from PHP display should be gone when None is active.

    Step 2: Turn Debug System off on production

    1. System → Global Configuration → System tab.
    2. Debug System: No.
    3. Debug Language: No unless you are translating.
    4. Save.

    Debug Mode plus Maximum is how sites become unreadable under PHP 8 when old extensions still emit deprecations.

    Step 3: Stop Log Deprecated API filling administrator/logs

    1. System → Global Configuration → Logging tab.
    2. Log Deprecated API: No on production (Yes only while you are intentionally auditing extensions).
    3. Log Almost Everything: No unless you are debugging a specific incident.
    4. Note the Path to Log Folder. If deprecated.php is huge, archive or delete it after you turn logging off (keep a copy if you still need the list of offenders).
    5. Save.

    Log Almost Everything does not include the deprecated category. Deprecated API calls use the separate Log Deprecated API switch and write to deprecated.php.

    Step 4: DIY when the administrator is locked

    If deprecated output or a fatals storm blocks the admin UI, edit configuration.php over SFTP or hosting File Manager. Change permissions temporarily if the file is read-only (often 444 → 644 on Linux hosts), edit, then lock it down again.

    Set the property Joomla already understands. Do not append a free-standing error_reporting(…) call at the bottom of the class file:

    public $error_reporting = 'none';
    public $debug = false;
    

    Useful values for $error_reporting: 'none', 'simple', 'maximum', 'development', or 'default' (system default). Matching debug:

    public $debug = false;
    

    Optional logging flags you may also see in the same file:

    public $log_everything = 0;
    public $log_deprecated = 0;
    

    Save the file, reload the site, then finish the job in Global Configuration once the admin is reachable again.

    Step 5: DIY PHP host filter (System Default or compile-time noise)

    Some deprecations fire so early that only the PHP process setting fully hides them. Prefer the host panel (MultiPHP INI, PHP-FPM pool, or “Select PHP version → Options”).

    Example php.ini / FPM style:

    display_errors = Off
    error_reporting = E_ALL & ~E_DEPRECATED & ~E_STRICT
    log_errors = On
    

    On Apache with AllowOverride permitting PHP flags, some hosts accept:

    php_value error_reporting 22527
    

    (22527 is a common integer for E_ALL & ~E_DEPRECATED on older PHP lines. Confirm with echo E_ALL ^ E_DEPRECATED; on your PHP version, or use the host UI instead of guessing.)

    If Global Configuration is set to Maximum, Joomla overrides the host filter for display. Switch Maximum off first, then tune PHP.

    Step 6: Verify and keep staging honest

    1. Production: Error Reporting None, Debug No, Log Deprecated API No.
    2. Staging clone: temporarily use Simple or Development, or enable Log Deprecated API, and capture which extensions appear in the log.
    3. Confirm visitors no longer see notice HTML in View Source.
    4. Confirm the server error log is not still spamming the same deprecations every request (display off does not always stop logging).
    5. Clear Joomla cache after config changes.

    What not to do

    • Do not paste error_reporting(E_ALL & ~E_DEPRECATED); at the bottom of configuration.php. That old Infyways tip (and many Stack Overflow clones) treats a settings class like index.php.
    • Do not leave Maximum + Debug on a public PHP 8 site “just in case.”
    • Do not error_reporting(0) in core index.php as your long-term strategy. Updates overwrite it and you lose real fatals you need.
    • Do not ignore a flood of deprecations forever on an abandoned extension. PHP 8.3 / 8.4 and Joomla 6 will keep raising the cost.

    Fix the cause when messages point at your stack

    Signal Likely cause Next step
    Deprecations name a third-party extension path Extension not ready for your PHP / Joomla line Update or replace the extension
    Deprecations name a template override Old PHP in the override Rewrite the override on a child template
    Only on Maximum / Development Expected noise while modernising Keep production on None; fix on staging
    Site unusable after a PHP upgrade Reporting too high + legacy code Set None/Simple via configuration.php, then plan an upgrade

    If the site is still on Joomla 3 or early 4 with abandoned extensions, silencing notices only buys time. Infyways upgrades start at $149 with a free audit within 12 hours: Joomla Upgrade Services.

    What thinner articles leave out

    Topic Typical post This guide
    First step Hack configuration.php with error_reporting() Global Configuration Error Reporting
    Joomla API log Ignored Log Deprecated API and deprecated.php
    PHP 8 + Maximum Missing Why the site can go blank or unusable
    Locked admin Vague FTP advice Edit $error_reporting and $debug properties correctly
    Host PHP One .htaccess line display_errors, logging, and Maximum override behaviour
    Root cause “Messages are annoying” Update extensions or upgrade the CMS

    Key takeaways

    1. Production: Error Reporting None, Debug System No, Log Deprecated API No.
    2. Simple is a useful middle ground for triage without full deprecation spam.
    3. Avoid Maximum on live PHP 8+ sites unless you are ready for noise.
    4. When locked out, set $error_reporting = 'none'; and $debug = false; in configuration.php.
    5. Do not append raw error_reporting() calls to configuration.php.
    6. Host PHP filters help when System Default inherits a noisy ini, but Maximum overrides them for display.
    7. Silencing is temporary. Fix or replace the extension that still uses deprecated APIs.

    Frequently asked questions

    How do I disable deprecated Joomla messages?

    Set Global Configuration → Server → Error Reporting to None on production, turn Debug System off, and set Log Deprecated API to No.

    What is the difference between Error Reporting None and Simple?

    None hides PHP error display. Simple still shows basic errors and warnings but filters much of the notice and deprecation noise.

    Why did Maximum make my PHP 8 site unusable?

    Maximum forces very high reporting, so every E_DEPRECATED from legacy extensions can dump onto every page. Switch back to None or Simple.

    How do I edit Error Reporting if the administrator will not load?

    Edit configuration.php and set public $error_reporting = ‘none’; and public $debug = false; then reload.

    Should I add error_reporting() to configuration.php?

    No. Use the $error_reporting property or the Global Configuration UI. Appending a free-standing call is an outdated and brittle hack.

    What does Log Deprecated API do?

    It writes Joomla deprecated API usage to deprecated.php in the log folder. Turn it on only while auditing, then turn it off.

    Will hiding deprecated messages fix security issues?

    No. It only stops display or API logging. Outdated extensions can still be vulnerable. Plan updates or a migration.

    Can I filter E_DEPRECATED in php.ini only?

    Yes for System Default, and for some compile-time cases. If Joomla Error Reporting is Maximum, change that setting too.

    Where do we start if deprecations come from abandoned extensions?

    Request a Joomla upgrade audit so the stack moves to current Joomla and PHP with supported replacements.

  • Test and enable Gzip compression in Joomla

    Test and enable Gzip compression in Joomla

    Gzip compression in Joomla shrinks text responses (especially HTML that PHP builds) before they leave the server, so browsers download less data. On Joomla 4, 5, and 6 you enable Gzip Page Compression under System → Global Configuration → Server. That switch compresses Joomla’s buffered page output when PHP zlib is available. Static CSS and JavaScript files are a separate job for Apache mod_deflate / the Joomla .htaccess gzip section, Nginx, LiteSpeed, or a CDN (often Brotli with Gzip fallback).

    Many “5 simple steps” posts turn the Global Configuration toggle on and stop. Then GTmetrix still complains about uncompressed assets, or the site shows ERR_CONTENT_DECODING_FAILED from double compression. This guide covers what the toggle really does, how to test correctly, DIY server rules, Brotli in 2026, and how to undo a bad stack without guessing.

    What you will learn

    • Gzip Page Compression vs server or CDN compression for static files
    • How to enable and disable the Joomla setting safely
    • How to test with DevTools and curl (not only a random online badge)
    • DIY .htaccess / host panel options and the official htaccess.txt gzip block
    • Why double Gzip breaks pages and how to fix it
    • Where Brotli fits, and when compression is not the real speed problem

    What Joomla Gzip Page Compression actually compresses

    Layer Compresses Where you enable it
    Gzip Page Compression Buffered HTML (and related PHP output) when zlib works Global Configuration → Server
    Apache / LiteSpeed / Nginx Often CSS, JS, HTML, JSON, SVG, fonts Host panel, vhost, or .htaccess
    Joomla htaccess.txt gzip section Prebuilt .css.gz / .js.gz if those files exist Root .htaccess from current htaccess.txt
    CDN (Cloudflare and similar) Edge compression, often Brotli + Gzip CDN dashboard

    Official help describes the setting as compressing buffered output if supported. Requirements: PHP compiled with zlib, and no second compressor already mangling the same response.

    Step 1: Confirm zlib and current headers

    1. System → System Information → PHP Settings. Confirm zlib (or zlib compression support) is available.
    2. Open the live homepage in a private window.
    3. DevTools → Network → select the document request → Headers. Look for Content-Encoding: gzip or br.
    4. Optional curl check from any machine that can reach the site:
    curl -sI -H "Accept-Encoding: gzip, deflate, br" "https://www.example.com/"
    

    Note whether compression is already on before you change anything. Many hosts and CDNs already gzip HTML.

    Step 2: Enable Gzip Page Compression in Joomla

    Joomla Global Configuration Server tab with Gzip Page Compression set to Yes
    1. System → Global Configuration → Server tab.
    2. Gzip Page Compression: Yes.
    3. Save & Close.
    4. System → Clear Cache.
    5. Retest the document response for Content-Encoding: gzip.

    If the site breaks (blank page, encoding error), set the option back to No immediately, clear cache, and jump to the troubleshooting section. Double compression is the usual culprit.

    Step 3: Test properly (HTML vs CSS/JS)

    What you test How Pass looks like
    HTML document DevTools Network → first document, or curl -I with Accept-Encoding Content-Encoding: gzip or br
    A CSS file Click a .css request in Network Same header, or CDN br
    A JS file Click a .js request Same
    Online checkers GTmetrix, KeyCDN HTTP Header Checker, giftofspeed, etc. Use as a second opinion, not the only proof
    curl -sI -H "Accept-Encoding: gzip" "https://www.example.com/media/system/js/core.min.js"
    

    Joomla’s toggle can pass HTML while CSS/JS stay uncompressed. That is expected until the server or CDN compresses static files.

    Step 4: DIY server compression for static assets

    Prefer the host’s “Optimize website” / “Compress content” panel when it exists. On Apache, a minimal deflate block (only if the host does not already compress) looks like:

    <IfModule mod_deflate.c>
      AddOutputFilterByType DEFLATE text/html text/plain text/xml text/css
      AddOutputFilterByType DEFLATE application/javascript application/json application/xml
    </IfModule>
    

    Rules of thumb:

    • Do not stack aggressive mod_deflate on top of Joomla Gzip Page Compression if HTML starts failing. Pick one HTML compressor.
    • Keep a backup of .htaccess before editing.
    • After Joomla updates, diff your .htaccess against the shipping htaccess.txt. The GZIP & BROTLI section evolved (including E=no-brotli:1 on precompressed assets).

    Official notes: The htaccess.txt file. If the site looks strange after enabling that gzip section, the comments in htaccess.txt say your server may already gzip CSS/JS. Comment the block out.

    Step 5: Brotli and CDN in 2026

    Modern browsers prefer Brotli (Content-Encoding: br) when the edge supports it. Joomla has no “Brotli Page Compression” switch. Enable Brotli on LiteSpeed, Cloudflare, or Nginx with the brotli module, and keep Gzip as fallback for older clients.

    • If the CDN already compresses, you often leave Joomla Gzip on or off based on whether origin HTML is still uncompressed in a bypass test
    • Test with a cache-bypassing header or orange-cloud off briefly so you know whether origin or edge is doing the work
    • Precompressed .js.gz / .css.gz must not be compressed again (the stock htaccess rules set no-gzip / no-brotli for those files)

    Step 6: Troubleshoot and disable cleanly

    Symptom Likely cause Fix
    ERR_CONTENT_DECODING_FAILED Double Gzip / Brotli Turn Joomla Gzip off, or remove duplicate server rules, clear caches
    HTML compressed, CSS/JS not Only page compression on Enable server/CDN compression for static types
    Nothing compressed No zlib, proxy stripping encoding, or Accept-Encoding missing in the test Check PHP info, retest with the curl header above
    Works in curl, fails in browser Extension, SW, or CDN cache serving a bad body Purge CDN, disable service worker, retest private window
    CPU spikes after enabling Compressing huge uncacheable HTML every hit Add page/object cache. See caching in Joomla

    To disable Joomla’s layer only: Global Configuration → Server → Gzip Page Compression → No → Save → Clear Cache. That does not turn off host or CDN compression.

    Gzip is not a substitute for a healthy stack

    Compression helps text weight. It does not replace image optimisation, a current PHP version, or leaving Joomla 3. If Core Web Vitals stay poor after Gzip and cache, fix the platform. Infyways upgrades start at $149 with a free audit within 12 hours: Joomla Upgrade Services.

    What thinner articles leave out

    Topic Typical post This guide
    Scope of the toggle “Compresses all files” HTML buffer vs static assets vs CDN
    Testing One online badge DevTools + curl for HTML and JS/CSS
    Double compression Rarely mentioned ERR_CONTENT_DECODING_FAILED playbook
    htaccess.txt Random deflate snippet Official gzip/brotli notes and when to disable
    Brotli Missing or hand-wavy CDN/server layer, not a Joomla switch
    Next bottleneck Stop at Gzip Cache and upgrade path

    Key takeaways

    1. Turn on Gzip Page Compression for buffered HTML when zlib is present.
    2. Compress CSS/JS at the server or CDN. The Joomla toggle alone is not enough.
    3. Test the document and at least one CSS and one JS request.
    4. Avoid double compression. Decoding errors mean turn a layer off.
    5. Keep .htaccess aligned with current htaccess.txt after upgrades.
    6. Prefer Brotli at the edge when available, with Gzip fallback.
    7. Pair compression with caching. Compression on an uncached PHP hit still costs CPU.

    Frequently asked questions

    How do I enable Gzip compression in Joomla?

    Go to System → Global Configuration → Server, set Gzip Page Compression to Yes, save, and clear cache. Then verify Content-Encoding on the HTML document.

    Does Gzip Page Compression compress CSS and JavaScript?

    Not reliably. It targets Joomla’s buffered page output. Static files need server, htaccess, or CDN compression.

    How do I test Gzip on a Joomla site?

    Use DevTools Network headers or curl with Accept-Encoding: gzip and look for Content-Encoding: gzip or br on HTML and assets.

    What causes ERR_CONTENT_DECODING_FAILED after enabling Gzip?

    Usually two compressors on the same response. Disable Joomla Gzip or the extra server rule, purge caches, and retest.

    Should I use Gzip and Brotli together?

    Yes at the edge when configured correctly: Brotli for supporting browsers, Gzip as fallback. Do not double-compress the same payload.

    Do I need zlib for Joomla Gzip Page Compression?

    Yes. Without zlib support in PHP, the Joomla setting cannot compress buffered output.

    Is Gzip enough to make Joomla fast?

    No. It reduces transfer size for text. You still need caching, modern PHP, lean extensions, and optimised images.

    How do I turn Gzip off again?

    Set Gzip Page Compression to No, save, clear Joomla cache, and purge CDN cache if you use one.

    Where do we start if the site is slow even with Gzip?

    Request a Joomla upgrade audit and review Joomla caching on staging.

  • Joomla PHP.ini Settings: Where They Live and What to Set (Joomla 4, 5, 6)

    Joomla PHP.ini Settings: Where They Live and What to Set (Joomla 4, 5, 6)

    Joomla PHP.ini settings are the PHP runtime limits and switches (memory, upload size, execution time, input variables, error display, OPcache) that decide whether Joomla 4, 5, or 6 installs cleanly, updates without timeouts, and uploads extensions without silent failures. Joomla 6 needs PHP 8.3.0 or newer (8.4 recommended) and at least 256M memory. You do not edit these inside Joomla. You read the effective values under System → System Information → PHP Information, then change them through your host panel, a .user.ini or php.ini file, an FPM pool, or .htaccess (module mode only).

    Most “ultimate” php.ini posts paste one block of values and skip the part that actually breaks sites: which file PHP reads on your server. A php_value line in .htaccess throws a 500 on PHP-FPM. A php.ini in the web root does nothing under some SAPIs. post_max_size smaller than upload_max_filesize silently caps uploads. This guide is the operator version: requirements by Joomla version, a decision table for where to set values, recommended numbers, DIY files for each server type, and a troubleshooting map.

    What you will learn

    • PHP versions and modules Joomla 4, 5, and 6 require
    • How to read the effective PHP values Joomla actually runs with
    • Which file wins: php.ini, .user.ini, .htaccess, FPM pool, or host panel
    • Recommended values for memory, uploads, execution time, max_input_vars, OPcache
    • DIY edits for cPanel, WHM, Plesk, .user.ini, Nginx + PHP-FPM, and XAMPP
    • Production hardening: display_errors, disable_functions, session paths
    • Fixes for memory exhausted, upload caps, timeouts, and 500 errors from php_value

    PHP requirements by Joomla version

    Joomla PHP minimum PHP recommended Notes
    Joomla 6.x 8.3.0 8.4 Refuses to start below 8.3. Memory at least 256M
    Joomla 5.x 8.1.0 8.2 or 8.3 Security-only support through October 2027
    Joomla 4.x 7.2.5 8.2 End of life. Move to 5.4 then 6

    Required PHP modules for Joomla 6: json, simplexml, dom, zlib, gd, and mysqlnd or pdo_mysql or pdo_pgsql. Recommended: mbstring. Source: Joomla technical requirements. If your host still pins PHP 8.1 or 8.2, fix that before you tune any php.ini values for Joomla 6.

    Where PHP actually reads its settings

    This is the part thin guides skip. PHP has one main php.ini, but the value you see is the result of a chain. A later file or a host override can change it. Which override works depends on how PHP runs (the SAPI).

    Method Works when Does not work when Typical hosts
    Host panel (cPanel MultiPHP INI Editor, Plesk PHP Settings, “Select PHP Version”) Almost always. Safest first choice Value is locked by the host plan Shared and managed hosting
    .user.ini in Joomla root PHP runs as CGI, FastCGI, or PHP-FPM Apache mod_php (ignored). Only PHP_INI_PERDIR and PHP_INI_USER directives apply Most modern shared hosting, LiteSpeed, Nginx + FPM
    php.ini in Joomla root suPHP / phpSuExec style CGI on older cPanel setups FPM and mod_php usually ignore it; often not recursive to subfolders Legacy cPanel
    php_value in .htaccess Apache with PHP as a module (mod_php) PHP-FPM, CGI, FastCGI. Causes HTTP 500 “Invalid command php_value” Older Apache stacks, some VPS
    FPM pool (php_admin_value) You control the server Shared hosting VPS, dedicated, Docker
    Main php.ini (/etc/php/…) Root access Shared hosting Own server

    Rule: pick one method per server. Do not stack .htaccess php_value on top of .user.ini and a panel. When they disagree, you spend hours chasing a value that “refuses to change.”

    Step 1: Read the effective values in Joomla

    Joomla System Information screen showing PHP version and server details
    1. Administrator → System → System Information.
    2. Check PHP Version, Web Server, and the “PHP Built On” line. Note the Server API (mod_php, FPM, CGI, LiteSpeed). That decides your override method from the table above.
    3. Open the PHP Information tab. Search the page for memory_limit, upload_max_filesize, post_max_size, max_execution_time, max_input_vars, display_errors, opcache.enable.
    4. Note the “Loaded Configuration File” and “Additional .ini files parsed” rows. That is the file chain PHP actually used.
    Joomla PHP Information tab listing effective php.ini values

    Trust this screen, not a php.ini you edited by hand. If the value you changed is not reflected here, PHP is reading a different file or the host caps it.

    Step 2: Recommended values for Joomla 4, 5, and 6

    Directive Practical value Why Joomla needs it
    memory_limit 256M (512M for VirtueMart, big ACL, or migrations) Joomla recommends at least 256M. Too low gives “Allowed memory size exhausted”
    upload_max_filesize 64M Extension packages, templates, and media uploads
    post_max_size 64M or larger than upload_max_filesize PHP caps uploads at the smaller of the two. Must be equal or larger
    max_execution_time 120 to 300 Core updates, Akeeba backups, imports, large migrations
    max_input_time 120 or -1 Large multipart uploads over slow connections
    max_input_vars 3000 to 5000 Global Configuration permissions, big menus, and ACL forms exceed the 1000 default and save silently truncated
    display_errors Off on production Never show PHP errors to visitors. Log them instead
    log_errors / error_log On, path outside web root You still need the errors somewhere
    date.timezone Your server zone (for example Asia/Kolkata) Cron, scheduled tasks, and publish dates
    opcache.enable 1 Biggest free PHP speed win. Usually on by default in PHP 8
    realpath_cache_size 4096K Fewer filesystem stats on large Joomla trees

    These numbers are starting points for a normal business site. A brochure site on a tiny VPS can run 128M. A store doing imports can need 512M and 600 seconds. Tune from evidence in the PHP error log, not from a blog table.

    Step 3: Change values in cPanel (most shared hosts)

    1. cPanel → Software → MultiPHP INI Editor (or “Select PHP Version” → Options on CloudLinux hosts).
    2. Basic Mode: pick your domain, then set memory_limit, upload_max_filesize, post_max_size, max_execution_time, max_input_vars.
    3. Apply. cPanel writes a php.ini and .user.ini for that document root for you.
    4. Reload System Information in Joomla and confirm the new values.

    Also check cPanel → MultiPHP Manager to confirm the domain runs PHP 8.3 or 8.4 before Joomla 6 upgrades.

    Step 4: Change values in WHM (server owners)

    WHM MultiPHP INI Editor used to change Joomla php.ini values per PHP version
    1. Log in to WHM (port 2087).
    2. Software → MultiPHP INI Editor.
    3. Basic Mode for dropdowns, or Editor Mode to edit the full php.ini for one PHP version.
    4. Select the PHP version your Joomla domains use. Change the directives. Save.
    5. Restart PHP-FPM (or Apache in module mode) if the change does not appear in Joomla within a minute.

    WHM edits apply server-wide for that PHP version. Use cPanel per account when only one site needs a bigger limit.

    Step 5: Change values in Plesk

    1. Websites & Domains → your domain → PHP Settings.
    2. Set memory_limit, upload_max_filesize, post_max_size, max_execution_time, max_input_time, and add max_input_vars = 5000 under Additional directives.
    3. Confirm the PHP version and handler (FPM by Apache or Nginx is common).
    4. Apply, then verify in Joomla System Information.

    Step 6: DIY .user.ini in the Joomla root (CGI, FastCGI, PHP-FPM)

    When the panel does not expose a value, create .user.ini in the same folder as Joomla’s index.php and configuration.php:

    memory_limit = 256M
    upload_max_filesize = 64M
    post_max_size = 64M
    max_execution_time = 300
    max_input_time = 300
    max_input_vars = 5000
    display_errors = Off
    log_errors = On
    
    • PHP re-reads .user.ini on a timer (user_ini.cache_ttl, default 300 seconds). Wait five minutes or restart FPM before you judge it “not working.”
    • Only PHP_INI_PERDIR and PHP_INI_USER directives apply. disable_functions, open_basedir, OPcache size, and other PHP_INI_SYSTEM values cannot be set here.
    • Protect it. Current Joomla htaccess.txt blocks direct access to .user.ini style files on Apache. On Nginx, deny dotfiles in the vhost.
    • Joomla’s administrator folder has its own request path. If admin uploads still fail, copy the same .user.ini into administrator/.

    Step 7: DIY php.ini in the Joomla root (legacy suPHP / phpSuExec)

    Older cPanel servers running PHP as CGI with suPHP read a php.ini from the script directory instead of .user.ini. Same directives, different filename:

    memory_limit = 256M
    upload_max_filesize = 64M
    post_max_size = 64M
    max_execution_time = 300
    max_input_vars = 5000
    

    Under suPHP the file is often not recursive. Copy it into administrator/ as well. If a php.ini in the root changes nothing, you are not on suPHP. Use Step 6 or the panel.

    Step 8: .htaccess php_value (Apache mod_php only)

    Use this only when System Information shows Server API “Apache 2.0 Handler” (mod_php). On PHP-FPM, CGI, and FastCGI these lines break the site with a 500 error.

    <IfModule mod_php.c>
        php_value memory_limit 256M
        php_value upload_max_filesize 64M
        php_value post_max_size 64M
        php_value max_execution_time 300
        php_value max_input_vars 5000
    </IfModule>
    

    Wrapping in IfModule avoids the 500 when a host migrates you to FPM later, but the values then silently stop applying. Prefer .user.ini on any host newer than about 2018.

    Step 9: Nginx + PHP-FPM pool (VPS and dedicated)

    Edit the pool file (for example /etc/php/8.4/fpm/pool.d/www.conf or your site’s pool):

    php_admin_value[memory_limit] = 256M
    php_admin_value[upload_max_filesize] = 64M
    php_admin_value[post_max_size] = 64M
    php_admin_value[max_execution_time] = 300
    php_admin_value[max_input_vars] = 5000
    php_admin_flag[display_errors] = off
    php_admin_flag[log_errors] = on
    php_admin_value[error_log] = /var/log/php/joomla-error.log
    

    Then restart the service (for example systemctl restart php8.4-fpm). Match Nginx too, or uploads still fail at the proxy before PHP sees them:

    client_max_body_size 64m;
    fastcgi_read_timeout 300;
    

    php_admin_value locks the setting so .user.ini cannot override it. Use plain php_value in the pool if you want per-site files to win.

    Step 10: XAMPP, MAMP, and local development

    1. Find the loaded php.ini: XAMPP Control Panel → Apache → Config → php.ini (usually C:\xampp\php\php.ini). On macOS MAMP it lives under the selected PHP version folder.
    2. Back the file up, then search for each directive and raise memory_limit, upload_max_filesize, post_max_size, max_execution_time, max_input_vars.
    3. Set display_errors = On locally so you see problems that production hides.
    4. Restart Apache from the control panel. CLI PHP uses a separate php.ini on many local stacks, so php -i may show different values from the browser.
    5. Verify with a throwaway info.php containing <?php phpinfo();, then delete it. Never leave phpinfo files on production.

    Step 11: OPcache and production hardening

    Where you control the main php.ini or FPM pool:

    opcache.enable = 1
    opcache.memory_consumption = 192
    opcache.interned_strings_buffer = 16
    opcache.max_accelerated_files = 20000
    opcache.validate_timestamps = 1
    opcache.revalidate_freq = 60
    
    • Joomla 5 and 6 with a few extensions easily exceed 10000 PHP files. Keep max_accelerated_files high (the value rounds up to a prime).
    • Keep validate_timestamps = 1 unless your deploy restarts FPM. With it at 0, a Joomla update can leave stale code cached and show broken pages until restart.
    • Drop the ancient opcache.fast_shutdown line from old tutorials. It was removed in PHP 7.2.

    Security directives that belong in server-level php.ini, not .user.ini:

    expose_php = Off
    allow_url_include = Off
    session.cookie_httponly = 1
    session.cookie_secure = 1
    session.use_strict_mode = 1
    disable_functions = exec,passthru,shell_exec,system,proc_open,popen
    

    Test disable_functions on staging first. Some backup and image extensions need exec for ImageMagick or archive tools. Joomla itself does not need those functions.

    Step 12: Verify and troubleshoot

    1. Reload System → System Information → PHP Information and confirm every value you changed.
    2. Upload a 30 to 50 MB extension zip through System → Install → Extensions.
    3. Save Global Configuration → Permissions once. If a permission change does not stick, raise max_input_vars.
    4. Run a Joomla core update or a full backup and watch for timeouts.
    5. Check the PHP error log path you configured actually receives entries.
    Symptom Likely cause Fix
    Allowed memory size of 134217728 bytes exhausted memory_limit 128M Raise to 256M (or 512M for stores and migrations)
    Upload fails or “file too large” at a size below your setting post_max_size smaller than upload_max_filesize, or Nginx client_max_body_size Set post_max_size equal or larger; raise Nginx limit
    Extension install “Unable to write” or blank page after upload max_execution_time or memory during unzip Raise both; check tmp folder permissions
    HTTP 500 right after editing .htaccess php_value on PHP-FPM or CGI Remove the lines; use .user.ini or the panel
    Values in .user.ini never appear mod_php, wrong folder, or cache_ttl not elapsed Check Server API; place the file beside index.php; wait 5 minutes or restart FPM
    Permissions or menu saves lose fields max_input_vars 1000 Raise to 3000 to 5000
    Site slow after every update OPcache off or too small Enable OPcache; raise max_accelerated_files
    Joomla 6 upgrade blocked PHP below 8.3 Switch PHP version in the panel first

    Joomla settings that sit on top of PHP

    • Media upload limit: Content → Media → Options has its own Maximum Size. PHP limits win if they are smaller.
    • Session lifetime: Global Configuration → System → Session Lifetime (minutes) works with PHP session.gc_maxlifetime. Keep the PHP value at or above Joomla’s, in seconds.
    • Error Reporting: Global Configuration → Server. Maximum overrides PHP display settings. Keep None on production. Details: disable deprecated Joomla messages.
    • Gzip and cache: zlib must be present for Gzip Page Compression; cache handlers are covered in caching in Joomla.

    When php.ini is not the real problem

    If you keep raising memory and time to get a Joomla 3 site through a PHP 8 upgrade, the problem is abandoned extensions and an old template, not PHP limits. Fix the platform. Infyways upgrades start at $149 with a free audit within 12 hours: Joomla Upgrade Services. For ongoing server tuning, see Joomla support and maintenance.

    What thinner articles leave out

    Topic Typical post This guide
    Which file PHP reads “Edit php.ini” Decision table by Server API: panel, .user.ini, php.ini, .htaccess, FPM pool
    Joomla versions Joomla 3 or 4 numbers Joomla 6 needs PHP 8.3+, 8.4 recommended, 256M minimum
    Upload caps upload_max_filesize only post_max_size, max_input_time, Nginx client_max_body_size
    max_input_vars Missing Why ACL and menu saves truncate
    500 after .htaccess Unexplained php_value on FPM/CGI and the fix
    OPcache Copy-pasted PHP 5 block PHP 8 values, validate_timestamps, removed fast_shutdown
    Verification phpinfo file left on server System Information plus real upload, save, and update tests

    Key takeaways

    1. Joomla 6 needs PHP 8.3.0 or newer, 8.4 recommended, with at least 256M memory.
    2. Read effective values in System → System Information → PHP Information before and after every change.
    3. Choose the override method by Server API: panel first, then .user.ini on FPM/CGI, .htaccess php_value only on mod_php.
    4. Set post_max_size equal to or larger than upload_max_filesize, and match Nginx client_max_body_size.
    5. Raise max_input_vars to 3000 to 5000 so permissions and menus save completely.
    6. Keep display_errors Off and log_errors On in production.
    7. Enable OPcache with a high max_accelerated_files and validate_timestamps on.
    8. Do not stack multiple override files. One method per server.

    Frequently asked questions

    Where is the php.ini file for Joomla?

    Joomla has no php.ini of its own. PHP loads the server’s php.ini plus overrides. Find the loaded file under System → System Information → PHP Information (“Loaded Configuration File”).

    What PHP version does Joomla 6 require?

    PHP 8.3.0 minimum, PHP 8.4 recommended. Joomla 5 runs on PHP 8.1 or newer, with 8.2 or 8.3 recommended.

    What memory_limit should I set for Joomla?

    256M for most sites. Use 512M for VirtueMart, HikaShop, large ACL trees, and migrations.

    Why does .htaccess php_value give a 500 error?

    PHP is running as FPM, CGI, or FastCGI, so Apache does not understand php_value. Remove the lines and use .user.ini or your host panel.

    What is the difference between php.ini and .user.ini?

    php.ini is the main server configuration (and a per-directory file on legacy suPHP). .user.ini is the per-directory override PHP reads under CGI, FastCGI, and FPM. Only per-directory and user-level directives apply in .user.ini.

    Why can I not upload a 50 MB extension after raising upload_max_filesize?

    post_max_size is still smaller, or Nginx client_max_body_size blocks the request. Raise both to at least the upload size.

    What is max_input_vars and why does Joomla need it?

    It caps how many form fields PHP accepts per request. The 1000 default truncates Joomla permission and menu forms. Set 3000 to 5000.

    Should display_errors be on in Joomla?

    No, not on production. Turn it Off, keep log_errors On, and use Joomla Error Reporting None. Enable it only on staging or local.

    Do I need to restart anything after editing php.ini?

    Main php.ini and FPM pool changes need a PHP-FPM or Apache restart. .user.ini changes apply after user_ini.cache_ttl (default 300 seconds). Panel edits usually handle the restart for you.

    Where do we start if PHP limits keep breaking a Joomla upgrade?

    Request a Joomla upgrade audit. We check PHP version, limits, extensions, and template compatibility before touching production.

  • Fix Joomla Browser Compatibility Issues in Safari, Firefox, Chrome, and Edge

    Fix Joomla Browser Compatibility Issues in Safari, Firefox, Chrome, and Edge

    A Joomla browser compatibility issue is a page that works in one current browser and fails in another. Joomla 4, 5, and 6 support the current major version and the one before it of Chrome, Edge, Firefox, and Safari (the n-2 policy the project adopted in 2019). Internet Explorer is not supported. Most reports are not browser bugs at all: they are a cached stylesheet, a browser extension, a Joomla 3 template, a cookie scoped to the wrong host, or one of three documented core bugs (Safari 15 and Joomla’s ranged media queries, Firefox 148 and TinyMCE in Joomla 5.4.3 / 6.0.3, and Conservative caching breaking the Web Asset Manager). This guide separates them in order and gives the fix for each.

    Generic cross-browser posts tell you to “test on real devices” and “check Can I Use.” That does not help when the administrator dashboard renders as a single column on a client’s Mac or the article editor flickers forever in Firefox. Those are known Joomla issues with issue-tracker numbers, version ranges, and specific fixes. You will find them here, together with a triage that stops you rewriting CSS for a problem the private window would have solved.

    What you will learn

    • Which browsers Joomla 4, 5, and 6 actually support and where that policy is written
    • How to tell a browser bug from cache, an extension, a responsive bug, or a PHP error
    • The three documented Joomla core bugs that only show in one browser, with fixes
    • Which modern CSS features are safe for Joomla templates in 2026 and which still need fallbacks
    • Safari-specific quirks (100vh, hover, date inputs, backdrop-filter, autoplay) and how to code around them
    • The Safari login failure that is really the site URL
    • A tested one-command fix that makes Cassiopeia render on Safari 15 from a child template
    • Which testing tools are worth using and in what order

    Supported browsers by Joomla version

    Joomla Browsers to test Policy source Do not spend time on
    3.10 (end of life) Current Chrome, Edge, Firefox, Safari Old docs list still names IE. Not a 2026 requirement IE8 to IE11. Joomla 3 itself is unsupported
    4.x Current and previous major of Chrome, Edge, Firefox, Safari Production motion PROD2019/005: n-2, drop Internet Explorer. Bootstrap 5 UI IE11. Bootstrap 5 does not support it
    5.x and 6.x Same four, current and previous major Same policy. Core JavaScript is ES2018, IE11 es5.js builds removed in 5.0 IE11, Safari 15 and older, any es5.js shim

    Bootstrap’s rule, which Joomla’s UI follows, is the latest stable browsers, not Internet Explorer: Bootstrap browsers and devices. The IE11 bundle removal is recorded in the Joomla 4.4 to 5 removal list. The wiki page Joomla Browser Support is a Joomla 3 document. Do not use it as the matrix for Joomla 5 or 6.

    What n-2 means in practice: Safari ships one major per year, so a Mac that cannot go past Safari 15 (macOS Monterey and older) is outside support for every Joomla 4.4.1 or newer release. Chrome, Edge, and Firefox update monthly and auto-update, so “old Chrome” is almost never the cause. Firefox ESR is supported because it tracks a recent major.

    Documented one-browser bugs in Joomla core

    Check this table before you touch any CSS. If the symptom, browser, and Joomla version match, the fix is known.

    Symptom Browser Joomla versions Cause Fix
    Administrator dashboard, sidebars, and Cassiopeia grid collapse to one mobile column on a wide screen Safari 15 and older (macOS Monterey, Big Sur) 4.4.1 and newer, all 5.x, 6.0.x, 6.1.0 (we checked the shipped files) Core CSS is compiled with ranged media queries @media (width >= 1200px). Safari added support in 16.4. Older Safari drops the whole rule. Issues #42439 and #45674 Update Safari (16.4 or newer). If the Mac cannot, the browser is outside policy; use Chrome or Firefox on that Mac. For a public site with many legacy Safari visitors, transpile the template CSS to classic min-width syntax and ship it from a child template (tested procedure in Step 9). Do not overwrite core files; the next update reverts them
    TinyMCE editor flickers and reloads forever, articles cannot be edited Firefox 148 and newer 5.4.3 and 6.0.3 Firefox 148 (February 2026) changed behaviour TinyMCE relied on. Listed on the Joomla 6.0.3 known issues page Install the “Firefox 148 TinyMCE Hotfix” one-time patcher from the Joomla 6.0.3 / 5.4.3 download page (System → Install → Extensions), or update to 5.4.4 / 6.0.4 or newer. Chrome users are unaffected, which is why it looks like “Firefox is broken”
    Site error “Unsatisfied dependency … for an asset” or missing scripts on some pages, only after caching is on All browsers, but appears random per visitor 4.0 to 4.1.0 with Conservative caching; any version with a broken third-party cache plugin Module caching stored Web Asset Manager dependencies with the wrong owner. Issue #37122, fixed in 4.1.1 Update Joomla. Clear cache. If a page-cache extension reproduces it, exclude the administrator and logged-in users. Details in caching in Joomla
    Cassiopeia menus “act strangely” in Safari Safari 15 and older 5.0.x Same root cause as the first row. Issue #42713 was closed in favour of #42439 Same fix

    Name the failure before you edit CSS

    What you see In which browsers What it usually is
    Layout wrong only on a phone width All of them Responsive CSS or a missing viewport tag. Not a browser bug
    Wide screen renders the mobile layout Safari 15 or older only Ranged media queries. See the table above
    IE11 admin is unstyled or dead IE only Unsupported. Move the user to Edge
    One browser shows yesterday’s CSS One Cache, or a service worker from a PWA extension
    Styles missing everywhere All CSS 404, mixed content, CSP, or .htaccess. See 500 on mod_rewrite
    Login works in Chrome, drops in Safari Safari Site URL, www versus apex, or HTTP versus HTTPS. Cookie scope, not WebKit
    Editor will not load or keeps refreshing Firefox 148+ TinyMCE bug in 5.4.3 / 6.0.3. Install the hotfix or update
    A slider or menu dies in one browser One An extension script. Read the console
    Fonts, icons, or a map missing in Firefox or Brave only Firefox, Brave Tracking protection or Shields blocking a third-party host. Self-host the asset
    Only the administrator is broken One or all Atum, or an admin module. The site template is innocent
    Blank page, no layout talk All A PHP fatal, not CSS. Read the host log

    Step 1: Write down the browser, the version, and the URL

    1. Note the browser name and a major version (Chrome 14x, Safari 18, Firefox ESR). “Doesn’t work on Mac” is not a report. On a Mac, Safari → About Safari shows the version; the macOS version tells you the maximum Safari it can run.
    2. Note the exact URL. Site homepage, one article, and /administrator/ are three different products.
    3. If the browser is Internet Explorer, stop. On Joomla 4, 5, or 6 that is expected. Send the user to current Edge, Chrome, Firefox, or Safari.
    4. If the browser is Safari 15 or older and the layout is the complaint, go to the core bugs table. You are done diagnosing.
    5. If every current browser fails the same way, you are not debugging compatibility. Fix the error, the missing file, or the template, then come back.

    Step 2: Rule out cache and extensions

    1. Open a private window with extensions disabled. Retest the same URL.
    2. If the private window is fine, the cause is a cached file or an extension (ad blockers block scripts and fonts, Firefox Enhanced Tracking Protection and Brave Shields block third-party hosts). Clear that browser’s cache for the site. Then clear Joomla’s cache (System → Maintenance → Clear Cache) and any CDN.
    3. If the private window is still broken, the site is serving the failure. Continue.

    Joomla appends its media version to core asset URLs, and that version changes when you update Joomla or an extension. A hand-edited user.css does not change it, so browsers can keep the old file for days. Clear Joomla cache after CSS edits, and on a CDN purge the CSS path.

    Step 3: Read the console, not the homepage

    1. Open developer tools in the broken browser. Console and Network.
    2. Reload. Copy the first red error. The file name is the extension or the template.
    3. On Network, filter CSS and JS. A red row is a 404 or a blocked request. An unstyled page with a 404 on template.css is a path problem, not a rendering engine.
    4. Mixed content (HTTPS page calling http:// assets) is blocked hardest by Chrome and Safari. Fix the URLs in the template and in article HTML. Do not tell users to allow insecure content.
    5. “Refused to load” or “violates the following Content Security Policy” means the System – HTTP Headers plugin (or the host) set a CSP that the extension does not satisfy. Browsers enforce CSP slightly differently, which is why it can look like a one-browser bug. Fix the policy or the inline script, do not disable CSP site-wide.

    Step 4: See if the template is the only broken piece

    1. On a staging copy, set the site template to Cassiopeia (System → Site Templates).
    2. Retest the broken browser.
    3. If Cassiopeia is fine, your template or one of its overrides is the bug. Update it to a build for this Joomla major, or replace it. Joomla 3 templates (Bootstrap 2, IE conditional comments, MooTools menus) will not become compatible by adding a script.
    4. If Cassiopeia fails too, the template is not the cause. Look at modules on that page, then at the core bugs table.

    Confirm the template prints a viewport tag. Cassiopeia does. A custom index.php that omits it makes phones look “broken in Safari” while the desktop looks fine:

    <meta name="viewport" content="width=device-width, initial-scale=1">

    Step 5: Disable the extension named in the console

    The first console line usually names a file under /media/, /templates/, /modules/, or /plugins/. Disable that extension on staging and reload.

    • A menu or slider that calls MooTools or an ancient jQuery will fail in current browsers even when the rest of the page is fine. Background: remove MooTools from Joomla.
    • Do not “fix” it by loading jQuery again. Joomla 4, 5, and 6 core UI does not need jQuery. A second copy fights over $ and creates a new one-browser failure.
    • HTML5 Shiv and Respond.js were IE8 hacks. They do nothing on Joomla 4+ and add a script current browsers do not need. Remove them if a ten-year-old tutorial put them in the template.
    • Page builders and Helix-style frameworks that still ship -moz-, -ms-, and -webkit- prefixed rules from 2015 produce console warnings but rarely break layout. Update the template; do not hand-edit its compiled CSS.
    • Custom scripts you added yourself belong in a child template or a proper include, not pasted into index.php: add or remove custom JavaScript in Joomla.

    Step 6: Audit modern CSS the template uses

    When the template is yours or a child template, check the newer CSS features it relies on. This is the 2026 state of the features that most often produce “works in Chrome, broken in Safari or Firefox” on Joomla sites. Verify current numbers on Can I Use.

    Feature Safe in all supported browsers since Watch out for
    Ranged media queries (width >= 1200px) Safari 16.4 (March 2023). Chrome 104, Firefox 63 Safari 15 and older drop the rule entirely. This is the Joomla core bug above
    :has() Firefox 121 (December 2023). Chrome 105, Safari 15.4 Firefox ESR older than 128
    Container queries Firefox 110 (February 2023). Chrome 105, Safari 16 Same Safari 15 Macs
    Native CSS nesting Safari 16.5, Firefox 117, Chrome 112 (2023) Early nesting syntax required &; relaxed syntax landed later in 2023 and 2024. Compile nesting with Sass for public sites
    Subgrid Chrome 117 (September 2023). Firefox 71, Safari 16 Chrome-only test rigs miss nothing here now
    dvh, svh, lvh units Safari 15.4, Chrome 108, Firefox 101 Use 100dvh for full-height heroes on iOS instead of 100vh
    text-wrap: balance Safari 17.5 (2024). Chrome 114, Firefox 121 Harmless when unsupported. Fine to ship
    color-mix() Safari 16.2, Chrome 111, Firefox 113 Provide a plain colour first, then the mix
    backdrop-filter unprefixed Safari 18 (2024). Chrome 76, Firefox 103 Keep -webkit-backdrop-filter alongside it for Safari 16 and 17
    scrollbar-width, scrollbar-color Safari 18.2, Chrome 121, Firefox 64 Safari 17 shows default scrollbars. Cosmetic only
    AVIF images Safari 16 (16.4 on macOS), Chrome 85, Firefox 93, Edge 121 Wrap in <picture> with a WebP or JPEG fallback

    Pattern for anything not yet universal:

    .hero { min-height: 100vh; }
    @supports (height: 100dvh) {
      .hero { min-height: 100dvh; }
    }

    Step 7: Safari and iOS quirks that are not bugs

    Behaviour Why What to do in the template
    Full-height section overflows behind the iOS toolbar 100vh includes the space under the collapsing browser bar Use 100dvh with a 100vh fallback
    Dropdown menu needs two taps on iPhone First tap fires :hover, second fires the click Make the parent item a real link or use the Cassiopeia menu that opens on tap; test with @media (hover: none)
    Background video does not play Autoplay requires muted and playsinline <video autoplay muted loop playsinline>
    Form fields look different, date picker missing on older desktop Safari Safari styles native controls and added input type="date" on desktop only in 14.1 Set appearance: none where you style controls; provide a text fallback for very old macOS
    Fixed header jumps when the keyboard opens iOS resizes the visual viewport Prefer position: sticky for headers
    Glass effect missing on Safari 16 and 17 Needs the -webkit- prefix before Safari 18 Write both -webkit-backdrop-filter and backdrop-filter
    Fonts render heavier or lighter than Chrome Different text rasterisation per OS, not a CSS error Accept it. Do not chase pixel identity between operating systems

    Step 8: Fix Safari login separately from CSS

    If the page looks right in Safari but login or the administrator session dies, stop comparing stylesheets.

    1. Global Configuration → Site → Site URL, and the live host, must be the same scheme and host. https://example.com and https://www.example.com are different cookie hosts. Chrome is more forgiving of the redirect. Safari drops the session.
    2. Force one host in the server redirect, then clear cookies and test again.
    3. Global Configuration → System → Cookie Domain and Cookie Path: leave blank unless you run subdomains that must share the session.
    4. If the Joomla page is inside an iframe on another site, Safari blocks that third-party cookie. Do not embed the login.
    5. Session and consent cookies are covered in disable cookies for Joomla visitors.

    Step 9: Fix it in a child template, not in core

    Joomla 4.1 and newer support child templates. Every browser fix you write belongs there so updates do not erase it.

    1. System → Site Templates → Cassiopeia (or your template) → Create Child Template.
    2. Add rules to media/templates/site/{child}/css/user.css. Cassiopeia loads user.css automatically after its own CSS.
    3. Need to override a core stylesheet? Joomla resolves a relative asset such as template.min.css by looking in media/templates/site/{child}/css/ first and only then in the parent’s folder (HTMLHelper::includeRelativeFiles). A file with the same name in the child wins. No joomla.asset.json edit is needed.
    4. Never edit media/vendor/bootstrap, media/templates/site/cassiopeia, or media/system. The next Joomla update replaces them and the “fix” disappears in one browser first, which restarts the whole hunt.

    Tested: make Cassiopeia render on Safari 15 from a child template

    We inspected the files Joomla 6.0.0 and 6.1.0 ship. Cassiopeia’s template.min.css contains 111 media queries, all in range syntax and none in min-width form. Atum has 118, and media/vendor/bootstrap/css/bootstrap.min.css (Bootstrap 5.3.8) has 81. Cassiopeia does not load the vendor Bootstrap file at all; Bootstrap is compiled into template.min.css, so swapping the vendor file does nothing for Cassiopeia. The fix is to transpile the template CSS.

    1. Create the child template (step 1 above). Note its folder name, for example cassiopeia_legacy.
    2. On any machine with Node.js, run Lightning CSS against the shipped file with a Safari 15 target:
      npx lightningcss-cli --targets "safari >= 15" --minify 
        media/templates/site/cassiopeia/css/template.min.css 
        -o media/templates/site/cassiopeia_legacy/css/template.min.css
    3. Result on Joomla 6.1.0: 111 ranged queries became 111 min-width / max-width queries, file size 247 KB to 251 KB, everything else unchanged. Repeat for template-rtl.min.css if you serve RTL.
    4. Clear Joomla cache. Load the site in Safari 15 (BrowserStack macOS Monterey works) and the grid returns.
    5. After every Joomla update that changes Cassiopeia, rerun the command. Your child file is never touched by the updater, but it also does not receive core CSS fixes until you regenerate it.

    For the administrator, the same approach works with an Atum child template and media/templates/administrator/{child}/css/template.min.css. In practice, updating Safari on the one editor’s Mac is the cheaper fix. For third-party templates that load media/vendor/bootstrap/css/bootstrap.min.css, transpile that file into the child’s css/ folder and change the template’s asset URI to point at it.

    Step 10: Retest the supported browsers, in this order

    1. Chrome or Edge on desktop (same engine, still check Edge once if the client uses it).
    2. Safari on a real Mac or iPhone. Desktop Chrome does not stand in for iOS Safari; on iOS, Chrome and Firefox are WebKit under the hood, so “works in Chrome on iPhone” tells you nothing about Chrome on desktop.
    3. Firefox, including ESR if the client is a locked office build.
    4. The administrator on each, not only the homepage. Article edit screen included (that is where the Firefox 148 bug shows).

    Tools, in order of cost: your own devices and a colleague’s Mac; Safari Technology Preview and Firefox Developer Edition for what is coming next; Playwright (free, runs Chromium, WebKit, and Firefox from one script) for regression screenshots; BrowserStack or LambdaTest when you need a specific old macOS and Safari 15 to confirm the ranged media query case. A paid lab is not the first step, and it will not make Internet Explorer run Joomla 6.

    Do not sniff the browser

    Joomla’s old browser class, and any template switch based on the user-agent string, will mislabel current Edge, Brave, and in-app webviews. Safari on iPad reports itself as macOS Safari. Serve one template. Fix the CSS with @supports and media features like (hover: none). User-agent hacks are how a site ends up with a broken stylesheet that only one browser ever loads, which then looks exactly like a compatibility bug.

    When the honest fix is an upgrade

    If the site is Joomla 3 and the goal is “works in current Safari and Chrome”, Protostar and a pile of IE scripts are the wrong project. Move to a Joomla 5 or 6 template built on Bootstrap 5, on staging, then retest. Path notes: Joomla upgrade issues and benefits of Joomla migration. Infyways runs those jumps from $149, with a compatibility audit within 12 hours: Joomla Upgrade Services.

    What thinner articles leave out

    Topic Typical post This guide
    Browser support “Test in all major browsers” The n-2 policy, where it is recorded, and what it means for Safari 15 Macs
    Core bugs None Safari ranged media queries (#42439, #45674), Firefox 148 TinyMCE hotfix, Conservative caching and the Web Asset Manager (#37122), with version ranges
    Triage Start editing CSS Private window, console, Cassiopeia control, then the named extension
    Modern CSS “Check Can I Use” Safe-since table for the eleven features that actually break Joomla templates, with fallback pattern
    Safari “Safari is buggy” 100vh, two-tap hover, autoplay, date inputs, sticky headers, backdrop-filter prefix
    Login in Safari Not mentioned Site URL and cookie host, iframe blocking
    Where to put the fix Edit template.css Child template, user.css, same-name file override; never core files
    Safari 15 fix “Update Safari” or “replace Bootstrap” Measured: Cassiopeia 6.1.0 ships 111 ranged queries, Bootstrap is compiled in, one Lightning CSS command produces a working child template.min.css
    Legacy Add HTML5 Shiv, Respond.js, jQuery Remove them. They create the next one-browser bug

    Key takeaways

    1. Joomla 4, 5, and 6 support the current and previous major of Chrome, Edge, Firefox, and Safari. Not Internet Explorer, not Safari 15.
    2. A wide screen showing the mobile layout in Safari 15 or older is the ranged media query bug. Update Safari, or transpile template.min.css into a child template. Do not edit core CSS.
    3. Firefox 148 and a flickering TinyMCE on Joomla 5.4.3 or 6.0.3 means install the hotfix or update.
    4. Same failure in every browser is not a browser bug.
    5. Private window first, then the console, then Cassiopeia, then the extension named in the error.
    6. Safari login failures are usually the site URL and cookie host.
    7. Use @supports, 100dvh, and (hover: none) instead of user-agent sniffing.
    8. Put every fix in a child template. Do not add HTML5 Shiv, Respond.js, or a second jQuery.

    Frequently asked questions

    Which browsers does Joomla support?

    For Joomla 4, 5, and 6: the current major version and the one before it of Chrome, Edge, Firefox, and Safari. Internet Explorer is not supported. The old Joomla 3 browser list is not the matrix for current releases.

    Why does the Joomla administrator show one column on a Mac in Safari?

    Safari 15 and older do not understand the ranged media queries in Joomla 4.4.1 and newer core CSS, so the responsive grid collapses. Update to Safari 16.4 or newer, or use Chrome or Firefox on that Mac.

    Why does the article editor keep reloading in Firefox?

    Firefox 148 broke TinyMCE in Joomla 5.4.3 and 6.0.3. Install the Firefox 148 TinyMCE hotfix from the Joomla download page or update to 5.4.4 / 6.0.4 or newer.

    Why does the site look fine in Chrome and broken in Safari?

    Check a private window, then the console. If the layout is the mobile layout on a wide screen, check the Safari version. If only login fails, compare the Global Configuration site URL with the host Safari is using, including www and HTTPS.

    Why is the administrator broken in Internet Explorer?

    Joomla 4 and newer use Bootstrap 5 and modern JavaScript. IE11 is outside that support. Use Edge or another current browser.

    Will HTML5 Shiv or Respond.js fix it?

    No. Those scripts patched Internet Explorer 8. They do not fix Joomla 4, 5, or 6, and they should come out of the template.

    The layout breaks on phones but not on desktop. Is that a browser bug?

    No. If every browser breaks at the same width, it is responsive CSS or a missing viewport tag. If only iOS overflows at the bottom, replace 100vh with 100dvh.

    One browser still shows the old design after I changed the template. Why?

    That browser cached the CSS. Test in a private window, then clear Joomla cache and the CDN. Editing user.css does not change Joomla’s media version.

    Should I load jQuery so older browsers work?

    No. Extra jQuery copies cause $ conflicts. Current Joomla does not need jQuery for the core layout.

    Can I make Cassiopeia work on Safari 15 without editing core files?

    Yes. Transpile media/templates/site/cassiopeia/css/template.min.css with Lightning CSS targeting Safari 15 and save the output as template.min.css inside your child template’s css folder. Joomla loads the child’s copy first. Replacing media/vendor/bootstrap does nothing for Cassiopeia because Bootstrap is compiled into template.min.css.

    Does Cassiopeia work in all browsers?

    It works in the browsers Joomla supports. Use it as the control. If Cassiopeia is fine and your template is not, fix or replace the template.

    Who can fix a template that only fails in one browser?

    Infyways traces the console error and upgrades templates that cannot be patched. Request a Joomla upgrade audit.