Joomla system plugin
Fix the label you can't edit.
Give any element on your site an accessible name, without touching a line of template or vendor code.
Point it at a CSS selector, choose aria-label, title or aria-hidden, and type the value. It applies on every page, and it keeps applying after the next template update.
Why it exists
The gap was in someone else's code.
It started with a "back to top" button that had no accessible name at all. A screen reader would announce a button and nothing else. The markup lived inside a template's own system plugin, not in an override, so editing it directly meant the fix would quietly vanish on the next update.
This plugin is the way around that. You list the elements and the attributes they need, and it adds them in the browser once the page loads. Your template and extensions stay exactly as their authors shipped them.
How it works
Three fields per fix.
1 · Selector
Say what to patch
An ID like #back-to-top, a class like .social-icon, or anything more specific. It matches every element that fits, not just the first.
2 · Attribute
Pick what to set
aria-label to give it a name, title for a tooltip, or aria-hidden to hide decoration from screen readers.
3 · Value
Type the words
The text a visitor or screen reader should get, such as "Back to top". For aria-hidden, use true.
Before
An icon button with no name
<button id="back-to-top" type="button">
<span class="icon-arrow-up"></span>
</button>
After
Same button, now announced properly
<button id="back-to-top" type="button"
aria-label="Back to top">
<span class="icon-arrow-up"></span>
</button>
Illustrative markup. Yours will differ, and that's the point: you target whatever your template actually outputs.
What's in the box
Small plugin. Steady hands.
Any selector
As many rows as you need
Add a row for each fix. Rows stack, and each one applies on every page of the site.
Late content
Catches what loads later
Menus and widgets that appear after the page loads still get patched. It watches for new elements quietly.
Override on purpose
Corrects wrong labels too
It replaces any existing value, so it can fix a misspelled or unhelpful label, not just fill an empty one.
Safe by design
Locked to three attributes
Only aria-label, title and aria-hidden are allowed, and a bad selector can't break the page.
Where it earns its keep
The usual suspects.
Icon-only buttons
Back to top, menu toggles and search buttons that are only a picture.
Social links
A row of logos becomes "Follow us on Facebook" instead of silence.
Decorations
Hide purely visual flourishes so screen readers skip them.
Vendor code
Anything a template or extension outputs that you shouldn't edit directly.
Straight talk
Good to know first.
Find the gaps first
It fixes, it doesn't hunt
Use Joomla's own accessibility checker, Jooa11y, to spot what needs a label, then patch it here. Switch the checker off again on a live site.
Runs in the browser
It needs JavaScript
Patches are applied after the page loads. Visitors with scripts turned off, and anything that reads only the raw HTML, won't see them.
A patch, not a cure
Fix the source when you can
If the template is fixed later, this plugin won't back off by itself. Remove the row once it's no longer needed.
For the technical crowd
Under the hood.
- Works with
- Joomla 4, 5 and 6. A Joomla 3 build is not offered.
- Type
- System plugin, site side only. Nothing runs in the admin.
- Dependencies
- None. No jQuery, no framework, no extra files to load.
- How it applies
- One small inline script in the page head. It waits for the page to be ready, patches every match, then watches for new elements with a debounced observer.
- When idle
- With no rows configured, it adds nothing to the page.
- Safety
- Attribute whitelist, escaped output, and selectors wrapped so a typo can't throw an error on the page.
- Licence
- GPL v2 or later.
Ready to patch it?
It's free. Download it, or tell us what you're trying to fix.
Accessibility Attribute Patch
Changelog.
1.1.0
Stable · October 2026A second job for the plugin: new-tab links. Patching itself is unchanged.
- New-tab Links tab. For every front-end
target="_blank"link, the plugin addsrel="noopener"(keeping any values already there) and a screen-reader hint such as "(opens in new tab)". - Hint goes where it will be announced: a hidden span for links with text, the
aria-labelfor links that have one, and anaria-labelbuilt from the image's alt text for image-only links. - No double announcements: links that already mention a new tab or window, or already contain the hint, are left alone.
- Optional visible arrow, your own hint text for other languages, an exclusion class (default
no-newtab-hint), and a hidden-text class setting for templates that usesr-only. - Links inside
code,pre,script,styleandtextareaare skipped, andmailto:andtel:links are handled the same way. - Runs in the same pass as the patches, and works even with no patch rows. With both off, the plugin still adds nothing to the page.
- Test checklist (
TESTING.md) and new language strings included.
Earlier releases
1.0.5Docs
- The README now says plainly that Joomla 4, 5 and 6 are supported and that Joomla 3 is not. Confirmed working on a live Joomla 6 site running the T4 template.
1.0.4The real fix
- Fix: saved rows were being thrown away. Joomla stores each row's three values one level deeper than expected, under the form group's name, so every row failed validation and was silently dropped. The plugin now unwraps that level first, and still reads flatter shapes if another Joomla version produces them.
- Found with a diagnostic build that printed the raw saved data from a live site, not by guesswork.
1.0.3String-shaped rows
- Fix: depending on the Joomla version, saved rows can come back as one JSON-encoded string rather than a list, which PHP quietly loops over zero times. The plugin now decodes it first.
1.0.2Timing fix
- Fix: the patch script runs in the page head, before the page body exists, and crashed trying to watch a body that wasn't there yet. Patching and the observer now wait until the page is ready.
1.0.1Docs
- README gained a section on finding what needs patching with Joomla's own Jooa11y checker, and why to switch it off again on a live site.
1.0.0First release
- Set
aria-label,titleoraria-hiddenon any CSS selector, site-wide, from a list of rows in the plugin settings. - Re-applies patches when new content appears, with a debounced observer that never watches attribute changes, so it can't trigger itself.
- Attribute whitelist, escaped output, and invalid selectors skipped quietly instead of breaking the page.
- Does nothing in the admin, and nothing at all when no rows are configured.