Ember and Express: let Ember handle routes instead of Express? - node.js

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.

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

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"));

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.

Express.js or angular for handling routes in a MEAN application?

I am totally new to everything Nodejs/express/angular, and I just ran into a question that bothers me.
When you have a MEAN stack, it seems that routes can be handled by both Express.js and Angular.
Angular:
For instance, if I define a route in Angular, I can do it like this:
var app = angular.module("app", []).config(function($routeProvider) {
$routeProvider.when('/login', {
templateUrl: '/templates/login.html',
controller: 'LoginController'
});
$routeProvider.when('/front', {
templateUrl: '/templates/front.html',
controller: 'FrontController'
});
$routeProvider.otherwise({redirectTo: '/front'})
});
But with express.js I do:
app.get('/',function(req,res){
res.sendfile('templates/angular.html');
});
So my question is:
When do you use angular routing, and when do you use express routing?
(I might miss something very obvious here, but I hope you can point it out)
Those two serve different purposes on a single page app.
The app would do all the CRUD (endpoints where you create/read/update/delete your stuff, for example: projects, users, bills, etc). Also it would do all the authentication stuff (like /login and /register).
All of that needs routes, because you would want something like /api/users to grab all your users. All those routes, AKA CRUD routes and authentication routes goes into express.js router. Why there? Because those are routes of the backend.
On the other hand, you have your angular application, which contains the visual part of your application and there you want some routes. You want / to point to your home, you would want /users to have a page where you list your users or even /users/add to have a page with a form to add new users.
You could see it this way:
Backend routes (express ones): Those are the routes that an end user won't have to know about or even use them (your angular app will use them to communicate with the backend to work with its data but an end user wouldn't put them directly on the browser)).
Frontend routes (angular ones): Are the routes that maps to different pages of your application and because of that, end users can use them to access some parts of your application directly.

View templates and routes in node.js with AngularJS

Trying to understand how to implement AngularJS in a node.js express app. After setting up express, I need 2 things: routing and a template engine, so normally I would need to do as follows to set the app to use Jade templating engine:
app.register('.html', require('jade'));
...and then I would set routes probably like this:
app.get('/', function(req, res) {
res.render('index', function(err, html){
// ...
});
});
But if I want to use AngularJS for templating, do I still need Jade? And I read about how in AngularJS routes must be configured, does this mean the above way of declaring routes with app.get() would no longer be needed when using AngularJS?
If you don't need to add anything extra to your Angular layout prior to rendering the page for the client (i.e. in some cases you could add a window.user object in the Jade template for authentication when using PassportJS), you can completely ditch Jade altogether and let the Express static middleware render your index.html:
app.use(express.static(path.join(__dirname, 'public')));
Obviously, the files in public/ are all your Angular files, including the index.html. Be sure to require the path module too for path normalization, this isn't required though.
Afterwards, Angular will take care of the rest. This means that all your routes are defined inside the Angular app, and not in the Express routes.

Resources