I'm trying to use html5 mode in Angular JS app for sake of SEO. However, I faced the problem for Express serving index.html to request. The deep linking didn't work and cannot refresh page.
App.js
app.use(serveStatic(path.join(__dirname, 'public')));
app.use(serveStatic(path.join(__dirname, 'node_modules')));
app.use(serveStatic(path.join(__dirname, 'app_client')));
app.use('/api', routesApi);
app.all('/*', function(req, res, next) {
res.sendFile('./app_client/index.html', { root: __dirname });
console.log("send index");
});
I already try many researches from many sources, approach such as
app.get('/', function(req, res) {
res.sendFile('index.html');
});
or
router.get('/', function(req, res) {
res.sendFile(path.join(__dirname, 'app_client', 'index.html'));
});
or
app.get('/*', function(req, res) {
res.sendFile(__dirname + '/index.html')
});
None seems to work. I know that something must be wrong in my code, but i don't know where.
Found answer at lasts
app.get('/*', function(req, res, next) {
res.sendFile(__dirname + '/app_client/index.html');
}
Related
I don't know why the data is not returning in production mode and I just get index.html
app.use("/api/auth", authRoute);
app.use("/api/users", userRoute);
app.use("/api/movies", movieRoute);
app.use("/api/lists", listRoute);
app.use("/api/check-existance", verify);
app.use("/api/matches", matchRoute);
app.use("/api/categories", categoryRoutes);
app.use("/api/subCategories", subCategoryRoutes);
app.use("/api/competetions", competetionRoutes);
app.use("/api/stream", videos);
if (process.env.NODE_ENV === "production") {
app.use(express.static(path.join(__dirname, "../client/build")));
app.get("/*", (req, res) => {
res.sendFile(path.join(__dirname, "../client", "build", "index.html"));
});
} else {
app.get("/", (req, res) => res.send("Please set to production"));
}
you are returning the index.html for every get request and there is no data in this code.
app.get("/*", (req, res) => {
res.sendFile(path.join(__dirname, "../client", "build", "index.html"));
});
The Problem was that my client routes are differed from api routes, So when I corrected the routes in client code the data retrieve without any problem
Okay so this question originates from this post, which is also my question but sorta moved onto this problem.
Now the problem is, my angular app works but when it comes to Node routes, like /login, the browser thinks it's an Angular route. The browser does detect it as a Node route when I refresh the whole page but not when I am navigating the site once Angular routing has kicked in.
Long story short, here are my route files:
require('./routes/routes.js')(express, app);
require('./routes/default.js')(express, app);
routes.js file:
module.exports = function(express, app){
var router = express.Router();
router.get('/', function(req, res){
res.render('index');
});
router.get('/login', function(req, res){
if (req.isAuthenticated()){
res.render('index');
} else {
res.render('login');
}
});
default.js:
module.exports = function(express, app, passport, Promise){
var defaultRouter = express.Router();
defaultRouter.get('/*', function(req, res, next) {
res.render('./views/index.html');
});
};
Your help will be very much appreciated.
Thanks
I gave up on making this work on the root URL so I added /index to the baseURL like this:
index.html file:
<head>
<base href="/index/">
</head>
The, I added a catch all to the routes.js file, as below:
module.exports = function(express, app){
var router = express.Router();
router.get('*', function(req, res, next) {
if(req.url == '/' || req.url == '/login'){
next();
} else {
res.sendfile('./views/index.html');
}
});
router.get('/', function(req, res){
res.render('index');
});
router.get('/login', function(req, res){
if (req.isAuthenticated()){
res.render('index');
} else {
res.render('login');
}
});
With the angular file of course having this:
$locationProvider.html5Mode({
enabled: true,
requireBase: true
}).hashPrefix('');
And there. It works like a charm now.
I hope this helps whoever are in my shoes.
I am building a MEAN stack app, following this tutorial: https://www.youtube.com/watch?v=PFP0oXNNveg&t=3236s
The Problem: I try to do http.get() request from my angular2 frontend to my express backend. It does not work and i get the Error: ERR_CONNECTION_REFUSED:
The Error
My frontend is on localhost/4200 and my backend on localhost/3000. I figured the problem might be that, so i search for solutions and tried everything described in here: Angular-CLI proxy to backend doesn't work (solution to proxy the localhost port), which does not work for me. I still get the error.
here is my code :
Service method with API call
getUsers() {
return this.http.get('http://localhost/3000/api/users')
.map(res => res.json());
}
server.js
var express = require('express');
var path = require('path');
var bodyParser = require('body-parser');
var start = require('./routes/start');
var registration = require('./routes/registration');
var port = 3000;
var app = express();
//View Engine
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'ejs');
app.engine('html', require('ejs').renderFile);
//Set Static Folder
app.use(express.static(path.join(__dirname, 'client')));
app.use(express.static(path.join(__dirname, 'client', 'dist')));
//Body Parser MW
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({extended: false}));
app.use('/', start);
app.use('/api', registration);
app.listen(port, () =>{
console.log('Server started on port '+port);
});
The route i try to use with my API call
//get all the user
router.get('/users', function(req, res, next){
db.users.find(function(err, usrs){
if(err){
res.send(err);
}
res.json(usrs);
});
});
//get single user
router.get('/user/:id', function(req, res, next) {
db.users.findOne({_id: mongojs.ObjectId(req.params.id)}, function(err, usr){
if(err){
res.send(err);
}
res.json(usr);
});
});
//save a new user
router.post('/user', function(req, res, next) {
var user = req.body;
if(!user.name || !user.password){
res.status(400);
res.json({
"error": "Bad Data"
});
} else {
db.users.save(user, function(err, user) {
if(err){
res.send(err);
}
res.json(user);
});
}
});
module.exports = router;
I'm guessing because you're trying to go to 'http://localhost/3000/api/users' which has a / after localhost instead of a :, so you're going to localhost on port 80, which is the default. Switch it to 'http://localhost:3000/api/users', does that help?
I have a website which has a front-end and back-end.
I have stored my front-end files in client folder, and back-end files in admin folder. I have removed # tag from front-end URL by adding
$locationProvider.html5Mode(true);
in my client app.js file and
<base href="/">
added in client index.html file
Same thing I added in admin folder file also in index.html I added
<base href="/admin">
but still, it's not working.
Here is my server.js file
var express = require('express');
var bodyParser = require('body-parser');
var app = express();
var path = require('path');
var session = require('express-session');
var mongoose = require('mongoose');
mongoose.connect('mongodb://localhost/edb');
app.all('/', function(req, res, next) {
res.header("Access-Control-Allow-Origin", "*");
res.header("Access-Control-Allow-Headers", "X-Requested-With");
next()
});
app.use(session({secret: 'keyboard cat', cookie: { maxAge: 60000 }, resave: true, saveUninitialized: true }))
app.use('/', express.static('app', { redirect: false }));
app.get('/', function (req, res, next) {
res.sendFile(path.resolve('client/index.html'));
});
I have tried adding this to the server.js file
app.get('/admin', function (req, res, next) {
res.sendFile(path.resolve('admin/index.html'));
});
but it's taking to client index.html file.
Do you have a solution?
I got a solution
app.get('/*', function (req, res, next) {
res.sendFile(path.resolve('client/index.html'));
});
app.get('/admin/*', function (req, res, next) {
res.sendFile(path.resolve('admin/index.html'));
});
I added this code in server.js file
its work like a charm
Is it possible to tell a request to my Node App req in:
app.get('/*', function(req, res) {
res.sendFile(__dirname + '/site/index.html')
});
From which block of my Angular routes it is from (i.e. I want to be able to identify whats from the otherwise block);
.when('/user',
{...}
)
.when('/login',
{...}
)
.otherwise(
{...}
)
The reason I want it because I want to do something like:
app.get('/*', function(req, res) {
if (req is from otherwise block) {
res.status(400).sendFile(__dirname + '/site/index.html')
} else {
res.sendFile(__dirname + '/site/index.html')
}
});
The only thing i can otherwise think of is to create an array of all the allowed routes but I don't like duplication :p
Since the only link between Angular and Node is the HTTP request it's making, all you can do is retrieve the url and analyze which route it came from.
I'd define the routes you know about in Node, and then have a fallback for 404 errors:
app.get(['/login', '/user'], function(req, res) {
res.sendFile(__dirname + '/site/index.html')
});
app.get('*', function(req, res) {
res.status(404).sendFile(__dirname + '/site/404.html')
});