1

General idea of the web page:

  1. domain.com : leads to login page for admin and seller.
  2. shop.domain.com : leads to the shop of the seller.
  3. Planning to use React.js as frontend and Nodejs (Express Js) for backend.
  4. Haven't decide to host everything on Heroku, or only Nodejs backend on Heroku and React.js at somewhere else, since we are separating the development process.

How to redirect user to respective page according to the URL access (with or w/o subdomain)

In fact, there is a package from npm named express-subdomain-handler that aids the domain and subdomain routing in the server side, and I have no problem to done it and deploy to Heroku.

app.use(subdomainHandler({
    baseUrl: 'localhost',
    prefix: 'subdomain',
    logger: true
}));

app.get('/', function (request, response) {
    response.send('WELCOME TO LOCALHOST');
});

app.get('/subdomain/:shop', function (request, response) {
    response.send('WELCOME TO SUBDOMAIN');
});

I believe the routing above is more towards Server-Side-Rendering, as it only renders the respective page according to the URL (Or endpoint) accessed. But is it possible to render React app by this way? Cause what I had done before are just basically rendering of .ejs page, that's why I am not sure about this, and I never worked with React.js before.

Secondly, What if I host the React app on another server, maybe Vercel or NGINX or anything, and access the backend service in heroku by using REST API, is this a correct method to deploy a website? If so, is the domain and subdomain routing will be done at the hosting site of the React app, or inside the code itself, instead of expressjs in Heroku? As I believe expressjs will only responsible to create a series of endpoint to be listen. For example, inside express.js:

app.get('/hello', (req, res) => {
   res.send("Hello from domain");
})

app.get('/subdomain/hello', (req, res) => {
   res.send("Hello from subdomain");
})

And react app will just need to access these API without considering the routing issue of subdomain and domain at the backend. I believe this is somehow known as Client-Side-Rendering as every REST API will return JSON data to be rendered.

So if I perform in this way, how do we determine the page to be displayed by React app according to the URL accessed? For example, if domain.com it will leads to dashboard page, and shop.domain.com will leads to shop page?

3 Answers 3

3

Firstly, I've never use Heroku for hosting, so my solution might be different for your environment but, I think the whole concept will work for you.

There are no fixed answer for your questions but what I'm thinking right now can be helpful for you :) There are lots of sub-questions for your questions, so I seperated it.

And I'm not fluent with english so there can be some mis-communication between you and me, please let me know if there are wrong in what I understood from you question.

Q. But is it possible to render React app by this way?

(What I understood : can react app be hosted by SSR )

A. You can serve react app with SSR using code splitting and server side rendering, you'd better use server-side rendering for some meta tag and SEO-required pages, unless you need full SSR application. In case you need full ssr, there are also fancy framework for it, Next.js. You might already know about this judging by you refered Vercel.

Q. What if I host the React app on another server, maybe Vercel or NGINX or anything, and access the backend service in heroku by using REST API

(What I understood : can react app be hosted with another server? NGINX = using server instace, Vercel : using serverless architecture )

A. Also it can be hosted like that. It seems like this one is more react-like. But I don't recommend the Vercel for hosting since E-commerce service is required a lot of end point, Check out the pricing policy of Vercel.

Q. So, let say I am using Heroku for Express backend, does it means that I need to create 2 apps separately instead of combining them together

A. you can host multiple host for computer resource or not. In case, you are planning to multi-host, you might need proxy server to point other servers, In opposite, for single-host, reverse proxy to point each app.

Q. express-subdomain-handler vs. vhost

A. There are no fixed answer. you could achieve what you want using vhost or express-subdomain-handler. Or Both.

My solution concept is using single server instance with Reverse Proxy. Let Nginx virtual host your multi apps in single server.

What I recommend:

App list.

  1. react host - nodejs application
  2. client api host - nodejs application
  3. admin react host - nodejs application
  4. client api host - nodejs application

I used AWS S3 for hosting React apps and EC2 for API apps.

Structure Concept.

( NS / DNS ) : domain.com points your-ip
    |
    ( Server instance )
        |
        ( Nginx ) - virtual hosting
            |
            ( www.domain.com ) --- > client react host : ( node app for server side rendering ) : React rendered file for each route. 
                                                       Or you can just respond with index.html for all route for skipping SSR
            |
            ( api.domain.com ) --- > clinet api host : api.domain.com/what, api.domain.com/what/ever?you=want
            |
            ( admin.domain.com ) ---> admin react host : admin.domain.com/* : sending index.html  //static hosting and let all route point for index.html
            |
            ( admin-api.domain.com ) ---> admin react host : Only if you want to seperate. Or you can combine this with api.domain.com using subrouter

How to build the Structure.

Step 1. Server hosting.

I don't know much about Heroku but I guess there are aws ec2-like service(cloud computing) and s3-like service(static file service),
This can be single or multiple depending your choice. let's say you wanna go with single server and use virtual host for multiple service end point.

Step 2. Network layer setting

let's say name-server and DNS server part is network layer. I used AWS Route 53 for this.

    2.1 Buy an domain
    www.your-service.com 
    
    2.2 Add some CNAME to point your web-server host
    - your-service.com,
    - www.your-service.com
    - api.your-service.com,
    - admin.your-service.com    
.
.
.

Step 3.Create nodejs application (application layer)

I'm assuming that you had one already judging by code in your question.

ubuntu@ip-your-ip:~/project$ ls
api  cli   admin   admin-api   config   libraries  middlewares  models  node_modules   package.json 

ubuntu@ip-your-ip:~/project$ cd api

ubuntu@ip-your-ip:~/project/api$ ls
README.md  app.js  bin  config.json  pm2.config.js  node_modules  package.json  routes

ubuntu@ip-your-ip:~/project/api$ pm2 start pm2.config

PM2 is node application deamonizer, you can use any daemon for this.

PM2 reference. https://pm2.keymetrics.io/docs/usage/application-declaration/

Step 3. Nginx points for nodejs application


nano /etc/nginx/nginx.conf

listen 80;
server_name client.domain.com;
location / {
             proxy_http_version 1.1;
             proxy_pass  http://localhost:3000;
}

listen 80;
server_name api.domain.com;
location / {
             proxy_http_version 1.1;
             proxy_pass  http://localhost:3001;
}

listen 80;
server_name admin.domain.com;
location / {
             proxy_http_version 1.1;
             proxy_pass  http://localhost:4000;
}

listen 80;
server_name admin-api.domain.com;
location / {
             proxy_http_version 1.1;
             proxy_pass  http://localhost:4001;
}

I hope this solution is helpful for you :)

Sign up to request clarification or add additional context in comments.

3 Comments

I really appreciate your effort on answering my questions ! I think I am going with single server with with multiple service endpoints (btw considering EC2 for backend now), but I do have some questions regarding to your reply. Does multiple service endpoints means that I create to different endpoints, api/ for domain.com, and /api/subdomain for subdomain.domain.com to handle different request?
So I believe NGINX is setup inside EC2, and it's run in front of the backend server. Which means, on the Web hosting site, I just create different CNAME and point to the IP/instance of EC2 and let NGINX web server to decide the target URL for the request to go?
If my React App is deployed in S3, so I just change the location / { proxy_pass http:// } to the IP or URL of my S3 bucket?
2

1. About subdomain

api/ and api/subdomain can be impleted by NGINX virtual host but since you planned for virtual hosting for subdomain, api.domain.com.

go with api.domain.com/foo, sub.domain.com/bar seems more reasonable!

Ex.

listen 80;
server_name api.domain.com/api;
location / {
             proxy_http_version 1.1;
             proxy_pass  http://localhost:4000;
}

listen 80;
server_name api.domain.com/api/subdomain;
location / {
             proxy_http_version 1.1;
             proxy_pass  http://localhost:4000;
             #notice that api application is one and you are seperating namespace in it.
             #you can do the same thing in Node.js with subrouter. ( check out Router API in Nodejs official Site )
}
api.domain.com/foo, sub.domain.com/bar
listen 80;
server_name api.domain.com;
location / {
             proxy_http_version 1.1;
             proxy_pass  http://localhost:4000;#this one is node application listening port 4000
}

listen 80;
server_name sub.domain.com/;
location / {
             proxy_http_version 1.1;
             proxy_pass  http://localhost:4001;#and this is node application listening port 4001
}

Access in first case.


    GET    api.domain.com/api/foo
    GET    api.domain.com/api/subdomain/bar

Access in second case.


    GET    api.domain.com/foo
    GET    sub.domatin.com/bar


2. So true. Let every CNAME point to your EC2(or any web application on any server instance) as a origin


3. You don't need to configure server engine for your S3 instance.

S3 is not in EC2 instance but somewhere in AWS data center. So Virtual host is not a solution for route S3 bucket. Instead of doing that, you can use Route53 to route your S3 bucket for your domain.

If you already has a domain. You can configure your name server to point AWS name server. You can get NS/DNS from Route 53 console once you register the domain.

Meantime, there are a problem with static hosting react app(S3-like hosting), you have to give up the SSR. Because S3 is a static host, it can't perform like Lambda or server instance can.

S3 will just retrieve the stored file for the request, in this case, it will be the build file for react app. So if I were you I'm gonna go with S3 only for admin react application since SEO is not important on admin application.

To do SSR with express

Let your root domain(www.domain.com) point to client nodejs server in EC2. And nest the react build file for the server. React SSR app via Express is quite complicated to explain but there are planty of examples, so you might wanna google it.


Off the topic, I built my e-commerce react app on S3 and I'm regret doing it because SSR part is not easy. There are many solutions about it but amont those, next.js framework seems the best choice to do ssr ASAP.

4 Comments

Thanks for your very informative reply. So basically, if SSR: Then I should deploy everything in EC2, and works on the 1. About subdomain for reverse proxy, else if CSR, I can just separate the deployment on EC2 for express and S3 for React, then with the aid of Route 53, CNAME will directly pointed to S3 bucket. In that case, it doesn't matter on virtual hosting the backend according to domain and sub or not, as all API request can be pointed directly to EC2 in the method of Access in first case. And, sticking with CSR means giving up on SEO. Am I understand it in a correct way?
Yeah that's what I'm talking about bro, I think that works fine for you!
Hey man, thanks for so much information ! I do learn a lot from your reply and I really appreciate it, hopefully I manage to deploy the application successfully. Thanks.
Good luck for your development and I'm glad that my answer is helpful!
0

I think this is not on react part. React is the browser library and cannot handle the domain part.

I don't recommend to handle this part with express also since this need to use reverse-proxy, you'd better use Nginx,Apache, some other server engine to handle subdomain.

What you planned can be hosted like this,

Domain

  1. create domain.com
  2. add cname to shopping.domain.com

Server

  1. create admin server, client server
  2. reverse proxy those servers

Client

  1. create 2 react project.
  2. domain.com serve admin react build file.
  3. shop.domain.com serve shop react build file.

I also recommend static file hosting for admin react application, if you don't need to expose the admin page for the search engine.

5 Comments

Oh I forgot the routing part. Most of React application are using browser routing not server routing
So, let say I am using Heroku for Express backend, does it means that I need to create 2 apps separately instead of combining them together, so that it will resulted as: API from domain will point to foo.herokuapp.com and API from subdomain will point to bar.herokuapp.com? Or I should combine them together and determine it by using vhost? In this case, where should we setup the NGINX for reverse proxy?
Does it means that I need to setup nginx on the static file hosting site and reverse proxy it either to serve admin react or shop react, then all the API will just point back to to Heroku app? So in this case we can either separate the Heroku app, API pointing to foo.herokuapp.com/ or bar.herokuapp.com/, or we just combine it and add some works to the REST Api design. Example, / for all request from admin react and /shop/ for all request from shop react?
I wish to reclarify my idea : Firstly, create a Heroku app with the build-pack link, then we push our front end repo, which contain 2 different React app in it, the admin and shop react app, to the Heroku app we created. Then we configure the NGINX setting (not sure where or how to configure yet, still need some reading) inside the build-pack so that we can serve different React app according to the incoming URL type, either domain or subdomain.
Then the express backend will be deploy on another Heroku app (or maybe 2 Heroku apps for microservice architecture) and handle all the REST API, then return the JSON data back to React App. Is it?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.