1

I have an Apache site with a mix of ReactJS SPA (dynamic) routing and static HTML files. It's common to see rewrite strategies that direct all requests on non-existing files to /index.html at the root of the site.

What I need is similar, but when a request comes in to a directory, it needs to first search each directory for a (default) index.html file.

So if there is a request for:

www.example.com/this/directory/

It will first look for:

www.example.com/this/directory/index.html

...before redirecting to www.example.com/index.html where the React app resides.

The partial solution I have currently is:

Options -MultiViews
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^ index.html [QSA,L]

...which does redirect to the root index.html, but does not first look for an index.html file in the subdirectory.

The static HTML portion of the site is vast, so reworking to fix all the HREFs at this point is a no-go.

I've looked around, but can't find an answer to this amongst the noise in my searching.

0

You can use the RewriteCond conditions -f and -d to check for existing files and directories, respectively:

RewriteCond %{REQUEST_FILENAME} -f [OR]
RewriteCond %{REQUEST_FILENAME} -d
RewriteRule ^ - [L]
# Apache will stop here if a file or directory exists.
# Add whatever you need afterwards, for example:
RewriteRule . index.html [L]
| improve this answer | |
  • Is this a complete solution? I tried it just now, and it didn't work. I restarted my server too. – BBaysinger Aug 6 at 7:00
  • You can see the result at bbinteractive.co/_projects/marioparty/index.html by clicking a link in the main navigation. – BBaysinger Aug 6 at 7:05
  • I don't know what you need for ReactJS. Relevant for using existing files and directories are the first three lines. I edited the example to clarify this. – Gerald Schneider Aug 6 at 7:32
  • Well... As far as doing the basic of what React needs it's functioning the same as the solution I added in my question, but it's not redirecting to a sub index.html per my ask... – BBaysinger Aug 6 at 7:51
  • Actually, I'm seeing inconsistent results, depending on which link... It doesn't make sense though. – BBaysinger Aug 6 at 8:05
0

Try something like the following:

Options -MultiViews
RewriteEngine On

DirectoryIndex index.html

# Abort early if request is already for index.html in the root
RewriteRule ^index\.html$ - [L]

# Request a directory - check for index.html in that directory
# (Excludes the document root)
RewriteCond %{REQUEST_FILENAME} -d
RewriteRule %{DOCUMENT_ROOT}/$1/index.html -f
RewriteRule ^(.+?)/?$ $1/index.html [L]

# Route all other non-file requests to index.html in the root
# (incl. directories that don't contain index.html themselves)
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule . index.html [L]

As per your original directives, this will route all directories that don't contain an index.html document to index.html in the root.

The QSA flag is not required here.


Alternatively, you could modify the DirectoryIndex to first check the current directory and fallback to the /index.html file in the root.

For example:

Options -MultiViews
RewriteEngine On

# index.html in current directory, followed by /index.html (in root)
DirectoryIndex index.html /index.html

# Abort early if request is already for index.html in the root
RewriteRule ^index\.html$ - [L]

# Route all non-file/directory to index.html in the root
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule . index.html [L]

This requires the additional directory check on the last rule block, otherwise all directory requests would be rewritten to /index.html in the root (since this would take priority).

| improve this answer | |
  • Added alternative solution relying more on the DirectoryIndex directive. – MrWhite Aug 6 at 10:53

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.