Redirect all pages except one to homepage via .htaccess

Problems

I get too many redirect: all urls redirect infinitely to themselves, why?

Apache rewrite rules are processed top-to-bottom, so your custom rewrite rule is always processed first. The R redirect flag instructs Apache to tell the browser to make a new request to the altered URL instead of serving the destination of the rewrite at the current address, and the L “last” flag tells Apache to ignore all proceeding rewrite rules – so whenever your RewriteRule is applied, a new request is made and your rules are processed once again from the top.

Your RewriteCond instructs Apache to process the proceeding RewriteRule whenever the request URI path does not begin with /privacy-policy – so virtually every request is resulting in a redirect before any of the other rules in your .htaccess can be so much as evaluated.

As @MarkKaplun alluded to in the comments $1 is a back-reference that’s substituted with the portion of the matched URI contained in the first “capture-group” (the first set of parenthesis in the pattern). Since .* literally matches any number of any characters, in your RewriteRule $1 is substituted with the entire URI path.

In essence, your rewrite rules:

RewriteCond %{REQUEST_URI} !^/privacy-policy/
RewriteRule (.*) http://www.mywebsite.com/$1 [R=301,L]

evaluate to “If the URI does not begin with /privacy-policy/, have the web-browser send a new request to http://www.mywebsite.com/(original URI path).

So, for illustrative purposes, say you navigated to http://www.mywebsite.com/blog/2015; here’s what happens with each request:

  1. /blog/2015 does not start with /privacy-policy/, tell the browser to go to http://www.mywebsite.com/blog/2015.
  2. /blog/2015 does not start with /privacy-policy/, tell the browser to go to http://www.mywebsite.com/blog/2015.
  3. /blog/2015 does not start with /privacy-policy/, tell the browser to go to http://www.mywebsite.com/blog/2015.
  4. […]

Removing the $1 back-reference from the RewriteRule is insufficient, as a URI path of / (or a simply empty one) still does not qualify as beginning with /privacy-policy/, resulting the in the behavior:

  1. /blog/2015 does not start with /privacy-policy/, tell the browser to go to http://www.mywebsite.com/.
  2. / does not start with /privacy-policy/, tell the browser to go to http://www.mywebsite.com/.
  3. / does not start with /privacy-policy/, tell the browser to go to http://www.mywebsite.com/.
  4. […]

You can verify this behavior by taking a look at your Apache installation’s log files.


Solution

If you don’t plan on using WordPress’s intended address routing, there’s no reason to keep the default rewrite rules and stack more on top of them. Tailor them to your needs instead of adding complexity:

<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteRule ^(/|index\.php)$ /index.php? [L]
RewriteRule ^/?privacy-policy/?$ /index.php [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /? [L,R=301]
</IfModule>

In summary,

  1. .

    RewriteRule ^(/|index\.php)$ /index.php? [L]

    If / or index.php was explicitly requested, serve index.php, but drop the querystring (in order to prevent changing pages via query-var manipulation) and stop processing rewrites.

  2. .

    RewriteRule ^/?privacy-policy/?$ /index.php [L]

    If privacy-policy (with or without leading and trailing slashes) was explicitly requested, serve index.php and stop processing rewrites.

  3. .
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteCond %{REQUEST_FILENAME} !-d
    RewriteRule . /? [L,R=301]
    

    If the requested filename is not a file and not a directory, match a single character anywhere (in order to apply the rule no matter the URI) and tell the browser to make a new request to / and discard it’s querystring. Stop processing rewrites.

It’s worth noting that your intended outcome will probably produce a lot of unexpected behaviors – you’ll likely be unable to access the administrative dashboard, for one. Attachments may also break. But the above should at the very least provide a good starting point for learning more about rewrite directives.