User tests: Successful: Unsuccessful:
Pull Request resolves #46610
Added a <base> tag to the Cassiopeia error.php template header. This ensures that relative assets (like images in custom modules) load correctly when a 404 error occurs on a nested URL.
Added the onAfterRender event trigger to the exception handler.
404 exceptions bypassed the normal render pipeline, so the System - SEF plugin never got to run.
now this fix ensures the event fires allowing the SEf plugin to rewrite relative asset paths (like module imagess) when a 404 occurs on a nested URL.
Issue: 404 errors on nested URLs bypass the normal render pipeline, so the SEF plugin never runs to fix relative asset paths (like module imges).
Fix: Instead of modifying core exception files, it is handled entirely within the SEF plugin:
Ensure URL Rewriting is enabled in Global Configuration and the .htaccess file is active.
Go to Administrator > Content > Site Modules
Create a "Custom" module
Set the position to error-404 and
go to menu assignemt and assign it to "All Pages"
In the content editor, switch to code view and add an image with a relative path:
for eg: <img src="images/powered_by.png" alt="Test Logo">
Visit http://yourdomain.com/thispagedoesnotexist -> the custom page appears and the image is also visible.
Visit http://yourdomain.com/category/thispagedoesnotexist -> the custom error page does not load the image.
The image fails to load.
The image loads.
Please select:
Documentation link for guide.joomla.org:
No documentation changes for guide.joomla.org needed
Pull Request link for manual.joomla.org:
No documentation changes for manual.joomla.org needed
| Status | New | ⇒ | Pending |
| Category | ⇒ | Front End Templates (site) |
I have tested this item ✅ successfully on 652f4f8
Hi @krishnagandhicode, did you check multi-lingual sites? and multi-lingual sites that are running from a sub-domain?
I ask because while I do confirm the BEFORE and AFTER condition for:
The image fails to load and then The image loads correctly,
for the Home button, I can't seem to see any difference... (it could be simply that the Joomla router is handling things correctly...
Before I pass or fail this, I wanted to check with you.
Hi @krishnagandhicode, did you check multi-lingual sites? and multi-lingual sites that are running from a sub-domain?
I ask because while I do confirm the BEFORE and AFTER condition for: The image fails to load and then The image loads correctly,
for the Home button, I can't seem to see any difference... (it could be simply that the Joomla router is handling things correctly...
Before I pass or fail this, I wanted to check with you.
Yes Uri::base() automatically grabs the right physical root URL, also for sub-domains as well.
router handles multilingual sites as well.
You are right about the home button, The original issue (# 46610) mentioned about this ("Back to home page") and I also tested using laragon with joomla in a subfolder so the button actually did break for me, I believe you tested using a hosted site - so it works fine for you.
if the main issue - relative image path is fixed with the patch - then the fix works :)
I have tested this item ✅ successfully on 652f4f8
I have tested this successfully. I was indeed using a hosted site. Thanks @krishnagandhicode!
| Status | Pending | ⇒ | Ready to Commit |
| Labels |
Added:
bug
PR-5.4-dev
|
||
RTC
| Labels |
Added:
RTC
RMDQ
|
||
Maintainer decisions:
@krishnagandhicode Could you please check and adopt if you agree?
| Labels |
Added:
Updates Requested
Removed: RMDQ |
||
Maintainer decisions:
- PR can be merged if everything works
- One tested all 4 cases, they all work. But they think the base path should be moved one line down, after the metas, because the UTF-8 charset should be always the first element in the head. Not sure if it is relevant today, but in the past this was some kind of security thing to never have wrong charset definition.
@krishnagandhicode Could you please check and adopt if you agree?
AGREED - DONE
Thanks Heiko.
Sorry, this is incorrect.
<base> may be added by document renderer joomla-cms/libraries/src/Document/Renderer/Html/MetasRenderer.php
Lines 105 to 109 in 9890bce
Usually we do not enforce this tag.
If I right remember it only added for "subfolder installation". Maybe we have to look on it current behavior and make a proper fix for all installation.
| Status | Ready to Commit | ⇒ | Pending |
no r2c
Other way to fix the issue is to look why plugin "System - SEF" does not replace the image path as it does for regular pages. That how images in other content is working.
Other way to fix the issue is to look why plugin "System - SEF" does not replace the image path as it does for regular pages. That how images in other content is working.
When a 404 exception is thrown , the exception skips the normal this->render() call and jumps to the catch block. the exception handler's render method takes over , but it never fires the onAfterRender event.

maybe thats why Sef plugin neven gets a chance to rewrite the those relative paths ?
I am not sure but can we trigger onAfterRender inside the exception handler's render method or there some other way ?
| Labels |
Removed:
RTC
|
||
| Category | Front End Templates (site) | ⇒ | Libraries |
I have tested this item ✅ successfully on 53e07f6
I am not sure but can we trigger onAfterRender inside the exception handler's render method or there some other way ?
Sorry I forgot to write a response.
It is possible but it definitely will have a side effect. Also will be incomplete because should work together with before/after event and the extension may not expect it during error.
And in general new event dispatching should not be in path release. It will be new feature not a bug fix.
What you could try is to add onBeforeRespond listener to SEF plugin, and check for
if ($app->getDocument() instanceof \Joomla\CMS\Document\ErrorDocument){ ... }.
An existing onAfterRender code will be need to move in to dedicated protected method.
Potentially with internal flag to make sure it is called only once.
This will be called then from onAfterRender and onBeforeRespond.
Other ways is
onAfterError event additionally to existing onError event inside Application try/catch block.onBefore/AfterRender in to ErrorHandler (it is still questionable).But all these will be new feature.
And need to be discussed if we really want these events there.
What you could try is to add
onBeforeRespondlistener to SEF plugin, and check forif ($app->getDocument() instanceof \Joomla\CMS\Document\ErrorDocument){ ... }.An existing onAfterRender code will be need to move in to dedicated protected method. Potentially with internal flag to make sure it is called only once. This will be called then from onAfterRender and onBeforeRespond.
Thanks @Fedik I will refactor the SEF plugin now to use a protected method for onAfterRender and an internal flag to make sure it runs once per req.
What you could try is to add
onBeforeRespondlistener to SEF plugin, and check forif ($app->getDocument() instanceof \Joomla\CMS\Document\ErrorDocument){ ... }.
An existing onAfterRender code will be need to move in to dedicated protected method. Potentially with internal flag to make sure it is called only once. This will be called then from onAfterRender and onBeforeRespond.Thanks @Fedik I will refactor the SEF plugin now to use a protected method for onAfterRender and an internal flag to make sure it runs once per req.
@Fedik Would that mean it is a new feature? If so, the PR has to be made for the 6.2-dev branch.
I mean, if we use onBeforeRespond listener we can take it as bug fix, there will be just code moving around SEF plugin.
But of course, RM still free to decide if they want it or it need to wait 6.1 bugfix or in 6.2.
And when we take another path and decide to add a new event dispatching, then it definitely a new feature.
I mean, if we use
onBeforeRespondlistener we can take it as bug fix, there will be just code moving around SEF plugin. But of course, RM still free to decide if they want it or it need to wait 6.1 bugfix or in 6.2.And when we take another path and decide to add a new event dispatching, then it definitely a new feature.
Since you suggested it's okay as a bug fix, I've prepared the patch. It works and keeps everything contained within the SEF plugin.
Should I update the PR ?
Should I update the PR ?
Yes you can update. Then RM will see the changes and can make a decision.
Should I update the PR ?
Yes you can update. Then RM will see the changes and can make a decision.
If it is really just a bug fix, 5.4-dev is ok as target branch.
| Category | Libraries | ⇒ | Front End Plugins |
Looks good now. Thanks!
@brianteeman, @Bodge-IT and/or @exlemor could I ask you to test again?
The code works
Do all these new functions need to have @ since etc
I have tested this item ✅ successfully on 5c19cf7
I have tested this item ✅ successfully on 5c19cf7
Hi @krishnagandhicode, thank you for the fix ;) works successfully!
| Labels |
Removed:
Updates Requested
|
||
| Status | Pending | ⇒ | Ready to Commit |
RTC
| Labels |
Added:
RTC
|
||
✅ Final test before merge with JBT
htaccess.txt to .htaccess.htaccess and disabled 'Search Engine Friendly URLs' and 'Use URL Rewriting'
.htaccess
.htaccess
| Status | Ready to Commit | ⇒ | Fixed in Code Base |
| Closed_Date | 0000-00-00 00:00:00 | ⇒ | 2026-03-17 19:07:28 |
| Closed_By | ⇒ | muhme |
Thank you @krishnagandhicode for your contribution. Thank you @Fedik and @richard67 for your support. Thank you @brianteeman, @Bodge-IT and @exlemor for testing.
< base > seems entirely wrong here to me. The error template should explicitly use absolute paths for its own assets (it mostly already does via jdoc:include), and if users put relative paths in custom modules, that's a documentation/editor issue — not something to fix by globally rebasing all URLs on the error page.