jozenbasin
jozenbasin

Reputation: 2552

Serving static files with Express

I've written a Node.js application using express. When I request /, I want to serve /public/app/index.html. This works. However, index.html includes two css and two js files, and the relative pathing breaks. The paths are set as such (in the HTML header) but when trying to obtain app.js and style.css, the (browser?) thinks to look at / because, of course, that's what is being served.

<link rel='stylesheet' href='/lib/lib.css'/>
<link rel='stylesheet' href='style.css'/>
<script type="application/javascript" src="/lib/lib.js"></script>
<script type="application/javascript" src="app.js"></script>

The reason why this is a problem to me that I use a build process for my HTML, and it was logical at the time to dump all built files into one folder (HTML, CSS, JS, images). That way a template HTML file could be used that always pointed to js and css within its own folder. I'm hoping I can avoid injecting scripts with relative pathing.

Folder structure

root/
├── public/
│   ├── lib/
|   |    ├── lib.js
|   |    └── lib.css
│   ├── app/
│   |    ├── index.html
│   |    ├── style.css
|   |    └── app.js
├── app.js
├── routes/
|     └── index.js

app.js

var app = express();
var server = app.listen(4100);
app.use(express.static(path.join(__dirname, 'public')));
// routes
var index = require('./routes/index');
app.use('/', index);

index.js

var express = require('express');
var router = express.Router();

router.get('/', function(req, res, next) {
    var path = 'index.html';
    var options = {
        root : './public/app/'
    };
    res.sendFile(path, options, function(err){
        console.log(err)
    });
});

module.exports = router;

Upvotes: 1

Views: 1927

Answers (2)

Ben Ammann
Ben Ammann

Reputation: 712

Here you go

//Usefull to build the absolute Path
const path = require('path')

//Seperated Configuration
const configuration = {
  directory: './public/'
}

//Serve the index.html
app.get("/", function(req, res) {
  res.sendfile(path.join(__dirname, configuration.directory) + 'index.html')
});

//Serve other content
let staticPath = path.join(__dirname, configuration.directory);
app.use(express.static(staticPath));

app.listen etc ...

Upvotes: 1

robertklep
robertklep

Reputation: 203231

You could, for each page, add a separate static middleware:

// The "users" page.
app.use('/users', express.static(path.join(__dirname, 'public/users')));

// The "app" page.
app.use('/', express.static(path.join(__dirname, 'public/app')));

// Handle the rest of the static resources:
app.use(express.static(path.join(__dirname, 'public')));

To prevent issues, the order in which you declare them matters (the "more specific" routes should be declared first).

With a setup like that, you don't have to include a separate router.get('/', ...) just to serve public/app/index.html anymore, either.

Upvotes: 2

Related Questions