Using Rack::Proxy to serve multiple React Apps on the same domain.

Rahul Ojha
Aug 24 · 3 min read

Background:

We have 4 React apps running on the local server. All apps were running on different ports because we can not start multiple React Apps on the same port. We have to build a single sign-on server. Out of 4 react apps one will be responsible for managing authentication and based on roles or department redirecting to other apps. The Auth app will get token from Auth API and will store it to local storage, and other apps will be using this token while calling APIs.

Problem Faced:

Now while calling API from any React app we need to send the token with it. Since the token is stored in local storage by Auth App which is using a different port so the local storage will not be accessible for other react apps.

You can say that now “Why didn’t you go with Cookies”, Yes cookies are shareable among HTTP ports but its size is very less which is 4 KB. So if you have to store permissions and anything else which is shareable and exceeding to 4 KB the cookies will not be useful.

Solution:

We will be using a single domain and will access different React apps using namespace in URL.

Example:

localhost:9292/app1 => app1 => localhost:3001
localhost:9292/app2 => app2 => localhost:3002
localhost:9292/app3 => app3 => localhost:3003
localhost:9292/app4 => app4 => localhost:3004

Here we need to use a reverse proxy server to do this. And we will use Ruby Rack to create a proxy server. Now you are going to say why not use Nginx here? Yes, you are correct but there is a problem, React does not add the namespace in the assets path so assets will not be loaded and you will see a blank white page always, and there is no way in development to add the namespace in asset path without ejecting CRA. If you have specified any value to homepage key in package.josn file, then it will be automatically prefixed with assets path while creating a build in production mode.

So if you are Ruby developer then you are going to enjoy rest of the blog. But if you are not a Ruby developer again there is no issue because Ruby is nice and easily understandable. You just need to follow the steps.

Step 1:

Install ruby
You can use below link to install RVM and ruby. RVM is Ruby version manager.
https://rvm.io/rvm/install

Step 2:

gem install rack

Step 3:

gem install rack-proxy

Step 4:

Create a file ./proxy_server.rb and add below code.

require 'rack-proxy'class ProxyServer < Rack::Proxydef rewrite_env(env)
request = Rack::Request.new(env)
if request.path.match('/app1')
env["HTTP_HOST"] = "localhost:3001"
@port = 3001
elsif request.path.match('/app2')
env["HTTP_HOST"] = "localhost:3002"
@port = 3002
elsif request.path.match('/app3')
env["HTTP_HOST"] = "localhost:3003"
@port = 3003
elsif request.path.match('/app4')
env["HTTP_HOST"] = "localhost:3004"
@port = 3004
# The below line is important to load assets.
# So it detects app name from the first request to the app
# which is stored in an instance variable and redirects
# to that app for assets.
elsif request.path.match('/static') || request.path.match('/assets')
env['HTTP_HOST'] = "localhost:#{@port}"
else
env["HTTP_HOST"] = "localhost:3001"
@port = 3001
end
env
end
end

Step: 5

Add a file ./config.ru and add below code

require_relative './proxy_server'run ProxyServer.new

Step: 6

Run below command on the command line where you have stored above files. This command is responsible for starting your rack server.

rackup

Now your Rack server has started and ready do proxy pass. You just need to go at localhost:9292 and your default app which is app1 as per proxy_server file will be loaded to the browser. Port 9292 is default port defined for Rack server.

Conclusion:

You can run multiple react apps on the same domain in development and because of this your local storage and cookies are shareable among all applications. In the same manner, you can also do the same thing for other client-side frameworks too.

Thank you!

Welcome to a place where words matter. On Medium, smart voices and original ideas take center stage - with no ads in sight. Watch
Follow all the topics you care about, and we’ll deliver the best stories for you to your homepage and inbox. Explore
Get unlimited access to the best stories on Medium — and support writers while you’re at it. Just $5/month. Upgrade