How to serve an app with fastify, regardless of the subdomain? - node.js

I'm trying to serve different parts of my app on one server.
For instance, a user could visit,
http://app.my-site.com
or
http://admin.my-site.com
I'm using React on the frontend, conditionally producing the appropriate routes based on the subdomain, meaning I actually have one server serving one frontend that dynamically renders content.
When working with the webpack devserver, I'm able to enable this feature by adding the --allowed-hosts all option.
But then I build the project and try to serve it as follows:
app.register(require('fastify-static'), {
root: path.join(__dirname, 'client', 'dist'),
});
app.setNotFoundHandler((request, reply) => {
reply.sendFile(path.join(__dirname, 'client', 'dist', 'index.html'));
});
This works, but only locally (Heroku throws a 404 error).
After some research, I've found that express has a package for this purpose called express-subdomain. Is there a similar one for fastify or should I be doing something else entirely? After some research, I found answers online suggesting that I should add a CNAME for every subdomain I use.. which I could try, but I'm honestly just trying to understand why building my project works locally but not when deployed elsewhere.
I start the server like this:
​                ​app​.​listen​(​PORT​,​ ​'::'​,​ ​(​err​,​ ​address​)​ ​=>​ ​{
​                        ​if​ ​(​err​)​ ​throw​ ​err​;
​                        ​app​.​log​.​info​(​`Server listening on port ​${​address​}​`​)​;
​                ​}​)​;

Related

Deploy production build of ReactJS with Node express as backend

Hi even after lot of search i am still confused what is correct way to deploy my react app created using create-react-app with express as backend.
I ran npm run build which created build folder. I copied the build folder to be served as static folder of express and had put
app.use(express.static('build'));.
It is working fine for homepage, that is homepage opens when i run my express node server but when i go to anyother link outside homepage it gives 404.
Everything is working fine in developer mode, which i run by npm start command. I just want to know what i am doing wrond here. Let me know anymore info required to understand the problem. Thankyou.
It sounds like you don't have the backend server running. You need to npm start your server, and then npm start your front end if that make sense. They are 2 separate things.
Are you using client-side routing? A popular implementation of that is react-router.
Let say you are trying to access /page1, what client-side routing does is use the JS to toggle between different components to "fake" the routing, instead of rending a new HTML.
Yet, by default when you change routes, the browser does the usual stuff and send a GET request to the server asking for the corresponding HTML file. But since you only have index.html served, that's why you received 404.
You need to add the following at the end of your app.js, right before you call app.listen of your express server to tell the server to always return index.html no matter what route does it received.
/* client-side routing.
* For GET requests from any routes (other than those which is specified above),
* send the file "index.html" to the client-side from the folder "build"
*/
app.get("*", (_, res) => res.sendFile("index.html", { root: "build" }));
// your usual app.listen
app.listen(port, () => console.log("Listening"));

React frontend, Node JS backend to hosting

How to host an application React js with node js backend. Couldn't find anything on the internet. Do I need to run the
build
command on the backend? Help me please.
Thanks in advance.
The way I do it:
I build my react project and host it on the server.
As for node js, I run it on it’s own, and use Pm2 to run it on the server ( https://pm2.keymetrics.io/docs/usage/quick-start/ ) but there’s plenty of other ways you can find on google.
I hope I answered your question
I suggest you use Heroku, you get to host your full stack application for free, directly from your GitHub reposity, it takes care of automatic redeploys whenever you push something on your repo.
The only – slight – downside is having to wait ~5 seconds for the server to start up if your app hasn't been visited for a while and becomes idle (if you use a free option that is).
There are plenty of tutorials on how to do so.
As for serving the static version to your app in production — this could be of use:
server.js
/* If in production mode - serve compressed/static react content to server. i.e. what would be otherwise localhost:5000 would display frontend content.
/!\ Do not forget to generate Procfile and script for Heroku to insure proper generation of "build" directory /!\ */
if (process.env.NODE_ENV === "production") {
app.use(express.static(path.join(__dirname, "../frontend/build")));
app.get("*", (req, res) => {
res.sendFile(path.join(__dirname, "../frontend", "build", "index.html"));
});
}
Heroku will take care of it automatically if you tell your server to serve the static version with the code above.
There is also Glitch.com

Establishing a new react app with existing express webpage

I have a website made from nodejs-express and ejs , it has 5 pages home , events , about ,developer ,gallery , so all these pages are delivered using ejs. Now I need to create a web app using react and have it as another page of the website ,I searched throughout the internet i found no articles mentioning this particular scenario.
Please note I dont want my root route to be the react app , when i get a GET request on "/client" I need the react app (client) to load up.
My current senario is expressed in this sand box
https://codesandbox.io/s/integrate-react-app-4dwu0?file=/src/index.js
Where are you hosting this. You can deploy this at reactapp.yourdomain.com and set up a proxy for /client and route it to this one.
Here is your solution.
https://codesandbox.io/s/integrate-react-app-kb1c5?file=/reactAppFiles/index.html
You just need to set static files path and you have to send index.html.
it looks something like this
app.use(express.static(path.join(__dirname, "../reactAppFiles")));
app.get("/client", (req, res) => {
res.sendFile("index.html", {
root: path.join(__dirname, "../reactAppFiles")
});
I hope this answers the question.

Node.js (MERN) Serving static files and API's

Im currently building a simple app using the MERN stack to learn. What Ive done so far:
-User Registration and Login (API)
-TODO List (API and Frontend with static files)
Ok, Everything works good and as expected, except for one thing.
I attempt to use my API's for any request, but at the same time I want my whole app to work rendering in a web browser (TODO list). So, the process I've followed is:
-Start node instance
-npm run build (To build react project files)
I did a research on how to use React build in node project and I did the following:
app.use(express.static('myproject/build'));
app.get('/*', (req, res) => {
res.sendFile(path.resolve(__dirname, 'myproject', 'index.html'));
});
Good! So when I go to http://localhost:4000, it renders my index file and it actually works with my Login API, but I have some API's that are only available for consuming data and not rendering UI.
So, my problem is that when running the app, if I go to: http://localhost:4000/api/users/getdata
I get an error saying: Error: ENOENT: no such file or directory pointing the index.html
Ok, if I uncomment the code I posted before, then of course my app is not rendering UI, but my routes from API's work normally.
I know this might be setup/configuration process, but Im trying my best to understand this. If somebody could assist me with this problem please.
The hierarchy im working goes as follows:
myproject (contains models, routes (API's), middlewares, index.js)
frontend (inside folder 'myproject') (build, src (Components))
I did what #MaxAlex suggested. Changed the code from:
app.get('/*')
to
app.get('/')

Serving Angular2 app at a base URL with Express

I have an Angular2 app up and running and a very simple express server. Is it possible to only serve my application when a user visits '/app' (for example)?
If yes how can it be implemented?
I intend to have multiple Angular apps on different URLs and all of these need scripts. Hence a solution which takes care of which script to handle when would be desired.
Edit- Along with the accepted answer, if using the angular-cli, the 'base-href' has to be set to the URL of the app when building the app.
Yes, that's possible.
You have to define that endpoint as the only one:
app.get('/app', function (req, res) {
res.send(/* your application */)
})
You can use this:
// serve the angular web page
app.get('/', app.use(express.static(path.join(__dirname+'/../../public'))));
Note: change the dir name to reach your directory where contains the angular static files.

Resources