Home > Blockchain >  Redirect to frontend in directory or API in another directory using .htaccess
Redirect to frontend in directory or API in another directory using .htaccess

Time:04-13

I have the following directory structure where /root acts as my root directory despite being nested among any number of subdirectories:

  • example.com/dir1/root
    • client/build
    • api

When the user navigates to example.com/dir1/root/, I'd like all requests to be redirected to example.com/dir1/root/client/build/ but without changing the URL, as if the build/ directory contents were inside root/.

Additionally, I'd like all requests like example.com/dir1/root/api/* to be redirected to example.com/dir1/root/api/. Again, without changing the URL.

This is my current attempt, given my little understanding of how .htaccess works:

RewriteEngine on

# If an existing asset or directory is requested go to it as it is.
RewriteCond %{DOCUMENT_ROOT}%{REQUEST_URI} -f [OR]
RewriteCond %{DOCUMENT_ROOT}%{REQUEST_URI} -d
RewriteRule ^ - [L]

# Redirect all requests under /api/ to the API.
RewriteCond %{REQUEST_URI} ^/api/
RewriteRule ^ api/index.php [L]

# If the requested resource doesn't exist, use index.html (html5mode)
RewriteRule ^ client/build/index.html [L]

Note: I've searched but not found any answers for this specific scenario, and given my poor htaccess knowledge, I'm unable to cobble existing answers together very well.

CodePudding user response:

index.html is requesting resources like example.com/dir1/root/assets/style.css when this resides in /root/client/build/assets/. Essentially, I want /root/ to behave as if it's actually /root/client/build, except in the instance /root/api/ is requested.

I would implement this as 2 separate .htaccess files. One in the "root" directory (ie. /dir1/root/.htaccess) that handles the "api" requests and rewrites everything else to client/build (ie. a "false root"). And another .htaccess file in /dir1/root/client/build/.htaccess that handles just the routing within your app frontend.

For example:

# /dir1/root/.htaccess

RewriteEngine On

# Rewrite all requests under /api/ to the API handler "index.php"
RewriteRule ^api/(?!index\.php) api/index.php [L]

# Rewrite everything else to the "client/build/" subdirectory
RewriteRule (.*) client/build/$1 [L]

And...

# /dir1/root/client/build/.htaccess

DirectoryIndex index.html

RewriteEngine On

# Front-controller
RewriteRule ^index\.html$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . index.html [L]

The presence of the .htaccess file (containing mod_rewrite directives) in the subdirectory also serves to prevent a rewrite-loop, since it prevents directives in the parent .htaccess being re-processed (and rewriting the request back to client/build/... again and again).


A quick look at your existing rules...

# If an existing asset or directory is requested go to it as it is.
RewriteCond %{DOCUMENT_ROOT}%{REQUEST_URI} -f [OR]
RewriteCond %{DOCUMENT_ROOT}%{REQUEST_URI} -d
RewriteRule ^ - [L]

# Redirect all requests under /api/ to the API.
RewriteCond %{REQUEST_URI} ^/api/
RewriteRule ^ api/index.php [L]

# If the requested resource doesn't exist, use index.html (html5mode)
RewriteRule ^ client/build/index.html [L]

Issues with your existing rules:

  • Since the first rule prevents any requests that map to files or directories being processed, it will also prevent requests for /dir1/root/ itself (which is a directory) being rewritten to /dir1/root/client/build/index.html.

  • The condition RewriteCond %{REQUEST_URI} ^/api/ will never be successful since the REQUEST_URI server variable contains the root-relative URL-path, ie. /dir1/root/api/.

  • Since everything else is rewritten from the "root" to client/build/index.html, the static assets that also reside in client/build/ are not rewritten correctly (they are rewritten to index.html so presumably result in an unexpected response).

  • You can't perform the filesystem checks in the "root" .htaccess file, since the static assets that relate to index.html only "exist" after they have been rewritten.

  • Related