Serving multiple React apps from a single domain

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.