This is not a question about express.static()
I have a application where I need to serve multiple pages which have same js and css dependencies. Hence, writing css and js includes using <script> or <link> tags on every single page is bad practice.
I am looking for a look alike php include way to do it. As php would process all php code and send compiled html, I think same could be done with js on node server.
So a server would do kinda like below:
get html from a resources.html
push above html to index.html
send index.html
Or perhaps there could be other way around. Any idea?
You can use layouts with your chosen template engine and each view can extend that layout. For example, if you're using Jade as your template engine.
index.js
var express = require("express");
var app = express();
var port = process.env.PORT || 7080;
app.set('view engine', 'jade');
app.get('/', function (req, res) {
res.render('home');
});
app.listen(3000);
views/layout.jade
doctype html
html
head
script(src='/javascripts/home.js')
link(rel='stylesheet', href='/stylesheets/style.css')
block title
title= "My Website"
body
.container
block content
views/home.jade
extends ./layout.jade
block content
h1 Hello World!
The home.jade view extends the layout and overrides the content block. Visiting http://localhost:3000/ returns the following:
<!DOCTYPE html>
<html>
<head>
<script src="/javascripts/home.js"></script>
<link rel="stylesheet" href="/stylesheets/style.css">
<title>My Website</title>
</head>
<body>
<div class="container"><h1>Hello World!</h1></div>
</body>
</html>
Make a public folder in your root directory
then in main app.js/server.js
add the following line :-
`var express = require('express'),
bodyParser = require('body-parser'),
userRoutes = require('./routes/user'),
mongoose = require('mongoose');
var app = express();
mongoose.connect('mongodb://localhost/meanDemo');
app.use( bodyParser.json() ); // to support JSON-encoded bodies
app.use(bodyParser.urlencoded({ // to support URL-encoded bodies
extended: true
}));
app.use(express.static('public'));
app.engine('html', require('ejs').renderFile);
app.set('view engine', 'html');
app.use('/', userRoutes);
app.get('/',function(req, res){
res.render('userlist');
});
app.listen(3000);
console.log("sever started at 3000");
`
Then in views use /*filename to / will be your public directory
Related
I created super simple express app which will display one home.html view from view directory. Everything is ok home.html is displayed but there is no any css styles that i added. In the console i get only one error:
I tried to solve my problem with another answers from stack that I found like:
change app.use()
from -> app.use(express.static(path.join(__dirname, 'public')))
to -> app.use(express.static(path.join(__dirname + '/public')))
Okay here you can see how my directory structure looks like
As you can see I created public folder and inside of this folder i keep my css styles, so under the url: http://localhost:8080/public/css/style.css I should see my css styles but I can see only error
But in the same time under this url http://localhost:8080/css/style.css I can find my css file
I am really confused and I do not know what I am doing wrong. I will be very glad If any of you help me.
app.js
const express = require('express');
const path = require('path');
const bodyParser = require('body-parser');
const cookieParser = require('cookie-parser');
const flash = require('connect-flash');
const routes = require('./routes/index');
const app = express();
app.set('views', path.join(__dirname, 'views'));
app.engine('html', require('ejs').renderFile);
app.set('view engine', 'html');
app.use(express.static(path.join(__dirname, 'public')));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: true }));
app.use(cookieParser());
app.use(flash());
app.use('/', routes);
module.exports = app;
server.js
const app = require('./app');
app.set('port', process.env.PORT || 8080);
const server = app.listen(app.get('port'), () => {
console.log(`Server is up on ${server.address().port}`);
});
home.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<link rel="stylesheet" type="text/css" href="/public/css/style.css">
<title>Express</title>
</head>
<body>
<h1>Express</h1>
</body>
</html>
style.css
body {
background: #f6f6f6;
}
h1 {
color: green;
}
Ok so I made mistake with express server configuration. Instead of serving static file like
app.use(express.static(path.join(__dirname, 'public')));
app.use('/public', express.static(path.join(__dirname, 'public')));
This happened because /public directory was served under root url
I am working on building my views for a project, and I am running into so trouble getting images to render on my .ejs pages. When the page loads, there is just a little page icon next to the alt text I set in the ejs file. I'm also getting a "GET /public/images/ResConnect.png 404" error in the console. I've tried some solutions online, but nothing seems to work. Here is the code for the specific page I'm trying to get a logo to render on:
<!-- views/index.ejs -->
<!doctype html>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<html>
<head>
<title>ResConnect Home</title>
<link rel="stylesheet" href="//netdna.bootstrapcdn.com/bootstrap/3.0.2/css/bootstrap.min.css"> <!-- load bootstrap css -->
<script defer src="https://use.fontawesome.com/releases/v5.0.8/js/solid.js" integrity="sha384-+Ga2s7YBbhOD6nie0DzrZpJes+b2K1xkpKxTFFcx59QmVPaSA8c7pycsNaFwUK6l" crossorigin="anonymous"></script> <!-- load fontawesome -->
<script defer src="https://use.fontawesome.com/releases/v5.0.8/js/fontawesome.js" integrity="sha384-7ox8Q2yzO/uWircfojVuCQOZl+ZZBg2D2J5nkpLqzH1HY0C1dHlTKIbpRz/LG23c" crossorigin="anonymous"></script>
<style>
body { padding-top:80px; }
</style>
</head>
<body>
<div class="container">
<div class="jumbotron text-center">
<img src="./public/images/ResConnect.png" alt="ResConnect Logo"/>
<h1><span class="fa fa-lock"></span> ResConnect Home</h1>
<p>Please advise: Only approved personnel by The University of Mississippi Department of Student Housing may access ResConnect.</p>
<b>Login or Register with:</b><br>
<span class="fa fa-user"></span> Login
<span class="fa fa-user-plus"></span> Register
</div>
</div>
</body>
</html>
And here's my server.js file:
// server.js
// get all the tools we need
var express = require('express');
var session = require('express-session');
var favicon = require('express-favicon');
var cookieParser = require('cookie-parser');
var bodyParser = require('body-parser');
var morgan = require('morgan');
var app = express();
var port = process.env.PORT || 1848;
var passport = require('passport');
var flash = require('connect-flash');
require('./config/passport')(passport); // pass passport for configuration
app.use(favicon(__dirname + './public/images/favicon.ico'));
app.use(express.static('./public/images'));
// set up our express application
app.use(morgan('dev')); // log every request to the console
app.use(cookieParser()); // read cookies (needed for auth)
app.use(bodyParser.urlencoded({
extended: true
}));
app.use(bodyParser.json());
app.set('view engine', 'ejs'); // set up ejs for templating
// required for passport
app.use(session({
secret: 'vidyapathaisalwaysrunning',
resave: true,
saveUninitialized: true
} )); // session secret
app.use(passport.initialize());
app.use(passport.session()); // persistent login sessions
app.use(flash()); // use connect-flash for flash messages stored in session
require('./app/routes.js')(app, passport);
app.listen(port);
console.log('Server running on port ' + port);
And here is my get function for the index.ejs page I'm rendering:
app.get('/', function(req, res) {
res.render('index.ejs'); // load the index.ejs file
});
Additionally, here is my directory setup for the project, so that you can see where all of my files are:
Project file directory
Change
app.use(express.static('./public/images'));
to be
app.use('/public/images/', express.static('./public/images'));
You need express to serve files from the filesystem at ./public/images, but you need to serve those files from the uri under /public/images (instead of just '/')
For example in http://expressjs.com/en/starter/static-files.html note how the static middleware serves from 'public' but the uris in the sample do not include 'public'.
Adding a path as the argument to any .use mounts the middleware under the given path.
--- EDIT to support favicon.ico not served underneath /public/images
You can alternatively update the directory structure you are using;
app.use(express.static('/path/to/content'));
where /path/to/content contains
/
|-> favicon.ico
|-> public/
|-> images/
|-> x.png
|-> y.png
So keep in mind express.static serves whatever is inside the path you pass it, at the route it is mounted at (by default '/'). The path it reads from has no bearing on the uris, but the directory structure inside does
I'm using back4app BaaS service that uses Parse-Server. For the ClientSide I'm running AngularJS with html5Mode(true);
My problem is that this is NOT working: http://app.rizop.tv/dashboard
While this is working right: http://app.rizop.tv
Any idea how to fix expressJS to handle my routes in the right way?
I have this config:
cloud\app.js
// Helper modules that will be used
var path = require('path');
var bodyParser = require('body-parser')
// This imports the Router that uses the template engine
var index = require('./routers/index');
// Sets the template engine as EJS
app.set('view engine', 'ejs');
// This defines that the 'views' folder contains the templates
app.set('views', path.join(__dirname, '/views'));
// These options are necessary to
app.use(bodyParser.urlencoded({ extended: false }))
app.use(bodyParser.json())
// This bind the Router to the / route
app.use('/', index)
// Starts listening in the routes
app.listen();
cloud\routers\index.js
// Importing express
var express = require('express');
// Creating a Router
var route = express.Router();
// Defining a route that binds the GET method
route.get('/', function(req, res) {
// This is the code that renders the template
res.render('index', {testParam: 'Back4Apper'});
});
module.exports = route;
cloud\views\index.ejs
<!doctype html>
<html>
<head>
<meta charset="utf-8">
...
</body>
...
</body>
</html>
Here is my app structure:
You can make it work by making little changes in app.js and root html file
I assume you already defined $locationProvider.html5Mode(true); where you defined your routes. Then define base href in your index html
<head>
<base href="/">
...
</head>
This answer might be helpful to configure your server
The file at cloud/app.js should not have app.listen() on its final line, due to the fact that you are using Cloud Code. Can you please try that?
I have ran into the same problem and did the following
I've put this route as the last option, so when the express router ran out of options it will render the index file where is the angular app. Angular internal router will resolve that route and draw the view.
router.get('*', function (req, res) {
res.render('index', {testParam: 'Back4Apper'});
});
Obviously you can write a smarter regex instead of * according to your needs but you get the idea.
I'm taking a course (on MEAN) and it starts by trying to get something running end-to-end. The point now is to add in the Javascript necessary to make Angular work. I'm having some kind of simple problem including the scripts.
The error I'm getting is (firebug), which appears to complain about the entire index.html file, is:
The Jade code is short. It is an index.jade file which extends a layout.jade file which includes in all the js files:
extends ../includes/layout
block main-content
section.content
div(ng-view)
h2 some regular text 5
This produces the following index.html file:
<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" href="/css/bootstrap.css">
<link rel="stylesheet" href="/vendor/toastr/toastr.css">
<link rel="stylesheet" href="/css/site.css">
</head>
<body ng-app="app">
<script type="text/javascript" src="/vendor/jquery/jquery.js"></script>
<script type="text/javascript" src="/vendor/angular/angular.js"></script>
<script type="text/javascript" src="/vendor/angular-resource/angular-resource.js"></script>
<script type="text/javascript" src="/vendor/angular-route/angular-route.js"></script>
<script type="text/javascript" src="/app/app.js"></script>
<section class="content">
<div ng-view></div>
<h2>some regular text 5</h2>
</section>
</body>
</html>
================ UPDATE ========
It appears Node is substituting the index.html file for the assets. The project directory structure is:
The server.js file which node runs is:
var express = require('express');
var stylus = require('stylus');
// set env variable to determine if in production or development mode; this contains environment if set my MODE
var env = process.env.NODE_ENV = process.env.NODE_ENV || 'development';
// create express application
var app = express();
function compile(str, path) {
return sytle(str).set('filename', path);
}
// configure express
//app.set('views', __dirname + '/server/views');
app.set('views', __dirname + '/views');
app.set('view engine', 'jade');
app.use(stylus.middleware({
src: __dirname + '/public',
compile: compile
}));
console.log("dirname:" + __dirname);
app.use(express.static(__dirname + '/public'));
//app.use(express.static(path.join(__dirname, '/public')));
app.get('/partials/:partialPath', function(req, res) {
res.render('partials/' + req.params.partialPath);
});
app.use(express.logger('dev')); //- logger no longer bundled with Express
app.use(express.bodyParser());
// add routes:
// We won't tell the server specifically what routes to handle. We'll have the client-side be
// responsible to server up and 404 notices. Client-side will have to specify all routes.
// Other solution is to coordinate your routes, so that every client route is also listed on the server.
// Far more customary to have a server side have a catch all that lists up a 404 page.
app.get('*', function(req, res) {
res.render('index');
})
var port = 3030;
app.listen(port);
console.log("listening on port: " + port + " ...");
This looks like a path issue as the page is not able to access your assets directory. Make sure your public folder is set right in your node server code. It should be along the lines of app.use(express.static(path.join(__dirname, 'public_folder_name')));. Looking at your folder structure, your server.js is nested in server folder and not at the same level as your public folder. Try app.use(express.static(__dirname + '/../public'));
I'm having a small problem with my project.
I'm using node and express for a little webpage .. it is rendering the html page, but the javascript file (test.js) is not sent to the user ..
<!doctype html>
<html>
<head>
<title>Spektrum</title>
<script src="test.js"></script>
<meta name = "viewport" content = "initial-scale = 1, user-scalable = no">
<style>
canvas{
}
</style>
</head>
<body>
<!-- some stuff -->
</body>
</html>
Node.js file:
var http = require('http'),
fs = require('fs'),
express = require('express'),
app = express();
app.use(express.bodyParser());
app.set('view engine', 'ejs');
app.engine('html', require('ejs').renderFile);
// .....
app.listen(8080, function() {
console.log('Server running at http://127.0.0.1:8080/');
});
Any idea how to send the javascript file with the html file to the user?
Greetings,
JS
you need to use static middleware to serve file (test.js needs to exist)
example:
// GET /javascripts/jquery.js
// GET /style.css
// GET /favicon.ico
app.use(express.static(__dirname + '/public'));