I tried edit web root directory via .htaccess
file:
RewriteCond %{REQUEST_URI} !newweb/
RewriteRule (.*) /newweb/ [L]
RewriteCond %{REQUEST_FILENAME} !-f
and in index.html
code change CSS
, JS
links via base tag
<base href="http://example.com/newweb/">
but anchror links not redirect to example.com/#tag
but to example.com/newweb#tag
I need the first option to work.
...but anchror links not redirect to
example.com/#tag
but toexample.com/newweb#tag
Yes, using a base
element (to correct relative URLs) is not without its caveats. An in-page anchor such as #tag
is a "relative URL", so this is now relative to the base
URL.
The only way to resolve this is to fully qualify your in-page links, with a root-relative (or absolute) URL to the current page/URL. (Which may defeat the point of using the base
tag in the first place as a workaround for your other relative URLs.) Or don't use relative URLs to your resources / other pages in the first place.
See my answer to a similar question on the Pro Webmasters stack for more detail:
UPDATE: Having had a look at your website, which is essentially a one-page website that relies on fragment identifiers (ie. #tag
) for all in-page links then you should change all relative URLs to your resources (CSS, JS and images) to be root-relative (starting with a slash) and remove the base
element.
By "root-relative", it should be root-relative to your expected client-side root, not the actual filesystem root.
For example, the following relative URL in your HTML source:
vendor/bootstrap/css/bootstrap.min.css
Should be changed to a root-relative URL (not a filesystem path):
/vendor/bootstrap/css/bootstrap.min.css
Note that this does not include the /newweb
filesystem subdirectory.
The directives in .htaccess
then internally rewrite the URL to /newweb/vendor/bootstrap/css/bootstrap.min.css
(the underlying filesystem path). The /newweb
subdirectory is then entirely hidden from the client.
By using the base
tag in your HTML you are also exposing the /newweb
subdirectory to the client (and search engines) and potentially creating duplicate content, since your site is available at both example.com/
and example.com/newweb/
.
RewriteCond %{REQUEST_URI} !newweb/ RewriteRule (.*) /newweb/ [L] RewriteCond %{REQUEST_FILENAME} !-f
However, these directives are not correct. Do you have other directives in your .htaccess
file? The last RewriteCond
directive is invalid on its own at the end. And the preceding RewriteRule
rewrites everyithing to the directory root (which may explain why you resorted to using relative URLs in your HTML source?)
To rewrite everything to the corresponding URL in the /newweb
subdirectory then you would need something like:
RewriteEngine On
# Rewrite enverything to the /newweb subdirectory
RewriteRule !^newweb/ /newweb%{REQUEST_URI} [L]
This assumes that your page only references resources that are contained within the /newweb
subdirectory and not elsewhere on the filesystem. If you are then you will also need a filesystem check.
However, by itself, this doesn't resolve the issue of example.com/newweb/
still being accessible (although this is less important now that the URL-path is not exposed). By this can be resolved with an external redirect from /newweb
back to the document root (but we need to be careful of a redirect loop, given the rewrite in the opposite direction).
So, try the following instead:
RewriteEngine On
# If /newweb is requested directly then redirect to remove it
RewriteCond %{REDIRECT_STATUS} ^$
RewriteRule ^newweb/?(.*) /$1 [R=302,L]
# Rewrite enverything to the /newweb subdirectory
RewriteRule !^newweb/ /newweb%{REQUEST_URI} [L]
Change the 302 (temporary) rediredct to 301 (permanent) only when you have confirmed it is working OK.