Node.js + Express.js: How to use the root (/) for serving static files? - node.js

how do we serve a static file located in the root of the directory (/) and not in a folder of it?
I am using Node.js with Express.js, I have tried the following JavaScript code in my index.js file which is located in / (the root of the directory).
Attempt 1
const path = require('path');
app.get('/', function(req, res) {
res.sendFile(path.join(__dirname, 'index.html'));
})
Attempt 2
const path = require('path');
app.get('/', function(req, res) {
res.sendFile(path.join(__dirname, '/'));
})
Same output as Attempt 1
Attempt 3
app.use(express.static('/'));
Didn't work, showed an error: "Cannot GET /".
Attempt 4
app.use(express.static(''));
Didn't work, showed an error: "Path cannot be empty".
Please assist, I have refered to many other possible questions similar to this, and one of the questions didn't have an answer, so I am re-asking.

The argument you pass to express.static needs to be the path to the directory where the file is.
It shouldn't be / which is the root of the entire file system (you might intend it to be the URL path / and not the file system path / but that isn't what it means).
The special variables __dirname will give you the directory the JS file you are currently running is in. You probably want that (assuming a directory structure like this):
.../
|-server.js
|-index.html
So
app.use(express.static(__dirname));
Note that it is generally better to separate out your server-side code and the files you sent to the client. It makes it much easier to maintain the project in the long run and prevents your server side code (which might contain secrets) being exposed over HTTP by the static module.

There isnt any difference if you use / and no / in the script
for express use
app.use(express.static(process.cwd() + '/'));

try this it might be helpful
app.use(express.static('/'));
you do not need the "/" before "js" because it is already included above:
<script src="test.js"></script>

Related

React.js: Heroku: Error: ENOENT: no such file or directory, stat '/app/src/client/build/index.html'

My apologies if this is not the correct way to do this. I have spent 4 days on this problem and eventually figured out a solution I would just like to post this possible solution if anyone else encounters this problem.
I am running a Node.js server with the React client inside of it here is an image of folder structure for reference.
I use a postbuild script in package.json to build my project on heroku
For reasons that are beyond me the following GET catch all statement
app.get("*", (req, res) => {
res.sendFile(path.resolve(__dirname, "client", "build", "index.html"))
});
Path was returning '/app/src/client/build/index.html' this is the incorrect path as your app is hosted on /app/client/build/index.html I had to edit my GET catch all statement to the following.
app.get("*", (req, res) => {
res.sendFile(path.resolve("client", "build", "index.html"));
});
It now correctly redirects to my index file and the app works correctly. Like I said unfortunately I cant advise on why the __dirname is not pointing to the right folder so if anyone could shed light on that will be great.
Also the robustness of the solution could be a problem as should Heroku change file structures the GET catch all statement could break.
__dirname returns the path to the folder containing the executed file.
So if the code containing __dirname is in the file '/app/src/app.js', __dirname will resolve as '/app/src'.
If your __dirname is in the file '/app/foo/bar/baz.js', it will resolve as '/app/foo/bar'.
Since you want your path to resolve as '/app/client/...' your fix is good.
The solution you used should be robust enough. path.resolve() will set your working directory (the one where you run your app, so '/app' on heroku I assume) as the root of your path. So unless you change your directory names or move files, you should be OK.

Serving express static files issue

I am having issues w/ serving static files in my current Express app, although I've done a similar setup in a bunch of other apps.. My folder structure is as follows:
/rootfolder/
/app
package.json
/client
/dist
/static
index.html
/server
/src
index.js
Relevant part of my server/src/index.js:
app.use(express.static(path.join(__dirname, "client", "dist")));
Where __dirname = /rootfolder/app/server/src
And when the user hits the / endpoint:
app.get("/", (req, res) => {
res.sendFile(appRoot.path + "/client/dist/index.html");
});
Where appRoot.path = /rootfolder/app
When I hit the / endpoint, I get a status 200 with the following text:
/rootfolder/app/client/dist/index.html
From what I can tell, the files are coded relative to each other correctly.. Does anyone know what I might be doing wrong?
Thanks in advance!
You're using res.send() instead of res.sendFile()
Also I suggest resolving your path via the path module, instead of concatenating a string.
const path = require('path')
app.use(express.static(path.join(__dirname, 'client', 'dist', 'static')))
And for the response of /:
res.sendFile(path.join(__dirname, 'client', 'dist', 'index.html')))
Try
app.use(express.static(path.join(__dirname,'client','dist')));
It basically gets the root directory and combines it with /client+ /dist + /static to give you the full route, without being relative path.
Now Let's call rootdirectory/client/dist X. That is the main directory for static files
If you have other files that are static but not in the same folder, you will have to give relative path from the X directory
Example:
app.get('/',function(req,res){
res.sendFile('/static/data.txt');
}
In the example above you indicate that the static file(data.txt) is located in the X/static directory.
Therefore => rootDirectory/client/dist/static/data.txt
2nd Example:
Let's say you have a folder in dist called images which you want to only store images.
when you are giving routes, you MUST use /images/filename.extention

serveStatic() unable to locate a file

I am new to node.js, and I am trying to use the serveStatic function to locate a specific file.
When I specify the exact path in the argument it doesn't work. However it works only when I specify the directory only , and name the file index.html inside that directory.
Any idea on how I can use to it locate a specific file? Any help would be really appreciated from you guys thanks!
Below is my code
var connect = require('connect'),
http = require('http'),
serveStatic = require('serve-static');
var app = connect();
// app.use(serveStatic('public')); Works
app.use(serveStatic('public/test.html'));// doesn't work
app.use(function(req, res){
});
http.createServer(app).listen(3000);
serve-static is meant to serve a whole directory (with all sub-directories, if any). You can't use it to serve just one single file.
What you could do with serve-static is to set a default file to be sent when user requests a root of your directory (by default it's an index.html file):
app.use(serveStatic('public', {index: 'test.html'}));
But if you really want to send just a single file, then is's better to use this answer:
app.use(function(req, res) {
res.sendfile('test.html', {
root: __dirname + '/public/'
});
});
Though, the best possible solution is to read this file once and cache it. In this case there will be no need to access your storage device each time somebody is requesting this file:
var html_data = require('fs').readFileSync('./public/test.html');
app.use(function(req, res) {
res.send(html_data);
});

How to configure the page the / path goes to in a tiny express app?

I'm using a simple node express server which is wrapped in the Webpack Dev Server (http://webpack.github.io/docs/webpack-dev-server.html)
I'm starting an express app from a top level directory where the static files are in a directory called "public".
I've got this line of configuration:
server.app.use(express.static(__dirname + '/public'));
If I type http://0.0.0.0:3000/index.html, all is good.
How but the URL of http://0.0.0.0:3000/ produces a directory listing of the top level.
What is the proper way to configure http://0.0.0.0:3000/ to go to the index.html file?
add
server.app.get('/', function(req, res) {
res.sendFile('index.html');
});
See the docs http://devdocs.io/express/index#res.sendFile
The solution involved setting the contentBase proper of the WebpackDevServer plus telling the
server.app.use(express.static(__dirname + contentbase);
Per this diff
The docs are here: http://webpack.github.io/docs/webpack-dev-server.html

Express-js can't GET my static files, why?

I've reduced my code to the simplest express-js app I could make:
var express = require("express"),
app = express.createServer();
app.use(express.static(__dirname + '/styles'));
app.listen(3001);
My directory look like this:
static_file.js
/styles
default.css
Yet when I access http://localhost:3001/styles/default.css I get the following error:
Cannot GET / styles /
default.css
I'm using express 2.3.3 and node 0.4.7. What am I doing wrong?
Try http://localhost:3001/default.css.
To have /styles in your request URL, use:
app.use("/styles", express.static(__dirname + '/styles'));
Look at the examples on this page:
//Serve static content for the app from the "public" directory in the application directory.
// GET /style.css etc
app.use(express.static(__dirname + '/public'));
// Mount the middleware at "/static" to serve static content only when their request path is prefixed with "/static".
// GET /static/style.css etc.
app.use('/static', express.static(__dirname + '/public'));
I have the same problem. I have resolved the problem with following code:
app.use('/img',express.static(path.join(__dirname, 'public/images')));
app.use('/js',express.static(path.join(__dirname, 'public/javascripts')));
app.use('/css',express.static(path.join(__dirname, 'public/stylesheets')));
Static request example:
http://pruebaexpress.lite.c9.io/js/socket.io.js
I need a more simple solution. Does it exist?
This work for me:
app.use('*/css',express.static('public/css'));
app.use('*/js',express.static('public/js'));
app.use('*/images',express.static('public/images'));
default.css should be available at http://localhost:3001/default.css
The styles in app.use(express.static(__dirname + '/styles')); just tells express to look in the styles directory for a static file to serve. It doesn't (confusingly) then form part of the path it is available on.
In your server.js :
var express = require("express");
var app = express();
app.use(express.static(__dirname + '/public'));
You have declared express and app separately, create a folder named 'public' or as you like, and yet you can access to these folder. In your template src, you have added the relative path from /public (or the name of your folder destiny to static files). Beware of the bars on the routes.
I am using Bootstrap CSS, JS and Fonts in my application. I created a folder called asset in root directory of the app and place all these folder inside it. Then in server file added following line:
app.use("/asset",express.static("asset"));
This line enables me to load the files that are in the asset directory from the /asset path prefix like: http://localhost:3000/asset/css/bootstrap.min.css.
Now in the views I can simply include CSS and JS like below:
<link href="/asset/css/bootstrap.min.css" rel="stylesheet">
What worked for me is:
Instead of writing app.use(express.static(__dirname + 'public/images')); in your app.js
Simply write
app.use(express.static('public/images'));
i.e remove the root directory name in the path. And then you can use the static path effectively in other js files, For example:
<img src="/images/misc/background.jpg">
Hope this helps :)
to serve static files (css,images,js files)just two steps:
pass the directory of css files to built in middleware express.static
var express = require('express');
var app = express();
/*public is folder in my project directory contains three folders
css,image,js
*/
//css =>folder contains css file
//image=>folder contains images
//js =>folder contains javascript files
app.use(express.static( 'public/css'));
to access css files or images just type in url http://localhost:port/filename.css ex:http://localhost:8081/bootstrap.css
note: to link css files to html just type<link href="file_name.css" rel="stylesheet">
if i write this code
var express = require('express');
var app = express();
app.use('/css',express.static( 'public/css'));
to access the static files just type in url:localhost:port/css/filename.css
ex:http://localhost:8081/css/bootstrap.css
note to link css files with html just add the following line
<link href="css/file_name.css" rel="stylesheet">
this one worked for me
app.use(express.static(path.join(__dirname, 'public')));
app.use('/img',express.static(path.join(__dirname, 'public/images')));
app.use('/shopping-cart/javascripts',express.static(path.join(__dirname, 'public/javascripts')));
app.use('/shopping-cart/stylesheets',express.static(path.join(__dirname, 'public/stylesheets')));
app.use('/user/stylesheets',express.static(path.join(__dirname, 'public/stylesheets')));
app.use('/user/javascripts',express.static(path.join(__dirname, 'public/javascripts')));
Webpack makes things awkward
As a supplement to all the other already existing solutions:
First things first: If you base the paths of your files and directories on the cwd (current working directory), things should work as usual, as the cwd is the folder where you were when you started node (or npm start, yarn run etc).
However...
If you are using webpack, __dirname behavior will be very different, depending on your node.__dirname settings, and your webpack version:
In Webpack v4, the default behavior for __dirname is just /, as documented here.
In this case, you usually want to add this to your config which makes it act like the default in v5, that is __filename and __dirname now behave as-is but for the output file:
module.exports = {
// ...
node: {
// generate actual output file information
// see: https://webpack.js.org/configuration/node/#node__filename
__dirname: false,
__filename: false,
}
};
This has also been discussed here.
In Webpack v5, per the documentation here, the default is already for __filename and __dirname to behave as-is but for the output file, thereby achieving the same result as the config change for v4.
Example
For example, let's say:
you want to add the static public folder
it is located next to your output (usually dist) folder, and you have no sub-folders in dist, it's probably going to look like this
const ServerRoot = path.resolve(__dirname /** dist */, '..');
// ...
app.use(express.static(path.join(ServerRoot, 'public'))
(important: again, this is independent of where your source file is, only looks at where your output files are!)
More advanced Webpack scenarios
Things get more complicated if you have multiple entry points in different output directories, as the __dirname for the same file might be different for output file (that is each file in entry), depending on the location of the output file that this source file was merged into, and what's worse, the same source file might be merged into multiple different output files.
You probably want to avoid this kind of scenario scenario, or, if you cannot avoid it, use Webpack to manage and infuse the correct paths for you, possibly via the DefinePlugin or the EnvironmentPlugin.
The problem with serving __dirname is that __dirname returns the path of the current file, not the project's file.
Also, if you use a dynamic header, each page will look for the static files in a different path and it won't work.
The best, for me, is to substitute __dirname for process.cwd() which ALWAYS donates the path to the project file.
app.use(express.static(process.cwd() + '/public'));
And in your project:
link rel="stylesheet" href="/styles/default.css"
See: What's the difference between process.cwd() vs __dirname?
I was using
app.use(express.static('public'))
When there was no file in the public folder with name index.html.
I was getting the following error in the browser:
"Cannot GET /"
When I renamed the file to 'index.html', it works fine.
Try accessing it with http://localhost:3001/default.css.
app.use(express.static(__dirname + '/styles'));
You are actually giving it the name of folder i.e. styles not your suburl.
I find my css file and add a route to it:
app.get('/css/MyCSS.css', function(req, res){
res.sendFile(__dirname + '/public/css/MyCSS.css');
});
Then it seems to work.
if your setup
myApp
|
|__ public
| |
| |__ stylesheets
| | |
| | |__ style.css
| |
| |___ img
| |
| |__ logo.png
|
|__ app.js
then,
put in app.js
app.use('/static', express.static('public'));
and refer to your style.css: (in some .pug file):
link(rel='stylesheet', href='/static/stylesheets/style.css')
Try './public' instead of __dirname + '/public'.
Similarly, try process.cwd() + '/public'.
Sometimes we lose track of the directories we are working with, its good to avoid assuming that files are located where we are telling express where they are.
Similarly, avoid assuming that in the depths of dependencies the path is being interpreted the same way at every level.
app.use(express.static(__dirname+'/'));
This worked for me, I tried using a public directory but it didn't work.
But in this case, we give access to the whole static files in the directory, hope it helps!
In addition to above, make sure the static file path begins with / (ex... /assets/css)... to serve static files in any directory above the main directory (/main)
Create a folder with 'public' name in Nodejs project
folder.
Put index.html file into of Nodejs project folder.
Put all script and css file into public
folder.
Use app.use( express.static('public'));
and in index.html correct path of scripts to <script type="text/javascript" src="/javasrc/example.js"></script>
And Now all things work fine.
static directory
check the above image(static directory) for dir structure
const publicDirectoryPath = path.join(__dirname,'../public')
app.use(express.static(publicDirectoryPath))
// or
app.use("/", express.static(publicDirectoryPath))
app.use((req, res, next) => {
res.sendFile(path.join(publicDirectoryPath,'index.html'))
In your nodejs file
const express = require('express');
const app = express();
app.use('/static', express.static('path_to_static_folder'));
In your pug file
...
script(type="text/javascript", src="static/your_javascript_filename")
...
Note the "static" word. It must be same in nodejs file and pug file.
i just try this code and working
const exp = require('express');
const app = exp();
app.use(exp.static("public"));
and working,
before (not working) :
const express = require('express');
const app = express();
app.use(express.static("public"));
just try

Resources