Score:2

.htaccess - Redirect all URLs with one exception

io flag

I want to redirect all URLs from one domain to another. Some of the old URLs have new counterparts with specific pages to redirect to. All other URLs should redirect to the homepage of the new domain.

But I don't want to rediret the sitemap.xml. So I made an exception like this (from here):

RewriteCond %{REQUEST_URI} !^/sitemap.xml?$

But it doesn't work.

Here's my complete code:

RewriteEngine on

# exception for the sitemap:
RewriteCond %{REQUEST_URI} !^/sitemap.xml?$

# specific redirects:
Redirect 301 /old-page  https://www.new-domain.com/

# catch the rest:
RedirectMatch 301 ^/ https://www.new-domain.com/

Is there something wrong?

Score:5
jp flag

As mod_alias is recommended for simple redirects, here's the solution with mod_alias:

# Specific redirects:
Redirect 301 /old-prefix https://www.example.com/
Redirect 301 /another-old-prefix/  https://www.example.com/path/

# Catch the rest, except the sitemap:
RedirectMatch 301 ^/(?!sitemap\.xml$).* https://www.example.com/

The main functional difference with Redirect is that it redirects everything with the same prefix.

Then any request beginning with URL-path will return a redirect request to the client at the location of the target URL. Additional path information beyond the matched URL-path will be appended to the target URL.

Score:4
kz flag

You are mixing mod_rewrite (RewriteCond, RewriteRule) and mod_alias (Redirect, RedirectMatch). The stray mod_rewrite RewriteCond directive will not do anything here. This directive only applies to the next RewriteRule directive.

Consequently, RewriteEngine is mod_rewrite and has nothing to do with mod_alias.

You can use either, but not both here, since you can get unexpected conflicts due to the order of processing.

Using mod_rewrite:

RewriteEngine on

# Specific redirects:
RewriteRule ^old-page$ https://www.new-domain.com/new-page [R=301,L]

# Catch the rest, except the sitemap:
RewriteRule !^sitemap\.xml$ https://www.new-domain.com/ [R=301,L]

Note that the URL-path matched by the RewriteRule pattern does not start with a slash.

You don't need a separate condition (RewriteCond directive) if you only want to make an exception for a single URL.

You will need to clear your browser cache before testing since the 301 (permanent) redirect will have been cached by the browser (and possibly intermediary caches). Test with 302 (temporary) redirects to avoid potential caching issues.

Aside: Redirecting the remaining URLs to the homepage on the new domain is often detrimental to SEO and users. It is generally better to serve a custom 404 with a meaningful message to users. Redirecting to the homepage will leave these pages in the search results for longer but will eventually be seen as a soft-404 by search engines (incl. Google). Users are left confused when they end up on a page they are not expecting and just bounce.

Alternatively, using mod_alias:

# Specific redirects:
Redirect 301 /old-page https://www.new-domain.com/new-page

# Catch the rest, except the sitemap:
RedirectMatch 301 ^/(?!sitemap\.xml).* https://www.new-domain.com/

Note that mod_alias does not have separate "conditions". Instead, we are using a negative-lookahead in the catch-all rule to make an exception.

I sit in a Tesla and translated this thread with Ai:

mangohost

Post an answer

Most people don’t grasp that asking a lot of questions unlocks learning and improves interpersonal bonding. In Alison’s studies, for example, though people could accurately recall how many questions had been asked in their conversations, they didn’t intuit the link between questions and liking. Across four studies, in which participants were engaged in conversations themselves or read transcripts of others’ conversations, people tended not to realize that question asking would influence—or had influenced—the level of amity between the conversationalists.