So, I’ve a basic express setup as shown below:
const path = require("path"); const express = require("express"); const app = express(); app.use(express.static(path.join(__dirname, "public"))); app.get("/", (req, res) => { res.send("Home Page"); }); app.get("/about", (req, res) => { res.send("About Page"); }); app.listen(3000, () => { console.log("Server listening on PORT 3000"); });
In the code above app.use()
middleware will be executed for every request because the default path for app.use()
is /
.
Now express.static()
will be serving the public
directory, so if I go to /
route I will see the contents of the index.html
file and the app.get("/")
middleware will not get executed.
But when I go to /about
, I see the contents sent from app.get("/about")
. This is what I don’t understand because according to docs it calls next()
only when the file is not found, but when it is found the request stops there.
So, when I navigate to /about
, app.use()
will be the first to get executed and it will find index.html
file and should render that, but instead it calls next
and the get
handler for about gets executed. WHY?
I am not very clear how static assets are being served, I guess when I go to /about
it is not actually looking for index.html
file but then what file is it looking for?
Advertisement
Answer
The root argument specifies the root directory from which to serve static assets. The function determines the file to serve by combining req.url with the provided root directory.
So, app.use(express.static(path.join(__dirname, "public")))
serves the public
directory.
Visiting /
route
Remember the file to serve will be determined by combining req.url
with root. So, in this case req.url
is /
and root is public
. So express will try to serve public/index.html
, where index.html
is the default, if no file is specified explicitly.
Sends the specified directory index file. Set to false to disable directory indexing.
This file will be found and will be rendered and the request ends there, so the get handler for /
is not executed.
You can set the index
property to false
and then express will not look for index.html
file by default.
So, setting app.use(express.static(path.join(__dirname, "public"), { index: false }))
will make express to not look for index.html
file by default and now if you visit /
route, the get
handler for /
will be executed.
Visiting /about
route
This time req.url
is /about
, so express will try to serve public/about/index.html
, which will not be found and therefore it calls next()
and the get handler for /about
gets executed.
Visiting /about.html
route
This time req.url
is /about.html
, so express will try to serve public/about.html
which if found will be rendered else next()
will be called.