1

I have got my directory structure like this in a nodejs project

I am serving <code>login_nimda.html</code> from <code>nimda.js</code>

And here's my login_nimda.html snippet with the CSS links:

enter image description here

I am serving login_nimda.html from nimda.js but the associated CSS file isn't loading up.

As you can see I have used root-relative path but I am still not getting any results. The same reason why I had to use the CDN for Bootstrap and couldn't use the downloaded file.

How is it supposed to be? Where am I going wrong with the href attribute of the link?

EDIT: Here's my nimda.js snippet that is serving the HTML file login_nidma.html

router.get('/', function( req, res){
    let html = fs.readFileSync(path.join(__dirname,'../static/login_nimda.html'));
    res.writeHead(200, {'Content-Type': 'text/html'});
    res.end(html);
});
Aakash Verma
  • 3,705
  • 5
  • 29
  • 66
  • Please provide your code, specially the section where you are serving the static files. – Kayvan Mazaheri Jan 06 '18 at 15:38
  • I have already provided the part of the page where it links with the css. The page `login_nimda.html` is just served as a response to a GET request by `nimda.js` present in the routes folder. Nothing special in there. – Aakash Verma Jan 06 '18 at 18:00
  • I meant your Node.is code. – Kayvan Mazaheri Jan 06 '18 at 18:44
  • @KayvanMazaheri Done. – Aakash Verma Jan 07 '18 at 04:40
  • are serving the static files such as `.css` files in your node.js server as well? If yes, please provide the related code. – Kayvan Mazaheri Jan 07 '18 at 07:32
  • @KavyanMazaheri No, I am not explicitly serving them as such. I just hoped that the html file would link to those but it seems that the html file which is sent as a response holds no connection back to the server. In this case, how am I supposed to serve the static css and js files alongside the html file? – Aakash Verma Jan 07 '18 at 09:04
  • What code do you have that is failing to correctly serve static files? – Greg Rozmarynowycz Jan 15 '18 at 06:25
  • Inside my `nimda.js` route, I have `app.use(express.static(path.join(__dirname, '../static')));` to serve my css and js inside the `/app/static` folder. – Aakash Verma Jan 15 '18 at 10:15
  • @AakashVerma Are you open to suggestions on a better way to organize your files/directories? Asking bc it would affect how I might answer your question. Also, are you using anything inside the `/dist` or `/public` directories? – therobinkim Jan 16 '18 at 03:30
  • @therobinkim No, I am not suggesting anything close to that. I want to serve static files from two different folders `static` and `public`. Doing express.static on both of them in `server.js` works but when I do express.static for `static` folder in `nimda.js`, it doesn't work. – Aakash Verma Jan 16 '18 at 18:04

3 Answers3

1

You need to serve your static files (e.g. .css files) as well.

You can use Express's built-in middleware for serving static files, express.static().

Here is basic example:

// serve static files in "app/static" with your node.js server
app.use('/static', express.static('app/static'))

Now you can access them in browser (and inside your HTML files) from /static:

<link href="/static/css/login_nimda.css" rel="stylesheet"> 

Please read more about express.static() and its usage here: http://expressjs.com/en/starter/static-files.html

Kayvan Mazaheri
  • 2,447
  • 25
  • 40
  • Hey, thanks. I had basically got what I was missing on from the discussion at comments. The scene now is that I have to set the static folder in `server.js` which works. Can you guess why when I try to set it in the `nimda.js` under `routes` folder it doesn't conduct the same? – Aakash Verma Jan 07 '18 at 12:10
  • @AakashVerma The argument to `express.static()` is a relative path. use `path.join` to pass the desired path. also read the last paragraph of (this)[http://expressjs.com/en/starter/static-files.html]. – Kayvan Mazaheri Jan 07 '18 at 14:20
  • Sorry to bug you this much, but I have been doing the same way you told me using `path.join` but the issue is that I am unable to do it from `nimda.js`. At `server.js`, `app.use(express.static(path.join(__dirname, '/app/static')));` works fine but not at `nimda.js`. I would just like to know if it's possible to serve from `nimda.js` – Aakash Verma Jan 07 '18 at 14:26
  • @AakashVerma I think this path is still relative to where this line is being called; so changing it to this might actually do the trick in `nimda.js`: `app.use(express.static(path.join(__dirname, '/../static')));` – Kayvan Mazaheri Jan 07 '18 at 14:30
  • So silly of me, I didn't check through `console.log(__dirname)` and there's bad news. I was able to produce same path for `express.static()` (checked it using `console.log`) in both `nimda.js` as well as `server.js` but it turns out that the one in `nimda.js` doesn't work. Don't know why but it doesn't. – Aakash Verma Jan 07 '18 at 15:08
1
  1. Use the express.static middleware to serve static files instead of:

    router.get('/', function( req, res){
        let html = fs.readFileSync(path.join(__dirname,'../static/login_nimda.html'));
        res.writeHead(200, {'Content-Type': 'text/html'});
        res.end(html);
    });
    

    https://expressjs.com/en/starter/static-files.html

    Don't forget that you can use the path module and __dirname variable (see this SO question) to help tell express.static(...) exactly where your static files are.

  2. If you want to app.use(express.static(...)) multiplie times in different files, you need to make sure you're applying the middleware to the same app instance. I've created a code sample to illustrate. In server.js#L10, I pass in var app into the routes.js module (which is the equivalent of your nimda.js). In routes.js#L4, I am calling .use() on the same var app as the one created in server.js. In your refactored version where you're using app.use(express.static(...)) in both your server.js and nimda.js, I'm going to guess that you're creating a new var app = express() in each file (which is something we want to avoid).

  3. I don't recommend having your static assets split into 2 different locations like you have pictured unless you have a very good reason to do so. Keeping them in one central location will help you reduce the amount of complexity in your app by ensuring that we don't even need a separate routes.js (aka nimda.js) file for the functionality you need at the moment.

therobinkim
  • 2,500
  • 14
  • 20
  • I should have had just given you the bounty points for your efforts in creating the code. Point 2 exactly pinpointed the problem when I know how vague my question was. All three points are lovely. Great job, man. Thanks! – Aakash Verma Jan 18 '18 at 20:08
0

If you are using Express, you dont have to handle requests to static content at all. Express will automatically return your statics. Just use path to router and folder structure. Such as

app.use('/my_statics',express.static(__dirname + "/public"));

if you have a.css at /public/assets/css/a.css below works

http://example.com/my_statics/assets/css/a.css

if you have b.html at /public/assets/b.html below works

http://example.com/my_statics/assets/b.html

EDIT: I built a similar setup in for my sideproject DataEndpoints. Check app.js for static and router setup. Also check routers folder to see how to handle, you may wanna look under views folder to how to set static file links

scetiner
  • 361
  • 3
  • 9
  • That's not the issue. It's just that when I set the static folder in route file `abc.js` and when I'm at that route say [http://example.com/abc](), it doesn't serve the static files – Aakash Verma Jan 16 '18 at 02:19
  • why dont you register your static files to the root express object, setting statics to a express.router object is not a proper way I think – scetiner Jan 16 '18 at 07:56
  • Can you please demonstrate that? I am open any valid and reliable solution. – Aakash Verma Jan 16 '18 at 18:05