nodejs express url rewrite? - node.js

I am new to nodejs and just started learning it. I started with express. Everything's good but have a question not sure if this needs to be URL rewrite or URL redirect.
views folder looks like below, (jade files)
views
- index
- news
- videos
The first page definitely is index, url is localhost:3000. Now I want my news page to be the index page, so when I enter localhost:3000 or localhost:3000/news, I want always to see the news.jade content. but I don't want to duplicate news.jade to index.jade. So I think the best thing is to have a urlwrite, then either localhost:3000 or localhost:3000/news will get news.jade content.
if a url rewirte needed to achieve my goal, is below code is a good example?
app.use('/news', function(req, res, next){
var old_url = req.url;
req.url = '/index';
next();
});
I searched a while, but didn't really get an answer, could someone please help?
Thanks

If you have scaffolded using express-generator, then it would create a routes folder that handles all the routing code. Refer this link to know more on express generator.
You have to edit the index.js file in that folder
router.get('/', function(req, res, next) {
res.render('news');
});
When ever the application receives a / request that is localhost:3000/ it will render the news file.
If you have any more doubt you can refer the manual here http://expressjs.com/en/guide/routing.html
Edit - Fix typo

Related

Unable to access ExpressJS route via href link

I'm not sure if this is a security feature or if I'm missing something obvious. I need to access one of my ExpressJS routes directly via a standard link on the page.
If I type the URL in to my browser location bar, I get the desired result. However, if I put that exact URL in a standard link on one of the pages on the site, the route never gets hit.
EDIT: Even if I pull this out of the router and add directly to app.js I get the same results. I'm simply trying to use Passport's Facebook authentication. The first route looks like this:
router.get('/login/facebook', function(req, res, next) {
passport.authenticate('facebook')(req, res, next);
});
I realize the req function wrapper is not needed, I was using it for debugging so I could see when the route gets called.
If I set a breakpoint there, it works fine if I just type the "/api/login/facebook" URL into my browser, but if I put the exact URL in a link on the page, the route never gets hit.
It turns out this was caused by Angular's routing mechanism intercepting the links. I found the solution here:
How to get Angular UI Router to respect "non-routed" URLs

Appending to url path in express

I am building freeboard using freeboard.io. I am running it on a node server using express. I use
router.get('/', function(req, res, next) {
res.sendFile(path.join(__dirname + '/index.html'));
});
to send the freeboard html file when the base route is hit. However, in order for freeboard to load my saved dashboard I need to append #source=dashboard.json to the url. So the final url would look like
http://localhost:8080/#source=dashboard.json
is there some way I can do this using express? Pretty much when I hit localhost:8080/ I want to append to the url path #source=dashboard.json and respond with the index.html file. Thanks!
The fragment section of the URL is never sent to the server by the browser. See here for more info. Therefore for the server the fragment will always be missing even if the user has entered it on the URL field. In this case redirecting the browser back with the same URL inclusing the fragment may be the wrong thing.

SEO for dynamically generated content in SPA (single page application) using node.js + express.js on server side

My client side code is a single page app (written in knockout.js) with its own routing system so when google crawler bot will try to access links (that have nothing to do with requesting new page from back end BUT just a part of client side routing) it will ask server (node.js + express.js) to serve page (for example 'mywebsite/about') and of course server will return 404 because it unawares of client routing system. Here is my current server code:
router.get('*', function(req, res, next) {
res.sendFile(path.resolve('../dist/index.html'));
});
My idea is to define the same routing structure as in a client and pass routs for client routing system in search parameter:
router.get('/about', function(req, res, next) {
res.sendFile(path.resolve('../dist/index.html?tab=about'));
});
then in client side I can catch it in javascript and pick correct route.
Here off course I have another problem - as I understand google bot doesn't run javascript.. but here I can use prerender.io middleware I guess.
1) Is it a right way to go with single page apps with generated content and SEO?
2) How to pass search parameter from express.js?
If you have query strings that Googlebot can use to recall consistent content then you can indicate this in Webmaster:
https://support.google.com/webmasters/answer/6080548?rd=1
Here's an example set up of mine:
Google wants to only index pages that have consistent content. If content varies for each user - then you want to set a rel="canonical" tag on each page indicating where the 'start' would be for this dynamically generated content.
The idea would be to adapt the Webmaster to your app rather than the other way around. Trying to 'trick' the bot can have dire consequences in SEO because Google does have human checkers that occasionally rate domains. If they find inconsistency between the search indexed URL and what they see in their browser, you'll earn a flag from a lazy operator. Here is the handbook operators follow.
Use prerender.io as first middleware of your pipe:
app.use(require('prerender-node').set('prerenderToken', 'YOUR_TOKEN'));
app.get('*', (req, res) => res.render('index.html'));

Express static serving wrong path

I am messing around with express.js and have built some basic functionality but am having issues with express static serving from the wrong place if the URL is longer than one directory from root. See the examples below.
I am using the normal documented approach to using static.
app.use(express.static(__dirname + '/public'));
And have set up a couple of routes. eg.
app.get('/signup', function(req, res) {
res.render('signup.ejs');
});
With a 404 catch at the end of the chain.
app.get('*', function(req, res){
res.status(404).render('404');
});
If I hit page such as localhost:3000 or localhost:3000/login which are defined routes, all is well. Even if I hit an undefined route of localhost:3000/foo, I get the 404 rendered correctly with all images present.
However if I go one further and do something like localhost:3000/login/foo all the images are missing and I will get an error in the browsers console with the following address.
http://localhost:3000/login/img/site-brand.png
This happens the same on routes defined with more than one directory too.
I interpreted the docs on the express website that regardless of what was calling for the static image it would be served from the public directory in root, which contains a js, img, and css directories.
My questions are, what have I misinterpreted? and how do I get express to always serve relative to root?
I wrote the whole question then realised that when I had set up the src="" tags in my .ejs files I had used relative paths, not absolute. Rather than delete the question I decided to answer it and post it for others.
So instead of using src="img/my-image.png" it should be src="/img/my-image.png" The leading slash indicates that the request is relative to root not the path that is making the request.
Basic web development stuff there. I should have seen it first time out but its late, and I am cramming my head full of new frameworks which is in turn squeezing the more trivial stuff out of my small brain.

Prerender.io not caching pages

I have made an app with AngularJS with an expressJS backend. Now I want to make it crawlable and I've found prerender.io. I think I've done everything correct bur for some reason I don't see any statistics in the prerenderer dashboard.
In my app.configure function I've included the token like follows:
app.use(require('prerender-node').set('prerenderToken', 'my-token'));
And in my HTML I've included the meta-fragment tag:
<meta name="fragment" content="!">
The last ting I've done was to tell AngularJS to use a hashprefix:
$locationProvider.html5Mode(false);
$locationProvider.hashPrefix('!');
But for some reason, if I refer to the documentation, I don't get the correct result. Below you can see what it is supposed to do:
Google sends a request to your server like this:
http://www.example.com/?_escaped_fragment_=/user/123
You turn the url back into this:
http://www.example.com/#!/user/123
For some reason if I try this it still adds the #! signs add the end of the URL, so if I request the URL of my app like google I get this:
http://www.my-website.com/?_escaped_fragment_=#!/home
So it does not replace the hash in the url. I think this is the cause of my problem.
Thanks in advance!
Edit - if I for example add an extra route then it works:
app.get('/', function (req, res) {
res.sendfile('./public/index.html');
});
app.get('/test', function (req, res) {
res.sendfile('./public/index.html');
});
the '/' route doesn't work the '/test' route does work.
Ok I solved my problem. The '/' route was never called because I had an index.html file inside my webpublic folder. I renamed this to public.html and changed the '/' route to get this file instead of the index.html file.
app.get('/', function (req, res) {
res.sendfile('./public/public.html');
});

Resources