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.