I have my react app running great on my local dev server but it did not work when I dump my production ready files straight into Apache\'s htdocs directory:
Here is
The above solution works for Ubuntu as well but I have struggled a bit with it so here are the steps necessary to make it work.
Location of the file where you need to place the above mentioned configuration is under
/etc/apache2/sites-enabled
default is
/etc/apache2/sites-enabled/000-default.conf
Then you need to make sure that RewriteEngine is running (otherwise you will get an error when restarting Apache server).
sudo a2enmod rewrite
Finally, restart Apache server
sudo /etc/init.d/apache2 restart
Now, it should work.
When you are using default configuration (root of the website is under /var/www/html
), then all you need to do is to place
<Directory "/var/www/html">
RewriteEngine on
# Don't rewrite files or directories
RewriteCond %{REQUEST_FILENAME} -f [OR]
RewriteCond %{REQUEST_FILENAME} -d
RewriteRule ^ - [L]
# Rewrite everything else to index.html to allow html5 state links
RewriteRule ^ index.html [L]
</Directory>
to the above mentioned file under <VirtualHost ...>
None of the solutions posted so far appear to address the issue where missing ressources incorrectly return 200 instead of 404, which can make debugging when certain files are missing rather annoying.
My solution is to instead watch what type of resource the request expects to recieve, since browsers will ask for HTML when navigating to a page (Firefox asks for text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
) but not when accessing resources after the initial load (JS files imported via <script>
or as ES6 modules ask for */*
, CSS files ask for text/css,*/*;q=0.1
, accessing JSON via the fetch()
API will specify application/json, text/plain, */*
and so on). By relying on that assumption, one can configure Apache to serve the Single page app when trying to access a non-existent file (such as a route that only works within the Single-page app) without also sending it whenever said SPA asks for a CSS file that has been renamed or a missing JSON file.
EDIT: MDN has a list of common values for the Accept header.
<Directory "/var/www/httpd/example.com">
RewriteEngine on
# Browsers will specifically ask for HTML (among other things) on initial page load
# That is, if the *user* tries to access a *nonexisting* URL, the app is loaded instead
# but if a webpage attempts to load a missing resource it will return 404.
# (You can still go to /myreactapp/favicon.ico, but a missing /myreactapp/favicon.png resource won't return 200)
# if (HTTP_ACCESS.contains('text/html') && file_not_exists(REQUEST_FILENAME))
RewriteCond %{HTTP_ACCEPT} text/html
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^ index.html [last]
# Any ressources loaded by index.html should behave correctly (i.e: Return 404 if missing)
RewriteRule ^ - [last]
AllowOverride None
Options FollowSymLinks Multiviews
Require all granted
</Directory>
Go on this directory
/etc/apache2/sites-available
open File : 000-default.conf
Change its permission : 777
Paste code on bottom of file
RewriteEngine on
# Don't rewrite files or directories
RewriteCond %{REQUEST_FILENAME} -f [OR]
RewriteCond %{REQUEST_FILENAME} -d
RewriteRule ^ - [L]
# Rewrite everything else to index.html to allow html5 state links
RewriteRule ^ index.html [L]