I am working on my portfolio and am using handlebars.
I have my main index.js in my root folder. It is working as far as I can tell. My home(index) page loads locally in my browser, but the css and images for it do not load. I also have my views folder, where my layout.hbs and index.hbs is. Then I also have my images/css folders, where I want my index.hbs to find my images/css (which I pass in as parameters in my res.render in my index.js).
However, when I load my home page, I get the errors:
"[Error] Failed to load resource: the server responded with a status of 404 (Not Found) (style.css, line 0)"
&&
"[Error] Failed to load resource: the server responded with a status of 404 (Not Found) (resize_profile_pic.jpg, line 0)"
Here is my index.js:
// === VARIABLES === //
var express = require('express');
var app = express();
var handlebars = require("express-handlebars");
var path = require("path");
var router = express.Router(); //creates a router object, do I even need this???
//===== view ENGINE SET UP =====//
app.set('view engine', 'handlebars');
app.engine(
"hbs",
handlebars({
layoutsDir: path.join(__dirname, "views/layouts"),
partialsDir: path.join(__dirname, "views/partials"),
extname: ".hbs",
defaultLayout: "layout"
})
);
app.set("views", path.join(__dirname, "views"));
app.set("view engine", "hbs");
//NOT sure what this does??? Or if I need it???
app.use("/public", express.static(path.join(__dirname, "public")));
//saw this on a previous post but doesn't seem to work???
app.use(express.static('images'));
// Route to display static src images - also saw this on a previous post???
app.get("/static", (req, res) => {
res.render("static");
});
//===== .GET PAGES =====//
router.get('/', (req, res, next) => { //also tried app.get, do I need router???
res.render('index', {title: 'Home Page', css:['style.css']});
});
app.use('/', router);
app.listen(3000);
Here is how my image is coded in my index.hbs:
<img src="/images/resize_profile_pic.jpg" alt="">
*I also tried "images/resize_profile_pic.jpg" and nada.
Related
I am building a website using Node.js, Express and EJS. For now I have two EJS templates, each corresponding to a page on the website:
the home page URL should be / or /home. The "staff" URL should be /staff. The home one works fine, but for some reason even when I visit the /staff or even a nonsense address (e.g., /eduwshduhwudhwud) I still get the home page. Here is my code that's inside the app.js which is used to build the routes.
Here is my folder structure and code:
var express = require("express");
var app = express();
app.use(express.static("public")); // To allow static files
app.set("view engine", "ejs");
// -------------------------------- HOME PAGE-----------------------------------
app.get("/", function(req, res){
res.render("home");
});
app.get("/home", function(req, res){
res.render("home");
})
// -------------------------------- STAFF PAGE-----------------------------------
app.get("/staff", function(req, res){
res.render("staff");
});
// -------------------------------- HOME PAGE-----------------------------------
// -------------------------------- HOME PAGE-----------------------------------
// -------------------------------- HOME PAGE-----------------------------------
app.listen(process.env.PORT, process.env.IP, function(){
console.log("SERVER IS RUNNING!");
})
Use path.join(__dirname, 'views') to combine the application's directory (i.e., _dirname) to your views directory.
This is how I am doing it in my application:
var express = require('express');
var path = require('path');
...
var app = express();
// view engine setup
app.set('views', path.join(__dirname, 'views')); // <-- add this line before your view engine definition
app.set('view engine', 'ejs');
...
Given this, within my routes I can refer to any view in the views folder with res.render(). For example:
res.render('dashboard', { title: 'My App', greeting: 'Hello' });
app.js
app.engine('.hbs', expressHbs({
defaultLayout: 'layout',
extname: '.hbs',
layoutsDir:'views/layouts',
partialsDir:'views/partials'
}));
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', '.hbs');
app.use(express.static(path.join(__dirname, 'public')));
it work correctly in this route [admin.js]
router.get('/', function(req, res, next){
res.render('admin/admin', {title: 'Admin'});
});
});
//will render http://localhost:3000/admin
however, when i add new route in [admin.js]
router.get('/insert-scene', function(req, res, next){
res.render('admin/insert-scene', {title: 'Insert Scene'});
});
//will render http://localhost:3000/admin/insert-scene
example:
<link href="./stylesheets/site.css" rel="stylesheet">
http://localhost:3000/public/stylesheets/site.css[work][/admin]
http://localhost:3000/admin/stylesheets/site.css[wrong path][/admin/insert-scene]
public folder not work in this route so hbs view just render /admin/.... in my ref source. How to solve this problem?
Do not serve static files with node, while node can handle it, it's not the intended use case of the technology.
Use a specific web server for that like nginx or a CDN.
As my question in Order of router precedence in express.js. I know that the order of express.js is first come first serve. But as code bellows, I don't understand that why the '__dirname' has declared and fixed in above of other code but whaterver I call javascript from ./public/abc.js, the app return a HTML markup of mainpage.
My pages include some javascript and it cannot be loaded. The server return 100% HTML
I am using express generator and folders is structured follows.
NodeJS
var routes = require('./routes/index');
var api = require('./routes/api');
var users = require('./routes/users');
var app = express();
// view engine setup
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'ejs');
// uncomment after placing your favicon in /public
//app.use(favicon(__dirname + '/public/favicon.ico'));
app.use(logger('dev'));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({
extended: false
}));
app.use(cookieParser());
app.use(express.static(path.join(__dirname, 'public')));
app.use('/api', api);
app.use('/users', users);
app.use('/:shopName', function(req, res, next) {
req.shopName = req.params.shopName;
next();
}, routes);
app.use('/', function(req, res) {
res.render('index', {
title: 'MainPage'
});
});
Client Javascript put in script tags like
<script type="text/javascript" src='./public/javascripts/Crypto/crytoUtils.js'></script>
The browser send out error "Uncaught SyntaxError: Unexpected token < cryptoUtils.js " in console and when I click in a link, I see the mainpage HTML markup..
Help me solve the problem ... pls. Thank
The path to the js file should be ./abc.js, public is left out unless you set that as the root for static files using:
app.use('/public', express.static(path.join(__dirname, 'public')));
To be clear, I suggest NOT using the above code, and instead modify your url in the script tag src attribute to appropriately target the file at it's location of /javascripts/Crypto/crytoUtils.js
so I was trying to follow a tutorial to use node.js as the front end of a wordpress site
This one http://www.1001.io/improve-wordpress-with-nodejs/
Here is the code from server.js
var frnt = require('frnt');
var fs = require("fs");
var path = require("path");
var express = require('express');
var app = express();
var doT = require('express-dot');
// Define where the public files are, in this example ./public
app.use(express.static(path.join(__dirname, 'public')));
// Make sure this is set before the frnt middleware, otherwise you won't
// be able to create custom routes.
app.use(app.router);
// Setup the frnt middleware with the link to the internal server
app.use(frnt.init({
proxyUrl: "http://localhost:8888/frnt-example/wordpress", // The link to your wordpress site
layout: false // We simplify this example by not using layouts
}));
// define rendering engine
app.set('views', path.join(__dirname, "views"));
app.set('view engine', 'html' );
app.engine('html', doT.__express );
// respond with "Hello World!" on the homepage
app.get('/', function (req, res) {
res.send('./views/index.html');
});
app.listen(8080); // listen to port 8080
It keeps outputting the following
./views/index.html
Rather than rendering the html?
I've never used frnt, but res.send sends a string so that's no big surprise.
Look at res.sendfile which sends the contents of a file.
I prefer to use ejs , it's sems like html just edit index.html to index.ejs
1- install ejs module npm install ejs
2- add this in app.js
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'ejs');
and render the index.ejs by using
app.get('/', function (req, res) {
res.render('index'); // or res.render('index.ejs');
});
res.send() // it send just a string not file
Hope it usefull !
Hi I'm trying to work with Express 3 using handlebars. But I am unable to "lookup the view" I am stuck with this error.
Error: Failed to lookup view "500" in views directory
"d:\projects\meadowlark\site\views" at EventEmitter.app.render
(d:\projects\meadowlark\site\node_modules\express\lib\application.js:519:17)
at ServerResponse.res.render
(d:\projects\meadowlark\site\node_modules\express\lib\response.js:904:7)
at d:\projects\meadowlark\site\meadowlark.js:29:7 at
Layer.handle_error
(d:\projects\meadowlark\site\node_modules\express\lib\router\layer.js:58:5)
at trim_prefix
(d:\projects\meadowlark\site\node_modules\express\lib\router\index.js:269:13)
at
d:\projects\meadowlark\site\node_modules\express\lib\router\index.js:238:9
at Function.proto.process_params
(d:\projects\meadowlark\site\node_modules\express\lib\router\index.js:313:12)
at
d:\projects\meadowlark\site\node_modules\express\lib\router\index.js:229:12
at Function.match_layer
(d:\projects\meadowlark\site\node_modules\express\lib\router\index.js:296:3)
at next
(d:\projects\meadowlark\site\node_modules\express\lib\router\index.js:190:10)
Its really strange for me. Can anyone explain this issue to me how can I solve it?
My js code is as follows:
var express = require('express');
var app = express();
// set up handlebars view engine
var handlebars = require('express3-handlebars')
.create({ defaultLayout:'main' });
app.engine('handlebars', handlebars.engine);
app.set('view engine', 'handlebars');
app.set('port',process.env.port || 3000);
app.get('/', function(req, res) {
res.render('home');
});
app.get('/about', function(req, res) {
res.render('about');
});
// 404 catch-all handler (middleware)
app.use(function(req, res, next){
res.status(404);
res.render('404');
});
// 500 error handler (middleware)
app.use(function(err, req, res, next){
console.error(err.stack);
res.status(500);
res.render('500');
});
app.listen(app.get('port'),function(){
console.log('Express started on http://localhost: '+ app.get('port') + " Press CTRL+C to terminate.");
});
I think I know what the issue here is, remember this setup of app.js from an O'Reilly book ("Web Development with Node & Express").
Here's what the author fails to clarify:
If you have your .handlebars template files in views/layouts/, structure your view engine setup like this:
var path = require('path');
var express = require('express');
var handlebars = require('express-handlebars'); // 'express3-handlebars' has been deprecated
var app = express();
// Set up handlebars view engine
app.set('views', path.join(__dirname, 'views/layouts/'));
app.engine('handlebars', handlebars({defaultLayout: 'main'}));
app.set('view engine', 'handlebars');
Note that you will need the var path = require('path'); in order to set 'views' to the filepath views/layouts/.
If you read the error, it clearly tells you that you are missing a 500 view template in your template directory. I'm not sure what your directory structure you have, but place a 500.handlebars file in the same directory the 404.handlebars file is. Should be somewhere in the views/ or views/layouts directory.
Make sure that your files: home.handlebars, about.handlebars, 404.handlebars, 500.handlebars and main.handlebars don't have hidden extensions. Like this: home.handlebars.html, about.handlebars.html, 404.handlebars.html, 500.handlebars.html, and main.handlebars.html.
If they do, removing those extensions and using only the .handlebars extension should resolve the issue.