In my playing around with React and Redux/Relay I wanted a way to serve them up from one host. Along with the Rails GraphQL/API backend.
There were plenty of examples of getting a single React app up and running with rewrite rules or .htaccess
. But I wanted things a little differently. Mostly I didn’t want to have to have the trailing /
.
I had initially set this up with Apache 2.4 and it was working great, until I wanted to deploy it with ActionCable integration I spent way too much time trying to get websockets to work with Apache so I ended up switching to nginx. So long Apache, ~20 years was a good run.
Here’s the Apache config I was using.
<VirtualHost :443>
ServerName example.com
RailsEnv production
RewriteEngine On
DocumentRoot /path/to/your_app/public
<Directory /path/to/your_app/public>
Require all granted
</Directory>
<LocationMatch "/redux.*">
# match without a trailing /
RewriteCond %{REQUEST_URI} ^/redux$
RewriteRule ^ %{DOCUMENT_ROOT}/redux/index.html [L]
# handle any files local to the parent directory
# this allows deep links into the app to work
RewriteCond %{DOCUMENT_ROOT}%{REQUEST_URI} -f [OR]
RewriteCond %{DOCUMENT_ROOT}%{REQUEST_URI} -d
RewriteRule ^ - [L]
RewriteRule ^ %{DOCUMENT_ROOT}/redux/index.html [L]
</LocationMatch>
<LocationMatch "/relay.*">
RewriteCond %{REQUEST_URI} ^/relay$
RewriteRule ^ %{DOCUMENT_ROOT}/relay/index.html [L]
RewriteCond %{DOCUMENT_ROOT}%{REQUEST_URI} -f [OR]
RewriteCond %{DOCUMENT_ROOT}%{REQUEST_URI} -d
RewriteRule ^ - [L]
RewriteRule ^ %{DOCUMENT_ROOT}/relay/index.html [L]
</LocationMatch>
</VirtualHost>
And here’s the same config for nginx
server {
listen 443 ssl;
server_name example.com;
passenger_enabled on;
passenger_app_env production;
root /path/to/your_app/public;
# match without a trailing /
location ~ ^/redux$ {
try_files $uri/index.html /index.html;
}
# handle any files local to the parent directory
# this allows deep links into the app to work
location /redux {
try_files $uri $uri/ $uri/index.html /redux/index.html;
}
location ~ ^/relay$ {
try_files $uri/index.html /index.html;
}
location /relay {
try_files $uri $uri/ $uri/index.html /redux/index.html;
}
}
By the way, that nginx config is the actual config that is serving up the Rails app for API and GraphQL, React Apps and the ActionCable endpoint.