Express routing serves angularjs content but not api - angularjs

I am using nodejs / express as the server side to my web application.
Another developer no longer working with me merged the angularjs dist bundle with the server application so that running "node index.js" it would serve the angular front end content and the server side api at the same time. It was to improve the slow load.
Since making the nodejs back end serve the ../dist folder front end I have an issue I am trying to resolve around routing.
There is a catch all route that I have current commented out as seen below.
When this is commented out I can hit all the api end points but it will not serve the angularjs content from ../dist folder.
When the catch all route is not commented out it servers up my angular content but cannot reach any of my api endpoints. All calls to the api end points return 200 but never hit the api end points.

Order matters when defining routes. If your first entry is a catch-all, then it will literally catch everything, even requests to /api. So place your catch-all as the very last entry:
app.get("/api", function(req,res) {
res.json({
message: "Hello World!"
});
});
app.get("*", function(req,res) {
res.sendFile(__dirname + "/dist/index.html");
});
It's also wise to explicitly declare your SPA route, even if you already have a catch-all:
app.get("/", function(req,res) {
res.sendFile(__dirname + "/dist/index.html");
});
app.get("/api", function(req,res) {
res.json({
message: "Hello World!"
});
});
app.get("*", function(req,res) {
res.sendFile(__dirname + "/dist/index.html");
});

Related

Shopify App Proxy - How to include my asset files in the request response | React / JS / Heroku

I'm building a Shopify App with React & Express, deployed via Heroku, which I'm trying to embed into my storefront using an Application Proxy.
When I finally load the proxied URL on my store - I get a blank screen and a bunch of 404's in the console for my .css and .js chunk files. The request was sent, authenticated, and my API's response is (200) - it just won't render anything.
Finally, after much research, I realized that Shopify has changed the path to these CSS and JS files to be my-store.myshopify.com/hash.chunk.js etc. instead of the reference to my Heroku server.
It appears this problem has been encountered before in this thread: Shopify app - how to include assets using an app-proxy with ruby on rails However, I can't seem to find a node/react/heroku equivalent to the Ruby solution presented here.
Any guidance or help would be greatly appreciated!
I begin by serving my React App through express with:
app.use(express.static(path.join(__dirname, 'client/build')));
and then when my proxy URL is hit I send back the index file within the client/build folder:
router.get('/proxy', (req, res) => {
res.set('Content-Type', 'application/liquid').sendFile(path.join(__dirname, '../client/build/index.html'));
});
I've managed to find a working solution to my problem after much trial and error.
The homepage in package.json is important. I had it set to just my Heroku address when it should actually be set to herokuaddress.com/YOURPROXYROUTE (i.e. /app/my-app)
Some additional middleware is required as well - for those interested I have the following routes set up to field requests from Shopify's app proxy.
This is set up above any of my route imports in server.js:
app.use(express.static(path.join(__dirname, 'client/build')));
and these routes are imported below that from a /shopify-routes.js file:
router.get('/proxy', (req, res) => {
res.set('Content-Type', 'application/liquid').sendFile(path.join(__dirname, '../client/build/index.html'));
});
router.get('/proxy/static/css/:file', (req, res) => {
res.set('Content-Type', 'text/css').sendFile(path.join(__dirname, `../client/build/static/css/${req.params.file}`));
});
router.get('/proxy/static/js/:file', (req, res) => {
res.set('Content-Type', 'text/javascript').sendFile(path.join(__dirname, `../client/build/static/js/${req.params.file}`));
});
Though this may be a bit heavy-handed, it has solved the problem and the app is loading within the Shopify storefront now.

React Routes not working on Server but work locally

I can go to the site index www.mysite.com and from there use the app navigation to go to www.mysite.com/login but I can't go directly to www.mysite.com/login as it gives a 404 message.
However this is working in localhost, where I can go straight to https://localhost:3000/login and it will load up the app with the login page route.
How can I get this to work on my Nginx server as-well?
You need to redirect all requests to index.html.
Refer to this for server configuration or you could redirect using server side like node or whatever server side you are using.
Try this in your server.js file
app.use("/users", require("./routes/users")); app.use("/groups", require("./routes/groups")); app.use(express.static(__dirname + "/client/build")); app.get("/*", (req, res) => { res.sendFile(path.join(__dirname, "client", "build", "index.html")); });

AngularJS app and separate index.html

I have typically used Angular to create whole websites rather than for parts of a website but now I would like to separate the homepage for SEO purposes so that it's a static HTML file and not part of the AngularJS app.
I'm using ExpressJS on the back-end but I'm not sure how I would serve the index.html and the app/index.html separately. Could someone point me in the right direction?
In server.js I normally have something like this:
app.use(function(req, res) {
res.sendFile(__dirname + '/app/index.html');
});
but what do I need to do to be able to deliver index.html if the user goes to the homepage and app/index.html if the user navigates to /somewhere
I'm trying to avoid the cost of an extra Heroku Application fee if at all possible?
See the code below. You will setup a rule wherein if the url is /home (or whatever your homepage path is), you send the user to index.html and after all the rules (if you have more rules) you will have a catchall rule where you will send user to app/index.html.
app.route('/home')
.get(function(req, res) {
res.sendFile(__dirname + '/index.html');
});
app.route('/*')
.get(function(req, res) {
res.sendFile(__dirname + '/app/index.html');
});
};

angular html5 mode allow file types with node

I have an angular app in html5 mode, and a node.js express back-end using the following snippet I can redirect everything back to the route:
app.use('/*', function(req, res){
res.sendFile(__dirname + '/public/index.html');
});
But because of this my ng-include will no longer work:
ng-include="'app/img/svg/star.svg'"
How can I allow certain file types that say end in '.svg' to still be loaded?

angular ui-router, html5 mode always refreshes to /

I am trying to use html5mode in angular, so that I can bookmark a page like http:/myhost/products (where /products is a route defined by$stateProviderRef.state(xxx) ).
To that end I've
added $locationProvider.html5Mode(true) to my app config
added 'base href="/"' (with the <>) to my index.html
added the catch all rewrite to my server.js in node.js
app.get('*', function(req, res) {
res.redirect('/');
});
restarted the node server
so what happens is that the app starts ok, all navigation works, I can go to http://myhost/products and everything works well.
However, if I press refresh at this point, I am redirected back to the index page. Looks to me as if ui-router is either losing the path (/products) or I have missed something in the config / setup
I have been browsing through the questions on StackOverflow until my eyes are bleeding, but all of the solutions to similar problems are things that I've already done (base=, redirect etc)
Anyone else has this problem and solved it ? Would be much appreciated if you could share your findings.
Thanks
You shouldn't redirect in server like that
app.get('*', function(req, res) { res.redirect('/'); });
Instead, send same index.html
app.route('/*')
.get(function(req, res) {
res.sendFile(path.resolve(app.get('appPath') + '/index.html'));
});
Take a look at this generator for more
https://github.com/DaftMonk/generator-angular-fullstack/blob/master/app/templates/server/routes.js

Resources