.htaccess how to redirect the contents of a directory to a subdirectory

RewriteRule ^/folder(.*)$ /folder/subfolder/$1 [R=301,NC,L]

As just mentioned in this other answer... in per-directory .htaccess files the RewriteRule pattern matches the URL-path less the directory-prefix, so the URL-path that is matched does not start with a slash. So, the pattern should be more like: ^folder(.*)$

Unless you have a requirement to use the root .htaccess file, I would create a .htaccess file in the directory you are redirecting from instead. So, in the /folder/.htaccess file (not the document root), try the following:

RewriteEngine On
RewriteBase /folder

RewriteCond %{REQUEST_URI} !^/folder/subfolder
RewriteCond %{REQUEST_URI} !^/folder/exclude-file1\.html$
RewriteCond %{REQUEST_URI} !^/folder/exclude-file2\.html$
RewriteCond %{REQUEST_URI} !^/folder/exclude-dir
RewriteRule (.*) subfolder/$1 [R=302,L]

The NC flag is not required here.

The first RewriteCond directive is to prevent a redirect loop, since we are redirecting to a subfolder of the folder we are redirecting from!

I've also used a 302 (temporary) redirect. When you are sure it's working OK, change to a 301 (permanent) - if that is the intention. 301s are cached by the browser so can make testing problematic.


Another way is to use the RedirectMatch directive.

RedirectMatch temp "^/folder\
(?!\
/subfolder|
/exclude-file1\.html$|\
/exclude-file2\.html$|\
/exclude-dir)(.*)$" \
"/folder/subfolder/$1"

As single line

RedirectMatch temp "^/folder(?!/subfolder|/exclude-file1\.html$|/exclude-file2\.html$|/exclude-dir)(.*)$" "/folder/subfolder"

Change from temp (302) to permanent (301) when ready.

The regex reads like this...
Match request line beginning (^) with /folder
not followed by (?!) exclusion 1 or (|) exclusion n followed by anything else (.*) to end of request line ($).

Redirect matched request to target/first captured group ($1).