Serve Static content to subdomain with express? - node.js

I have an express app, which is just the default blank app. I have then added the line:
app.use(serveStatic('docs/public', {'index': ['index.html', 'index.htm']}))
to serve the contents of my docs/public directory. This works great, but it is being served to the root of my application, so I no longer see the default express index page.
I would like to see the static html (which I am currently seeing as my index) as a subdomain, e.g. blog.mydomain.com. Or at least as mydomain.com/blog. How do I serve the static content to a subdomain?
NB: the static file names and folders can't change, as my ./docs directory is a hexo project and any changes would break the generation of the static content in the docs/public folder.
I have tried to use express-subdomain so I added code like this to my app.js:
var router = express.Router();
router.use(serveStatic('docs/public', {'index': ['index.html', 'index.htm']}))
app.use(subdomain('docs', router));
However, If I run that, I get the express index page at http://localhost:3000/ (not the static one) which is what I want, but if I go to http://docs.localhost:3000/ then I don't get my static content, still the original express index. In fact, if I remove the subdomain code nd run the app, navigate tot he docs subdomain I still get the same result.
I have also tried to use the subdomain module:
app.use(subdomain('docs', serveStatic('docs/public', {'index': ['index.html', 'index.htm']})));
However, that has the same result as above (not serving any static content).
So how can I serve the static content I am currently serving on a subdomain?

#GeorgeEdwards In your example code you've called the static middleware before the subdomain middleware. The order is important... it should be something like this:
app.use(subdomain('docs', express.static('docs/public')));
This means any requests with the docs subdomain will be handled by the express static middleware.

Related

Express static folder does not load properly

I'm having trouble with a Node APP that I am building.
App folder structure:
controllers // controllers
helpers // helpers
config // some config files
public // stores a built angular app
...
App URL 1: www.domain.com
App URL 2: www.another.com/myapps/app1
So this is how I set the static folder to load the assets:
app.use(express.static(__dirname + '/public'));
And this is how I would access the files in the static folder:
URL1: www.domain.com/assets/main.js
URL2: www.another.com/myapps/app1/assets/main.js
Now, the problem is that if I deploy the app on URL1 everything works perfectly. But deploying the app to URL2 gives me some issues.
The static files cannot be accessed on the app on URL2. I get 404 (Cannot GET ...).
www.another.com/myapps/app1/assets/main.js // returns 404
www.domain.com/assets/main.js // returns the JavaScript file.
There are multiple apps running on URL2 that is why I have used contexts to separate the apps.
My initial thoughts are that because of the additional contexts to the url on URL2, express is failing to set the static folder properly.
Could this be because the static folder is not being set properly?
express.static receives data from somewhere and applies this data to the root of your domain.
Actually you can get your files inside another folder by adding some structure.
In your case set app.use(express.static(__dirname + '/public')); and place assets inside app1 and then in myapps folders. All this should be inside public folder

ExpressJS static file serve always serves the same file

I have a expressJs setup which looks like this:
// Imports...
const app: express.Application = express();
const port: number = 3001;
const listener = new StatementListenerAPI();
app.use('/listen', listener.getRouter());
app.use('/welcome', router);
if (fs.existsSync('./client')) {
// Running in prod environment with pre built client directory. Serve this.
app.use(express.static('./client'));
}
app.listen(port);
So I have some routers connected to the express app, and at the bottom I declare that the directory client should be served statically. This directory contains an index.html as well as lots of JS, CSS and PNG files. However, no matter which URL I try to access from the express server, it always shows the code of the index.html within the statically served directory. The references to the JS and CSS files used inside the index.html also just return the code of the index.html.
I am using ExpressJS 4.16.3
What am I doing wrong?
Edit: So technically it works if using __dirname + '/client' instead of ./client. What I am now getting is that, when making GET requests from e.g. Postman (therefore "hand-crafting" the HTTP requests), I am always getting the correct results. If I call the resources from within my web browser, it still always shows the website (resolves the index.html). However, now all resources like JS and CSS scripts are being resolved properly, so apperantly Chrome resolves those dependencies properly, I am just wondering why I am still getting the contents of index.html as result when requesting some of the assets or some of the express endpoints via Chrome. API calls via code are working fine, so its only why manual chrome requests show this weird behaviour, at this point I am only asking out of curiosity.
Answer to your original question:
The path supplied to express.static should be relative to the directory from where you launch your node process or an absolute path. To be safe construct an absolute path (ie from the current directory or file). For example:
app.use(express.static(__dirname + '/client'));
Regarding your followup question:
I assume this is because Chrome uses heavy caching and it thinks this folder should return the html file. You can try and reset all caches in Chrome, or just for the page.

Where to place robots.txt - Nodejs express project

Can you please tell me where to place robots.txt and sitemap.xl in nodejs express project folder structure so that it will be available to search engines.
I placed it along with app.js and inside public folder,but i got "Cannot GET /sitemap.xml" error in both the case
Have you set the route for your public folder, the one that is shared or served to the public?
like for example:
app.use(express.static('public'))
All the content inside the folder: "public" like html,css or robots.txt will be served.

Express: How to serve font-awesome as static content?

I use express to serve static content on my site and I want to incorporate FontAwesome (npm install font-awesome). However in Font-Awesome's css the links to the font files are appended with a query-string containing versioning information witch express doesn't understand.
Has anyone encountered this and found a fix? Is there a simple way to make express ignore the qs for static content?
var express = require('express')
var app = express()
app.use('/static', express.static('./node_modules/font-awesome/css'))
app.use('/static', express.static('./node_modules/font-awesome/fonts'))
// response 200 | /static/font-awesome.min.css
// error 404 | /static/fontawesome--webfont.woff?v=4.6.3
Update
As #Denys Séguret points our it's not the qs as I had thought. The actual request is for /fonts/fontawesome--webfont.woff?v=...
Solution
app.use('/fonts', express.static('./node_modules/font-awesome/fonts'))
When your browser requests /static/fontawesome--webfont.woff?v=4.6.3, the server is free to ignore the ?v=xxx part. And that's what is done by the express.static module. The point of that part is to prevent browsers and proxies from using an old version of the file.
So the problem isn't where you think it is. The problem is you map the static route to two servers. The first one doesn't find the file and issues a 404.
(Dirty) Solution 1:
Change your mapping
app.use('/static', express.static('./node_modules/font-awesome'))
and change the URLs:
/static/fonts/fontawesome--webfont.woff?v=4.6.3
I say it's dirty because you're serving the unchecked content of a node modules (which is updated when you do a npm update). You should never do that.
 Solution 2:
Create a static directory (the name doesn't matter) and put inside the contents of the ./node_modules/font-awesome/css and ./node_modules/font-awesome/fonts directories then just map it using
app.use('/static', express.static('./static'));

Using nodejs Connect's static server middleware to serve only a subdirectory

I'm trying to build a webapp where:
http://mydomain.com/static/x.png serves x.png as a static file using Connect's static middleware
http://mydomain.com/other_stuff does other stuff
My directory structure is
start_server.coffee
static/
x.png
In start_server.coffee I have:
app = connect()
app.use connect.staticCache()
app.use connect.static(__dirname + '/static')
app.use ...middleware that serves the dynamic parts of my app...
app.listen 80
When I try http://mydomain.com/static/x.png, the request bypasses the static server and gets routed to the rest of my app. I stepped through the code in a debugger and it looks like static is trying to lookup static/static/x.png instead of static/x.png.
I was able to get it working by changing connect.static(_dirname + '/static') to connect.static(_dirname), but now it will serve stuff that's not in the static directory which is not good!
What's the cleanest way of doing what I'm trying to do? I could probably use Express's routing functionality, but I don't particularly want to use Express unless I have to, since the rest of my app handles routing its own way.
Thanks!
So the issue is the mismatch between your URL paths and your filesystem layout. There are 2 easy-peasy get-on-with-your-life solutions.
Remove "static/" from your URLs. The static middleware will only serve files under the static directory but the URLs won't include the word "static".
Do this: mkdir public && mv static public. Leave the public directory empty other than the static subdirectory. Now your URLs can stay the same and in your code you need app.use connect.static(__dirname + '/public').
Now this is what the static middleware provides out of the box. The URLs have to map simply to the filesystem. This is why it "just works" and is simple.
If you really want to have static/ in your URL but not map to a directory underneath your static root, add a middleware before the static middleware that alters req.path to remove the leading "/static", then call next() and I think that will trick the static middleware into doing what you want.

Resources