I have some plain HTML/CSS files in my frontend folder and the ejs files in the views folder and every other ejs file loads perfectly but the index.ejs file
I don't know what I am doing wrong here
This is my server.js: (this is a basic version of my server file)
const app = express();
app.set('views', __dirname + '/views');
app.set("view engine", "ejs");
app.use(express.static(__dirname + "/frontend"));
app.get("/", (req, res) => {
res.render("index");
});
//The below file loads perfectly. (requireAuth is a authentication middleware)
app.get("/create", requireAuth, (req, res) => {
res.render("create");
});
Also both the files index.ejs and create.ejs are very similar
If anyone requires any extra details then they can comment down.
You've defined static middleware for / (root path) and the index page is also defined for root path, but because static middleware is defined early, express tries to find and return static file instead of rendering index page.
You have two variants here:
Define static middleware for some path different than root:
app.use("/public", express.static(__dirname + "/frontend"));
Don't use root path for index page: app.get("/index", (req, res)...
Related
I am working on my portfolio project. I am using handlebars and nodeJS.
I have a section called projects where I list 4 different projects to showcase. I have an index.js where all my routing is done. Projects 1,3,4 work just fine. These all will be clicked on from a project section on my index page.
However, I am so lost on how to route my project 2. Projects 1,3,4 are all handlebars(.hbs). But my project 2 is an html page. As seen in my code snippet, the html is store under the same /public folder as all my other code. However, I still get the error "Failed to lookup view "../public/views/fountainWebsite/html/home" in views directory". I am not sure how this needs to be done??
// === 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
//===== view ENGINE SET UP =====//
app.set('view engine', 'handlebars');
app.engine(
"hbs",
handlebars({
layoutsDir: path.join(__dirname, "/public/views/layouts"),
partialsDir: path.join(__dirname, "/public/views/partials"),
extname: ".hbs", //expected file extension for handlebars files
defaultLayout: "layout" //default layout for app, general template for all pages in app
})
);
app.set("views", path.join(__dirname, "views"));
//thought this would maybe fix the error?? It didn't//
// app.set("fountainWebsite", path.join(__dirname, "fountainWebsite")); //
app.set("view engine", "hbs");
app.use("/public", express.static(path.join(__dirname, "public")));
//===== .GET PAGES =====//
app.get('/', (req, res, next) => {
res.render('../public/views/index', {title: 'Home Page', css:['../public/css/style.css'], js:['../public/js/navBar.js']});
});
app.use('/', router);
router.get('/project1', (req, res, next) => {
res.render('../public/views/partials/project1', {title: 'Data Structures', css:['../public/css/projects.css'], js:['../public/js/navBar.js']});
});
//error here//
router.get('/project2', (req, res, next) => {
res.render('../public/views/fountainWebsite/html/home');
});
router.get('/project3', (req, res, next) => {
res.render('../public/views/partials/project3', {title: 'This Portfolio', css:['../public/css/projects.css'], js:['../public/js/navBar.js']});
});
router.get('/project4', (req, res, next) => {
res.render('../public/views/partials/project4', {title: 'Dictionary', css:['../public/css/projects.css'], js:['../public/js/navBar.js']});
});
It is important that we understand what our code is doing. Let's start with the route handler for /project2:
router.get('/project2', (req, res, next) => {
res.render('../public/views/fountainWebsite/html/home');
});
This is telling Express to listen for a request with the path /project2 and to render the file at ../public/views/fountainWebsite/html/home.
Handlebars requires an extension (like .hbs) in order to know which view engines to use to render the file. As we have omitted an extension from our file path, Express will assume the extension is .hbs because that's what we told it to do when we called app.set("view engine", "hbs");
I have to assume that your file path with extension is ../public/views/fountainWebsite/html/home.html since you have put it in a folder called "html". If this is the case, Handlebars is not going to find this file because it is looking for ../public/views/fountainWebsite/html/home.hbs and it will throw an Error.
The simple solution would be to rename this file with a .hbs extension. This will at least allow Express to locate the file and render it through the Handlebars view engine.
However, one problem with this approach may be that this view gets rendered wrapped in your layout.hbs file and you do not want that. Perhaps you want this HTML file to be unprocessed and served as a static asset.
In this case, you could remove the /project2 route handler and let Express serve this file as a static asset. Since you have already registered your public/ folder as static assets folder with the call app.use("/public", express.static(path.join(__dirname, "public"))); and your file path shows that this HTML file is already within the public/ folder, you should be able to request this HTML directly from your browser at the path /public/views/fountainWebsite/html/home.html.
im trying to serve up static files using express and pug as the templating engine but somehow my assets are not being loaded
my files path :
+front
+views
+login
index.pug
+images
+js
+css
...
server.js
here is my server code :
app.use(express.static('front'));
app.set('views', './front/views')
app.set('view engine', 'pug')
router.get('/login', (req, res) => {
res.render('./Login_v1/login', { title: 'Login', message: 'Login'})
})
pug code :
link(rel='icon' type='image/png' href='/images/icons/favicon.ico')
step first add path to your static folder in app.js/server.js(your entry file of express)
app.use(express.static(__dirname + 'images/icons')); // path of your image folder
than you can access it by
href='localhost:serverPort/favicon.ico
I have a mean-stack application. By going to https://localhost:3000/#/home, it reads views/index.ejs. Here is the setting in app.js:
var app = express();
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'ejs');
app.use(express.static(path.join(__dirname, 'public')));
app.all('/*', function(req, res, next) {
res.sendFile('index.ejs', { root: __dirname });
});
Actually, I don't use the feature of ejs in index.ejs. So now I want to use just a index.html rather than index.ejs.
I put the content of index.ejs in public/htmls/index.html and views/index.html. And here is the current setting in app.js:
var app = express();
// app.set('views', path.join(__dirname, 'views'));
// app.set('view engine', 'ejs');
app.use(express.static(path.join(__dirname, 'public')));
app.all('/*', function(req, res, next) {
res.sendFile('index.html', { root: __dirname });
// res.sendFile('index.html'); // does not work either
});
However, running https://localhost:3000/#/home returns
Error: No default engine was specified and no extension was provided.
Does anyone know how to fix it?
Edit 1: by following the answer of user818510, I tried res.sendFile('index.html', { root: path.join(__dirname, 'views') }); in app.js, it still can NOT find index.html.
Whereas, in routes/index.js, the following can find index.html, but it gives a warning express deprecated res.sendfile: Use res.sendFile instead routes/index.js:460:9.
var express = require('express');
var router = express.Router();
var path = require('path');
... ...
router.get('*', function(req, res) {
res.sendfile('./views/index.html'); // works, but a deprecation warning
// res.sendFile('index.html', { root: path.join(__dirname, 'views') }); does not work
});
It is really confusing...
If it's a single page mean application, then you only need to start express with static and put index.html in static/ dir :
Project layout
static/
index.html
server.js
server.js
'use strict';
var express = require('express');
var app = express();
app.use(express.static('public'));
var server = app.listen(8888, function () {
console.log("Server started. Listening on port %s", server.address().port);
});
Now you can call http://localhost:8888/#home
It looks like a problem with the path. Your index.html is located at public/htmls/index.html and views/index.html. Your root option in res.sendFile should be __dirname+/public/htmls/ or __dirname+/views
In your code, you are using the path:
res.sendFile('index.html', { root: __dirname });
Your app.js would be in the project root where you have public directory alongside at the same level. Based on your rootoption in res.sendFile, you would have to place index.html at the same level as your app.js.
You should change the root path in res.sendFile. Use:
res.sendFile('index.html', { root: path.join(__dirname, 'public', 'htmls') });
OR
res.sendFile('index.html', { root: path.join(__dirname, 'views') });
The above root is based on the path that you've mentioned in your question.
Here's the link to the docs:
http://expressjs.com/en/api.html#res.sendFile
Your no default engine error is probably because you have commented the line where you set the view engine to ejs but still have existing ejs views. Uncommenting that line with the root path change should solve your issue.
Do not serve static content from an application server.
Use a web server for that, and in production, a content delivery network like Akamai.
A content delivery network will charge you per bandwidth (e.g: 10 cents per Terabyte). Serving the equivalent of 10 cents in Akamai can cost you thousands of dollars using cloud instances.
In addition to that, your servers will have unnecessary load.
If you absolutely have to serve static content from your application servers, then put a reverse proxy cache like nginx, varnish or squid in front of your server. But that will still be very cost inefficient. This is documented in the express website.
This is common practice in every Internet company.
Is it possible to serve static content and views from the same directory?
I found a partial solution below:
//Enable Express static content serving:
app.use(express.static(__dirname + '/html')); //Static path is folder called html
//Also enable EJS template engine:
app.engine('.html', require('ejs').__express);
app.set('views', __dirname + '/html'); //Set views path to that same html folder
app.set('view engine', 'html'); //Instead of .ejs, look for .html extension
//Start server
app.listen(8000);
//Express routes:
app.get('/', function(req,res) {
res.render('index', { message: 'hello world'});
//this only serves static index.html :(
});
app.get('/home', function(req,res) {
res.render('index', { message: 'hello world'}); //<-- this serves EJS
//whoo-hoo! serves index.html with rendered EJS 'hello world' message
});
This is working perfectly, except for the first route '/' which does not render EJS. All other routes (/home, /about, etc) will conveniently serve the dynamic EJS along with static content. Is there anyway to trick that first '/' to work in the same way?
For Express 3.x try putting router before static:
app.use(app.router);
app.use(express.static(path.join(__dirname, 'html')));
For Express 4.x the router has been deprecated but the concept is the same as routes are like middleware so you should be able to call them before the static middleware.
Note: my auto answer at end of the post
I'm trying to make a better experience of nodeJS and i don't really like to get all the script in one file.
so, following a post here i use this structure
./
config/
enviroment.js
routes.js
public/
css/
styles.css
images
views
index
index.jade
section
index.jade
layout.jade
app.js
My files are right now:
app.js
var express = require('express');
var app = module.exports = express.createServer();
require('./config/enviroment.js')(app, express);
require('./config/routes.js')(app);
app.listen(3000);
enviroment.js
module.exports = function(app, express) {
app.configure(function() {
app.use(express.logger());
app.use(express.static(__dirname + '/public'));
app.set('views', __dirname + '/views');
app.set('view engine', 'jade'); //extension of views
});
//development configuration
app.configure('development', function() {
app.use(express.errorHandler({
dumpExceptions: true,
showStack: true
}));
});
//production configuration
app.configure('production', function() {
app.use(express.errorHandler());
});
};
routes.js
module.exports = function(app) {
app.get(['/','/index', '/inicio'], function(req, res) {
res.render('index/index');
});
app.get('/test', function(req, res) {
//res.render('index/index');
});
};
layout.jade
!!! 5
html
head
link(rel='stylesheet', href='/css/style.css')
title Express + Jade
body
#main
h1 Content goes here
#container!= body
index/index.jade
h1 algoa
The error i get is:
Error: Failed to lookup view "index/index"
at Function.render (c:\xampp\htdocs\nodejs\buses\node_modules\express\lib\application.js:495:17)
at render (c:\xampp\htdocs\nodejs\buses\node_modules\express\lib\response.js:614:9)
at ServerResponse.render (c:\xampp\htdocs\nodejs\buses\node_modules\express\lib\response.js:638:5)
at c:\xampp\htdocs\nodejs\buses\config\routes.js:4:7
at callbacks (c:\xampp\htdocs\nodejs\buses\node_modules\express\lib\router\index.js:177:11)
at param (c:\xampp\htdocs\nodejs\buses\node_modules\express\lib\router\index.js:151:11)
at pass (c:\xampp\htdocs\nodejs\buses\node_modules\express\lib\router\index.js:158:5)
at Router._dispatch (c:\xampp\htdocs\nodejs\buses\node_modules\express\lib\router\index.js:185:4)
at Object.router [as handle] (c:\xampp\htdocs\nodejs\buses\node_modules\express\lib\router\index.js:45:10)
at next (c:\xampp\htdocs\nodejs\buses\node_modules\express\node_modules\connect\lib\proto.js:191:15)
But i don't really know what is the problem...
I'm starting thinking is because the modules exports...
Answer:
Far away the unique solution i found is to change the place i defined app.set('views') and views engine
I moved it to the app.js and now is working well.
var express = require('express');
var app = module.exports = express.createServer();
require('./config/enviroment.js')(app, express);
app.set('views', __dirname + '/views');
app.set('view engine', 'jade');
require('./config/routes.js')(app);
app.listen(3000);
I don't really understand the logic behind this but i gonna supose it have one.
Adding to #mihai's answer:
If you are in Windows, then just concatenating __dirname' + '../public' will result in wrong directory name (For example: c:\dev\app\module../public).
Instead use path, which will work irrespective of the OS:
var path = require ('path');
app.use(express.static(path.join(__dirname + '../public')));
path.join will normalize the path separator character and will return correct path value.
npm install express#2.5.9 installs the previous version, if it helps.
I know in 3.x the view layout mechanic was removed, but this might not be your problem. Also replace express.createServer() with express()
Update:
It's your __dirname from environment.js
It should be:
app.use(express.static(__dirname + '../public'));
It is solved by adding the following code in app.js file
app.engine('html', require('ejs').renderFile);
app.set('view engine', 'html');
app.set('views', __dirname);
app.get('/', function(req, res){
res.render("index");
});
I had the same error at first and i was really annoyed.
you just need to have ./ before the path to the template
res.render('./index/index');
Hope it works, worked for me.
You could set the path to a constant like this and set it using express.
const viewsPath = path.join(__dirname, '../views')
app.set('view engine','hbs')
app.set('views', viewsPath)
app.get('/', function(req, res){
res.render("index");
});
This worked for me
Check if you have used a proper view engine.
In my case I updated the npm and end up in changing the engine to 'hjs'(I was trying to uninstall jade to use pug).
So changing it to jade from hjs in app.js file worked for me.
app.set('view engine','jade');
In my case, I solved it with the following:
app.set('views', `${__dirname}/views`);
app.use(express.static(`${__dirname}/public`));
I needed to start node app.min.js from /dist folder.
My folder structure was:
This problem is basically seen because of case sensitive file name.
for example if you save file as index.jadge than its mane on route it should be "index" not "Index" in windows this is okay but in linux like server this will create issue.
1) if file name is index.jadge
app.get('/', function(req, res){
res.render("index");
});
2) if file name is Index.jadge
app.get('/', function(req, res){
res.render("Index");
});
use this code to solve the issue
app.get('/', function(req, res){
res.render("index");
});
Just noticed that I had named my file ' index.html' instead for 'index.html' with a leading space. That was why it could not find it.
This error really just has to do with the file Path,thats all you have to check,for me my parent folder was "Layouts" but my actual file was layout.html,my path had layouts on both,once i corrected that error was gone.
i had the same problem but, i change the name of the file from index.html to index.ejs and works!!!!
const express = require('express');
const router = express.Router();
router.get('/', (req, res) => {
res.render('index');
});
router.get('/contact', (req, res) => {
res.render('contact', { title: 'Contact Page' });
});
module.exports = router;
and index.js
const express = require('express');
const morgan = require('morgan');
const path = require('path');
const app = express();
//settings
app.set('port', 4000);
app.set('views', path.join(__dirname,'views'));
app.set('view engine', 'ejs');
//middlewares
//routes
app.use(require('./routes'));
//static files
//listening
app.listen(app.get('port'), () => {
console.log('Server is running at http://localhost:'+app.get('port')+'/');
});
update:
add this in index:
app.engine('html', require('ejs').renderFile);
I change the views folder name to views_render and also facing the same issue as above, so restart server.js and it works for me.
I had the same issue and could fix it with the solution from dougwilson: from Apr 5, 2017, Github.
I changed the filename from index.js to index.pug
Then used in the '/' route: res.render('index.pug') - instead of res.render('index')
Set environment variable: DEBUG=express:view
Now it works like a charm.
I had this issue as well on Linux
I had the following
res.render('./views/index')
I changed it too
res.render('../views/index')
Everything is now working.
I had the same issue. Then just check the file directory in your explorer. Sometimes views folder isn't present.
In my case, I was deploying my web app on a Windows Server and I had a service set up to run a .bat file with only one line as content:
node D:\webapp\app.js
But this was not enough. I also had to change the directory before that, so I added the following line at the beginning of the .bat file:
cd D:\webapp
app.get("/", (req, res) => {
res.render("home");
});
// the code below brought the error
app.get("/", (req, res) => {
res.render("/");
})
I was facing this error because i mistakenly deleted my error.ejs file and it was being called in app.js file and was not found in views as it was already deleted by me