Establishing a new react app with existing express webpage - node.js

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.

Related

How to serve an app with fastify, regardless of the subdomain?

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​}​`​)​;
​                ​}​)​;

How to create a node based server to serve REST API and also deploy the application.

I am new to nodeJS server area, need help in understanding how to work with REST API (using express) and deploy the angular application over a singe node server and same ports.
By deploying i want to understand if user hit below url http://localhost:8000/<page_name> then the specified page should open.
And is user hit below url using get or post request
http://localhost:8000/api/<api_name> then a json or a text will be returned.
How to run both the thing over a single node server.
Lets assume, you have all your static files in the /public folder of you app. Generally spoken, if you are using express.static, you should also get your index.html because this is handled by default for each directory.
In your case, as you are using Angular, the routing is handled from the client side (SPA). You should only have one single index.html after building your Angular app. All files from your dist folder should then be placed into your /public folder. Then you need to make sure, that initial file serving provides your index.html like so:
In this example static files are served first, then your API and if nothing is found, you are getting back you index file.
const express = require('express');
const app = express();
// serve static files
app.static(__dirname + '/public'));
// serve your API
app.get('/api/welcome', function (req, res) {
res.send('Welcome');
});
// fallback routing (server side handling)
app.get(/.*/, function (req, res) {
res.sendFile(__dirname + ‘/public/index.html‘
});
app.listen(3000);
Next time please make sure, to give all necessary information in your question ;-)
With the help from Sebastian, so far I can find a solution but its not working when i am hitting URL for different pages.
const express = require('express');
const app = express();
app.use(express.static('public'))
Please provide your suggestions.

Angular Universal app can't make post requests to my Heroku node API

My website is a SPA built with Angular, but it uses SSR with Angular Universal to provide crawlable and social media sharing content.
All GET requests in my server are handled by Universal like this:
app.engine(
'html',
ngExpressEngine({
bootstrap: ServerAppModuleNgFactory,
providers: [provider]
})
)
app.set('view engine', 'html')
app.set('views', __dirname)
app.use('/', express.static('./dist', {index: false}))
app.use('/', expressStaticGzip('./dist', {
enableBrotli: true
}))
app.get('/*', (req, res) => {
res.render('./dist/index', {
req: req,
res: res
})
})
and my pages contents are provided by Angular Services POST requests built with the same queryParams of the requested url.
One example:
If the user visits the url https://mywebsite.com/products?page=1&itemsPerPage=12 (GET request by default), the Angular Universal app and the Angular Router dynamically build my page template and the products list is provided by a Service that triggers a POST request to this URL: https://mywebsite.com/request-products with the following params in body:
{
page: 1,
itemsPerPage: 12
}
Then the Universal App builds the template with some *ngFor directives to populate it before serving it to the client.
This approach makes all my pages visible to webcrawlers and I also get the benefits of a Single Page Application.
When I'm testing my app, I build my Angular app, both Browser and Server builds, and set my environment like this:
export const environment = {
production: true,
apiUrl: 'http://localhost:7070/'
}
and serves my app in localhost, it works perfectly, without errors. My POST requests, like mentioned before, are all handled perfectly. But when I try to set my apiUrl to 'https://mywebsite.com/' and serve my app also in localhost, to access directly my API hosted in Heroku, I just can't access my POST routes.
My node express server app in Heroku is configured to accept requests from other domains, I can access it normally in my localhost server, but when I try to access it through my Angular Universal server build, it just won't work.
I know that I have to use absolute URLS in my Universal Apps, and I'm doing it already, but it's not working.
Does anyone know what I have to do to access external APIs in my Angular Universal Apps via https?
Thanks!
I've found the problem, and it's something really simple.
It turns out that I must use 'www' in my absolute url, like this:
'https://www.mywebsite.com/'
Now everything works perfectly, both from my localhost and my heroku servers.
Thanks to everyone that took some time to read my question!

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.

Ember and Express: let Ember handle routes instead of Express?

This might be a dumb question, but I'm serving an Ember app I made using ember-cli on an Express server, but when I try to access various routes, my Express app errors, saying that no route exists (which is true, because I defined the routes in Ember, not Express). How should I resolve this, and is this normal behavior?
My Ember router:
Router.map(function() {
this.route('index', {path: '/' });
this.route('portkey');
this.route('login');
});
My Express routes are just an API that do not serve any of the Ember routes, since localhost:1234 will automatically load index.html.
I've never had a problem using the Ember Router instead of the Express router. All I do is have 1 express route (for '/') which displays my Ember application index.html (well actually index.ejs) page. Not promising this is the right way to do it, but it's how I do it and it works for me.
So start with this.
app.get('/', function(req, res) {
res.render('index', {});
});
That's your express route. Now your ember routing.
App.Router.map( function() {
this.route("about", { path: "/about" });
this.route("favorites", { path: "/favorites" });
});
So as of now you have a routing structure that looks like the following:
yourdomain.com/ --> index.ejs displayed via express routing
/#/ --> this is the ember index route
/#/about --> this is the ember about route
/#/favorites --> this is the ember favorites route
Within the index.ejs file you have the basic ember file linking to your ember application.
Now onto your linking problems...
If you use the ember router, then make sure you are linking to your different routes the correct way. (Remember, ember routes start with /#/someroute).
So your links in handlebars should be something like:
{{#link-to 'some_page'}}Go to some page{{/link}}
NOT
Go to some page
Using the second, express would be trying to handle the routing but by using the first, ember is handling the routing.
So if you really think about it, you can have as many ember applications as your little heart disires because each ember application is linked to that current page in the express routing.
For example on my website, I use two routes (plus a bunch of REST routes obviously): login.ejs and index.ejs.
So for my site, I have the following routes:
mysite.com/
/#/
/#/budget
/#/history
/#/profile
/#/logout
mysite.com/login#/
#/register
#/forget
I hope this helps you a little bit.
EDIT
/#/ is a convention to tell ember you are routing via its router.
Think of it like this: Ember is a single-page framework. So when you link from page to page in ember, you aren't truely changing pages. You are just removing dom elements and replacing them with new ones. But if you go to /budget on the server, you are now going to a whole new page, not just the /#/budget section of the ember application.
I think you are just confusing what the ember router really is.
I had similar issues when trying to directly access any part of my Ember project other than index.html. From there I could easily navigate where I wanted, but it meant that providing someone a link or refreshing the page would fail.
Example: /accounts would fail.
/#/accounts would successfully redirect to /accounts however refreshing still would not work.
Solution:
Router.map(function() {
this.route('accounts');
});
Router.reopen({
location: 'hash'
});
Now all of my links are prefixed with # such as /#/accounts, refreshing and direct-linking works as expected.

Resources