79

I want to 301 redirect an entire website, but exclude everything in a folder called /uploads which exists in the /root directory.

I have googled for this, but didn't come up with anything, or I didn't think what I saw was right.

Can we crack this?

Amit Verma
  • 40,709
  • 21
  • 93
  • 115
PaulAdamDavis
  • 1,574
  • 3
  • 16
  • 19

4 Answers4

94

Try this mod_rewrite rule:

RewriteEngine on
RewriteRule !^uploads($|/) http://example.com%{REQUEST_URI} [L,R=301]

This rule does match any URL path that does not begin with either /uploads or /uploads/ (leading / is missing in the pattern due to the path prefix removal when used in .htaccess files) and redirects the request to the corresponding path at example.com.

Gumbo
  • 643,351
  • 109
  • 780
  • 844
73

Simple answer I just stumbled upon myself.

At the top before any other calls add the following

RewriteRule ^(uploads) - [L]
PseudoNinja
  • 2,846
  • 1
  • 27
  • 37
  • 2
    If anyone is curious what the [L] does: http://httpd.apache.org/docs/2.4/rewrite/flags.html#flag_l – Mark Steudel Aug 04 '15 at 20:36
  • 1
    This is an incomplete answer. I had used `Redirect` from mod_alias, and this doesn't seem to work together. So please add some info how this plays together with redirecting all other pages to *another* domain, as many others tell me that mod_alias is not the right choice for doing domain redirection. – Thomas Tempelmann Jun 03 '16 at 13:37
  • @ThomasTempelmann mod_alias and mod_rewrite do not play well together. I am not going to go into details as to why (because it is outside the scope of this question) but here is a link to another question that may help. http://stackoverflow.com/a/808089/588005 – PseudoNinja Jun 27 '16 at 18:56
  • This say uri that starts with "uploads" shouldn't be changed, and as no redirection is implicitly set, it can cause redirection loop. Why do you use braces here? – Edik Mkoyan Oct 12 '17 at 19:58
  • this breaks redirection of "uploads_b" – But those new buttons though.. Sep 02 '21 at 12:08
41

I think you want this:

RewriteEngine on
RewriteCond %{REQUEST_URI} !^/uploads/
RewriteRule (.*) http://www.newdomain.com/$1 [R=301,L]

If you get 500 Internal Error then double-check that you have a space between } and ! on the second line.

bahrep
  • 29,961
  • 12
  • 103
  • 150
Dominic Rodger
  • 97,747
  • 36
  • 197
  • 212
  • How i wrote my condition was `RewriteCond %{REQUEST_URI} !^/(app|app/.*)$` in order to get this to work. /app/ obviously being the folder i wanted to skip redirecting. – Ian LeBlanc Jul 25 '23 at 18:55
12

A mod-alias based solution

Redirect all except a specific folder

Add the following line to your root/.htaccess :

RedirectMatch 301 ^/((?!uploads).*)$ http://newdomain.com/$1

This will redirect all pages (excluding /uploads/*) from your old domain to the newdomain.

Amit Verma
  • 40,709
  • 21
  • 93
  • 115
  • 2
    This works perfectly! Very useful, since I couldn't use mod_rewrite because was not enabled on a customer's server – lucaferrario Jun 05 '16 at 16:00
  • 3
    Here is my solution for a virtual `http` host whose only purpose is to contain the `.well-known` directory for `certbot certonly --webroot` (let's encrypt): `RedirectMatch permanent ^/((?!\.well-known)(/.*)?)$ https://%{SERVER_NAME}/$1` – Tobias Oct 26 '18 at 14:34
  • 1
    It's good to have this solution for cases where the RewriteEngine is not used; in (virtual) hosts which use RewriteRules as well, it is better to use the `RewriteCond` solution. – Tobias Oct 26 '18 at 14:37