I'm trying to only use html and render pages from my express server. I keep getting the error
No default engine was specified and no extension was provided.
I have specified the dirname in app.js and I am telling the server to render by using the dirname in my router. I'm not really sure what's holding me up? Can someone provide some insight?
app.js ( I have removed import statements that aren't relevant)
var app = express();
app.use(express.static(__dirname + '/public')); //setting static file directory
//Store all HTML files in view folder.
module.exports = app;
here's my index router where I am calling render on the pages
var express = require('express');
var router = express.Router();
const path = require('path');
/* GET home page. */
router.get('/', function(req, res, next) {
res.render('main', { title: 'Express' });
});
/* GET styles page. */
router.get('/style', function(req, res, next) {
res.render('styles', { title: 'styles' });
});
/* GET styles page. */
router.get('/style',function(req,res){
res.sendFile(path.join(__dirname+'/style.html'));
});
module.exports = router;
If you don't have a renderer like Handlebars, you can't call res.render as far as I know. If you are serving static views you don't need a renderer anyways, you just specify the folder where the static files are located at.
This means after you have specified your static folder, you will be able to access the files by having their filename in the route. Express' documentation on static files. You don't need routes to send the files.
Example
CodeSandbox Example
src
|- view
| |- hello.html
|- index.js
index.js
const express = require("express");
//create a server object:
const app = express();
//Serve all files inside the view directory, path relative to where you started node
app.use(express.static("src/view/"));
app.listen(8080, function() {
console.log("server running on 8080");
}); //the server object listens on port 8080
module.exports = app;
You will now see hello.html on the /hello.html route. Any other file will also be visible under its name.
Related
I want to serve index.html and /media subdirectory as static files. The index file should be served both at /index.html and / URLs.
I have
web_server.use("/media", express.static(__dirname + '/media'));
web_server.use("/", express.static(__dirname));
but the second line apparently serves the entire __dirname, including all files in it (not just index.html and media), which I don't want.
I also tried
web_server.use("/", express.static(__dirname + '/index.html'));
but accessing the base URL / then leads to a request to web_server/index.html/index.html (double index.html component), which of course fails.
Any ideas?
By the way, I could find absolutely no documentation in Express on this topic (static() + its params)... frustrating. A doc link is also welcome.
If you have this setup
/app
/public/index.html
/media
Then this should get what you wanted
var express = require('express');
//var server = express.createServer();
// express.createServer() is deprecated.
var server = express(); // better instead
server.configure(function(){
server.use('/media', express.static(__dirname + '/media'));
server.use(express.static(__dirname + '/public'));
});
server.listen(3000);
The trick is leaving this line as last fallback
server.use(express.static(__dirname + '/public'));
As for documentation, since Express uses connect middleware, I found it easier to just look at the connect source code directly.
For example this line shows that index.html is supported
https://github.com/senchalabs/connect/blob/2.3.3/lib/middleware/static.js#L140
In the newest version of express the "createServer" is deprecated. This example works for me:
var express = require('express');
var app = express();
var path = require('path');
//app.use(express.static(__dirname)); // Current directory is root
app.use(express.static(path.join(__dirname, 'public'))); // "public" off of current is root
app.listen(80);
console.log('Listening on port 80');
express.static() expects the first parameter to be a path of a directory, not a filename. I would suggest creating another subdirectory to contain your index.html and use that.
Serving static files in Express documentation, or more detailed serve-static documentation, including the default behavior of serving index.html:
By default this module will send “index.html” files in response to a request on a directory. To disable this set false or to supply a new index pass a string or an array in preferred order.
res.sendFile & express.static both will work for this
var express = require('express');
var app = express();
var path = require('path');
var public = path.join(__dirname, 'public');
// viewed at http://localhost:8080
app.get('/', function(req, res) {
res.sendFile(path.join(public, 'index.html'));
});
app.use('/', express.static(public));
app.listen(8080);
Where public is the folder in which the client side code is
As suggested by #ATOzTOA and clarified by #Vozzie, path.join takes the paths to join as arguments, the + passes a single argument to path.
const path = require('path');
const express = require('express');
const app = new express();
app.use(express.static('/media'));
app.get('/', (req, res) => {
res.sendFile(path.resolve(__dirname, 'media/page/', 'index.html'));
});
app.listen(4000, () => {
console.log('App listening on port 4000')
})
If you have a complicated folder structure, such as
- application
- assets
- images
- profile.jpg
- web
- server
- index.js
If you want to serve assets/images from index.js
app.use('/images', express.static(path.join(__dirname, '..', 'assets', 'images')))
To view from your browser
http://localhost:4000/images/profile.jpg
If you need more clarification comment, I'll elaborate.
use below inside your app.js
app.use(express.static('folderName'));
(folderName is folder which has files) - remember these assets are accessed direct through server path (i.e. http://localhost:3000/abc.png (where as abc.png is inside folderName folder)
npm install serve-index
var express = require('express')
var serveIndex = require('serve-index')
var path = require('path')
var serveStatic = require('serve-static')
var app = express()
var port = process.env.PORT || 3000;
/**for files */
app.use(serveStatic(path.join(__dirname, 'public')));
/**for directory */
app.use('/', express.static('public'), serveIndex('public', {'icons': true}))
// Listen
app.listen(port, function () {
console.log('listening on port:',+ port );
})
I would add something that is on the express docs, and it's sometimes misread in tutorials or others.
app.use(mountpoint, middleware)
mountpoint is a virtual path, it is not in the filesystem (even if it actually exists). The mountpoint for the middleware is the app.js folder.
Now
app.use('/static', express.static('public')`
will send files with path /static/hell/meow/a.js to /public/hell/meow/a.js
This is the error in my case when I provide links to HTML files.
before:
<link rel="stylesheet" href="/public/style.css">
After:
<link rel="stylesheet" href="/style.css">
I just removed the static directory path from the link and the error is gone. This solves my error one thing more don't forget to put this line where you are creating the server.
var path = require('path');
app.use(serveStatic(path.join(__dirname, 'public')));
You can achieve this by just passing the second parameter express.static() method to specify index files in the folder
const express = require('express');
const app = new express();
app.use(express.static('/media'), { index: 'whatever.html' })
I am currently working on a nodejs project, and I have a simple question. I want to serve some libraries from my node_modules folder statically to the client (maybe stupid, but not relevant to the question), but I dont want to trash my main server JS file with all these statically served files like this:
const express = require('express');
const app = express();
// Imports here
app.use('/assets/lib/bootstrap', './node_modules/bootstrap/dist');
app.use('/assets/lib/axios', './node_modules/axios/dist');
app.use('/assets/lib/aos', './node_modules/aos/dist');
app.listen(3000, () => {
console.log('Server listening on port 3000');
});
If I have 10+ imports, this would trash up my Server JS file, which I like to keep as clean as possible. I was wondering why this option wouldn't work:
./routes/route1.js :
const express = require('express');
const router = express.Router();
const path = require('path');
// Imports here
router.use('/bootstrap', path.resolve(__dirname, 'node_modules/aos/dist'));
router.use('/axios', path.resolve(__dirname, 'node_modules/aos/dist'));
router.use('/aos', path.resolve(__dirname, 'node_modules/aos/dist'));
// path to node_modules file is not the problem here
module.exports = router
And in my main Server JS file:
const express = require('express');
const app = express();
const route1 = require('./routes/route1');
// Imports here
app.use('/assets/lib', route1);
app.listen(3000, () => {
console.log('Server listening on port 3000');
});
But this gives me an error. The file is not statically served to the client. Is this because an express Router can't serve static files? Maybe this is a rookie mistake, but any help is appreciated. The first code snippet does work, but I'm trying to keep my code organized.
Use the express.static middleware in your route1.js file instead of simply passing the folder path string to the route.
I'm a beginner in Express. So I might've failed to frame the question properly. I have created a MEAN application wherein I've separated my frontend and backened. Frontend runs on port:4200 and server runs on port:3000. I wanted to run both frontend and backend on same port as part of deployment. I'm getting MIME type errors, someone told me that there is some problem with my server environment. Maybe I'm not sending headers properly. Here is my code:
I have mentioned tried solutions in the code itself as <----TRIED THIS
server.js
const express = require('express');
express.static.mime.define({'application/javascript': ['js']}); <----TRIED THIS
const bodyParser = require('body-parser');
const path = require('path');
// express.static.mime.define({'application/javascript': ['js']}); <----TRIED THIS
const api = require('./routes/api');
const PORT = 3000;
const app = express();
app.use(express.static(path.join(__dirname, 'dist')));
app.use(bodyParser.urlencoded({ extended: true }));
app.use(bodyParser.json());
app.use('/api', api);
app.get('/', function(req, res) {
// res.send('Hello from the server'); <----TRIED THIS
// res.writeHead(200, {'Content-Type': 'text/html'}); <----TRIED THIS
// res.set('Content-Type', 'text/plain'); <----TRIED THIS
// res.setHeader("Content-Type","application/json"); <----TRIED THIS
res.sendFile(path.join(__dirname, 'dist/application/index.html'));
})
app.listen(PORT, function() {
console.log('Server listening on PORT '+PORT);
});
api.js
For instance I'm showing you GET function only
const express = require('express');
const router = express.Router();
const mongoose = require('mongoose');
const db = <my db string>;
const jwt = require('jsonwebtoken');
mongoose.connect(
...
)
function verifyToken(req, res, next) {
...
}
router.get('/myarticles', (req, res) => {
var person="Tanzeel Mirza";
console.log('Get request for tanzeel articles');
Article.find({contributor: person}, (error, article) => {
if(error) {
console.log(error)
}
else {
if(!article) {
res.status(401).send('Invalid email')
}
else if(2>4) {
console.log("test passed");
}
else {
res.json(article);
}
}
})
})
module.exports = router;
But still I'm getting
Loading module from “http://localhost:3000/runtime-xxx.js” was blocked because of a disallowed MIME type (“text/html”).
Loading module from “http://localhost:3000/polyfills-xxx.js” was blocked because of a disallowed MIME type (“text/html”).
Loading module from “http://localhost:3000/main-xxx.js” was blocked because of a disallowed MIME type (“text/html”).
Please correct me.
PS: I asked separate questions for MIME error here. But no answers.
Since your assets are inside dist/application folder, Use app.use(express.static(path.join(__dirname, 'dist/application')));
To match all web app routes, Use app.get('*', function(req, res) {
res.sendFile(path.join(__dirname, 'dist/application/index.html'));
}).
This a generic route and will be called into action only if express can't find any other routes and always serve index.html. For example any valid /api route will never reach this handler, as there a specific route that handles it.
Final code for server.js
const express = require('express');
const bodyParser = require('body-parser');
const path = require('path');
const api = require('./routes/api');
const PORT = 3000;
const app = express();
app.use(express.static(path.join(__dirname, 'dist/application')));
app.use(bodyParser.urlencoded({ extended: true }));
app.use(bodyParser.json());
app.use('/api', api);
app.get('*', function(req, res) {
res.sendFile(path.join(__dirname, 'dist/application/index.html'));
})
app.listen(PORT, function() {
console.log('Server listening on PORT '+PORT);
});
A few points to not.
To serve static files, you need not set any headers manually. Express looks up the files in the folder (dist folder in your case) you set as static directory with the express.static middleware function. Express also sets the response headers based on the file extension.
So you don't need express.static.mime.define in your code anymore.
In your case you have defined app.use(express.static(path.join(__dirname, 'dist'))); which listens for static files at dist folder. In this app.use command, you haven't used a mount path which means that all the requests will go through the static middleware. If the middleware finds an asset with the same name, path and extension in dist folder it returns the file, else the request is passed to the other route handlers.
Also, If you are using static middleware, as long as there is an index.html in dist folder (immediate child of dist folder), your route handler for "/" will never get invoked as the response will be served by the middleware.
If you don't have an index html file in dist folder(immediate child of dist), but it's present somewhere in subfolders of dist, and still you need to access it using root path "/", only then you need a route handler for path "/" as below.
app.get("/", function(req, res) {
res.sendFile(path.join(__dirname, "dist/application/index.html"));
});
JS files referred using "./" in dist/application/index.html are referred relative to dist folder itself and NOT dist/application folder.
You can refer this REPL for updated code 👉.
https://repl.it/repls/SoreFearlessNagware
Try below urls
/api/myarticles - Rendered by "/api" route handler
/api/myarticles.js - Rendered by static asset middleware because the file exists in dist/api folder
/ - rendered using "/" route handler and res.sendFile because index.html doesn't exist in dist folder.
/test.js - Rendered using static middleware because file exists in dist folder
Additional links for reference.
https://expressjs.com/en/api.html#res.sendFile
https://expressjs.com/en/starter/static-files.html
1.Build your angular project, either inside or outside the server folder using ng build cmd.
2.To build your project inside server, change the dist-folder path in angular-cli.
3.To change path, either use cli cmd or edit the angular-cli.json file's "outDir": "./location/toYour/dist"
Or by using this cli cmd ng build --output-path=dist/example/
4.Then In your server root file include the static build/dist folder using express.
5.Like this app.use(express.static(path.join( 'your path to static folder')));
6.Now restart your server.
So I have server.js file that imports a router
const path = require("path");
const express = require("express");
const app = express();
const PORT = 8080;
app.use(express.urlencoded({ extended: true }));
app.use(express.json());
app.use(require('./app/routing/htmlRoutes'));
The router looks like this
const path = require("path");
var express = require('express');
var router = express.Router();
router.get('/', function(req, res) {
res.sendFile('home.html', { root: path.join(__dirname, '../public') });
});
router.get('/survey', function(req, res) {
res.sendFile('survey.html', { root: path.join(__dirname, '../public') });
});
module.exports = router;
It does work! It renders html pages, however those html pages have css stylesheets hooked up to them and located in the same directory, but they render as blank html sheets (unstyled)...
How do I make them render with css stylesheets taken into account?
When the browser encounters the style reference of the loaded html file, it tries to load the file specified in the src attribute. Now your server script doesn't have a route for that. It will load the css if you add a route for that specific css file. However as Irshad said, the standard way to do this is to add a route for all the static files.
app.use(express.static("public"))
Right now, you are only sending home.html everytim the root is requested.
Change your code to read the requested file from the req and serve that file whatever it may be.
Why not set the middleware to serve static files (css, html) from public folder app.use(express.static("public"))
See the working example
I have some server side code in node js, which creates a express js object and runs the server. The app loads the index.html page which is inside the public folder. I have never written the code to serve the home page (mention below), still it works.
app.get('*', (req, res) => {
res.sendFile(path.join(__dirname, 'public/index.html'));
});
I have not written this code so how does the index.html gets rendered. My understanding says express JS looks for the first instance of index.html page in all the static folders declared in the code and renders it, in my case the static folder is "publimc" and it has index.html at the root level.
server code follows below, which I have written.
var express = require('express');
var app = express();
var mongojs = require('mongojs');
var db = mongojs('contactlist', ['contactlist']);
var bodyParser = require('body-parser');
app.use(express.static(__dirname + '/publimc'));
app.use(bodyParser.json());
app.get('/contactlist', function (req, res) {
console.log('I received a GET request');
db.contactlist.find(function (err, docs) {
console.log(docs);
res.json(docs);
});
});
app.listen(8000);
console.log("Server running on port 8000");
The home page is rendered as part of the express.static middleware default options.
To disable this logic, set express.static(..., { index: false }).
If you want to change the file served as a home page, set express.static(..., { index: 'yourfile.html' }).
What this option does, in fact, is attempt to serve an index page with given file name for each directory in your public folder, so if you have public/foo/index.html then it will get served when requesting /foo/ path.