express static: Conflict when folder-name equals html-page-name - node.js

I serve static content via
app.use(express.static(path.join(__dirname, '../Frontend'),{index:"index.html",extensions:['html']}));
In the folder /Frontend is a file with filename: projects.html and a folder with the foldername: projects. This constellation is conflicting and not working.
How can I serve projects.html on www.example.com/projects and the html-files inside the folder on www.example.com/projects/xyz?
(At the moment www.example.com/projects/xyz works and www.example.com/projects returns a 404. Furthermore there is a 301 redirect from /projects to /projects/)

I ended up with a solution (Thank you all for the comments you posted)
Before:
app.use(express.static(path.join(__dirname, '../Frontend'),{index:"index.html",extensions:['html']}));
After (The order is relevant):
app.use('/projects', express.static(path.join(__dirname,'../Frontend/projects.html')));
app.use(express.static(path.join(__dirname, '../Frontend'),{index:"index.html",extensions:['html']}));

Picking up on my comment, I would suggest a variation of what you used:
app.get('/projects', (req, res) => {
res.sendFile(path.join(__dirname,'../Frontend/projects.html'));
});
app.use(express.static(path.join(__dirname, '../Frontend'),{index:"index.html",extensions:['html']}));
This will be more efficient because the first route will only match /projects, not everything else that starts with /projects.

Related

Express server serving index.html instead of chunk files, in a React app

I'm trying to serve a production build of a React app(Typescript), booted with create-react-app.
I'm following the official guide: https://create-react-app.dev/docs/deployment/
There's nothing unique about my setup. This is the server.js file, located in the root directory(above src):
app.use(express.static(path.join(__dirname, 'build')));
app.get('/*', function (req, res) {
res.sendFile(path.join(__dirname, 'build', 'index.html'));
});
app.listen(8000);
The production files are created within a folder called build. An example of the paths generated:
<script src="./static/js/main.0ae46692.chunk.js"></script>
When i navigate to localhost:8000/, everything is served fine. The initial request serves the index.html, and the script requests serve the correct files.
But, when i try to navigate(from the browser) to something like localhost:8000/todos, all script requests return index.html.
I do not see anything "special" about my setup, and do not understand what's going on. Am i missing something in the guide? It clearly states that app.get('/*',...) fixes the issue.
Any help will be greatly appreciated.
Copying the comment into an answer here so it can be marked.
This sounds like the issue is the script tags are generated with relative paths, because it works when you make a request to the root /, but not anything else. Could you try setting the "homepage" to "localhost:8000"

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

Express serving static files for multiple paths using regex

I've different paths in my app like:
/a
/a/:b
/a/:/b/:c/:d
For paths like /a, I use:
app.use(express.static(path.join(__dirname, 'public')));
For paths like /a/:b, I add another like this:
app.use('/a', express.static(path.join(__dirname, 'public')));
Instead of adding express.static for every path, is there any way to achieve this using a single line of code possibly by using regex.
Something like:
app.use(/\/[a-z]*/, express.static(path.join(__dirname, 'public')));
// BTW, this doesn't work
What would be a good practice to serve static files for multiple paths? Thank you.
You can redirect to add trailing slash:
app.all(/\/[a-z]*/, function(req, res) {
res.redirect('/static/');
});
app.use('/static/', express.static( __dirname + '/public' ));
I've solved this by adding all static links a pre-slash.
For example:
<link href='/lib/csss/bstrap.min.js' />
instead of
<link href='lib/csss/bstrap.min.js' />
NodeJS+Express: serving static files for diffrerent URLs

Can't serve up a static directory using Node 0.9 and latest express 4.11.2

Using the following simple Node server
var express = require('express');
var app = express();
var path = require('path');
app.use(express.static(path.join(__dirname, 'public'))); // "public" off of current is root
app.listen(3000);
console.log('Listening on port 3000');
I have of course put a 'public' directory in my root and also dropped a index.html file in it but when i point my browser to
http://localhost:3000/public/
I get
Cannot GET /public/
The problem is how you're mounting express.static middleware. In your example you're mounting it to the root of your application.
So, in your example you should be able to access content of /public directory from http://localhost:3000/.
So, all you need is to specify a mounting point for express.static middleware:
app.use('public', express.static(path.join(__dirname, 'public')));
You should also keep in mind that express.static don't have a default index page. So, if you have no index.html in your public directory you'll get 404 anyway (express.static won't list your files like apache do).
This one caught me out as well when starting with express.
http://localhost:3000/public/ won't be accessible.
For example lets say you have a css folder inside of the public directory with a file called styles.css
Your browser would be able to access that file at http://localhost:3000/css/styles.css.
The express documentation on express.static can be found here: app.use (under the two example tables)
edit 1: See this answer here.
edit 2: #Leonid Beschastny answer is correct, I didn't see that a path to a folder was missing in app.use(express.static(path.join(__dirname, 'public')));

RESTIFY not serving static files from subdirs

I´m trying to serve static files with restify using following code.
app.get(/.*/, restify.serveStatic({
directory: __dirname + '/public',
default: 'index.html'
}));
Calling GET / or GET /index.html works as expected.
Calling any file in a subdirectory of public does not work.
For example calling GET /css/style.css leads to a 404.
The file exists but is not being served.
Any ideas?
Try like this, works fine for me:
app.get(/.*/, restify.serveStatic({
directory: 'public',
default: 'index.html'
}));

Resources