Not being able to find your JavaScript and CSS files is a client-side/browser issue related to your URL-path, it's not something that should be fixed in .htaccess
(at least not in this case) - although it is because you are changing this URL-path (in .htaccess
) that you are experiencing this problem.
This problem is caused by using relative URLs in your HTML. Relative to what? Remember, it is the user-agent/browser that resolves relative URLs in your HTML, not the server. So, you need to fix your URLs; not .htaccess
.
For example, if you are referencing your CSS file with a relative URL of the form href="styles.css"
(note, no slash prefix) and you are currently at the URL example.com/view.php?id=15
then the browser will naturally resolve your CSS URL and request example.com/styles.css
(in the document root). However, if you are currently at the URL example.com/watch/15
(effectively in a /watch
"subdirectory" [*1]) then the browser will resolve your relative CSS URL relative to a /watch
subdirectory, rather than the document root, so you end up with an absolute/resolved URL of the form example.com/watch/styles.css
.
([*1] Note that "subdirectory" in this context is not necessarily a physical subdirectory on your server - it is a "subdirectory" in the URL-path; an additional path-segment. But the browser does not know the difference.)
The same applies if you are using relative URLs in your custom error documents (defined with the ErrorDocument
directive on Apache). The custom error document can potentially be called on any URL, so any relative URL to a static resource (CSS, image, JS, etc.) is going to be relative to the URL that caused the error, not relative to the error document itself (the location of which is effectively hidden from the user-agent).
If you changed your JavaScript and CSS URLs to be root-relative (starting with a slash) or even absolute then you would not get this problem. This would be the preferred method. Alternatively, you can use the base
element...
base
tag/element
Alternatively you can include a base
element in the head
section of your HTML document (although this is not without its caveats [*2]). This references the absolute URL that all relative URLs are relative to. In other words, since you are expecting these relative URLs to be relative to the document root then add the following to the head
section:
<base href="http://example.com/">
Now, a relative URL such as styles.css
referenced in a document at URL /watch/15
will request http://example.com/styles.css
, not http://example.com/watch/styles.css
.
[*2] There are, however, some caveats with using the base
element. A primary concern is that any relative URL that is intended to target the current document will now target the base URL instead. This can effect in-page anchors like href="#top"
and URLs of the form href="?sortby=date"
etc. And also form
elements that submit to themselves using an empty action
attribute (eg. <form action="" ...
). These relative URLs that target the current document will need to be modified to include the full URL of the current page (which may defeat the point of using the base
tag as a workaround to begin with).
Reference: