Introduction
We've been building up our subReddit app over the past few discussions, and we're going to continue building it up here. As we've seen previously, we can "embed" javascript code into an html page using ejs files and syntax. And we have defined some of the differences between html pages, and ejs page:
- - html files are rendered on the client side which means they can utilize external files such as css, and Js files.
- - ejs files however, are rendered on the server side. This means that they can NOT access external css or Js files. But they can process Js internally within the html file itself, and we'll use this capability to render our output.
So when we generate our code with an ejs file, which is rendered on the server side, we no longer have access to our other files, such style sheets (css), Js files, images, or any other files that are considered "local static files". These are considered static because the sever can't do anything with them. They are all rendered on the client side.
But what if we want to be able to access these files? Luckily, there is a way. There is a method, in express, that is considered "middle ware", and it's called .static. This method functions off of app.use.
Now, app.use is different that the app.get that we've been using. app.get runs after a specific request to the server, and renders a specific ejs file. app.use on the other hand, will run every single time there is a request to the server. And because it is always listening for a request, our "static" files always available. Once again, this is an example of something called "middle ware".
The basic syntax for this is :
- app.use(express.static( 'public' ) )
This "public" directory becomes the directory that holds our "static Files". It does NOT have to be called public. You can name it anything you like, as long as the correct directory is linked in our index.js file. Also, this directory must reside within our apps root directory.
More information on serving static files in Express can be found here
Setting it Up
So we have the basics, now let's get it set up. First, we're going to modify our index.js file, by adding [ app.use ].
Now if we remember from our previous discussions we utilized __dirname to define our path for our views directory. Technically, [ __dirname ] is always the directory in which the currently executing script resides. So the reason we used this is so that we could reference the views directory from any directory within our app structure. We're going to incorporate the same process to reference our "static files directory".
So we'll add the following to our index.js file:
- app.use(express.static(path.join(__dirname, 'assets')))
Notice that we have named our directory for holding our "static" files, assets.
Next, we're going to add our new assets directory to our current directory structure.
*note: we can create separate directories for our css, js, imgs, or whatever files we need, but we would then have to make several entries into our index.js file, referencing all of these separate directories. A better way is to create a directory, that will have sub-directories for each static type, such as css, js, or whatever. This way we only need one entry in our index,js referencing the "root", or "parent" "static files directory".
So we create our static files "root directory" in the root directory for our app. Then we create our "static" sub-directories within this "parent static files" directory. When combined with our directory structure that we've already created, we get this:
Directory Structure
Here is our directory structure:
express
assets
node_modules
views
subReddit.ejs
notFound.ejs
index.js
package-lock.json
package.json
As you can see, we've created "static sub-directories" to hold our "static files", in an organized manner.
The next thing we need to do is to "link" our assets to our ejs file. We do this in the head section of our ejs file by adding a "link" element. One thing to understand here is that when we added:
- app.use(express.static(path.join(__dirname, 'assets')))
to our index.js, we are "serving" our entire "static files directory", and ALL of it's contents, to our app. So all of our "static files" can be accessed by using standard directory "path" declarations. So to refer to our base "static files directory", the path would be "/". But to refer say to the css files, the path would be /css/cssFileName.
So, in the head section of our subReddit.ejs file, we are going to add:
- <link rel="stylesheet" href="/css/styles.css">
Lastly, we're going to add a simple body style to our css file that just changes the body background color. And now if we run our subReddit.ejs app from our localhost, we'll see that indeed, the page background color has changed, showing that our process is working. Also if we type in the address bar of our browser:
- http://localhose:3000/css/styles.css
we'll see our contents of our styles.css "static" file, once again, showing that the process is working.
In Summary
To summarize:
- - We modified our index.js file to set a path for our "static assets directory"
- - app.use(express.static(path.join(__dirname, 'assets')))
- - We modified our folder structure to include our "static files directories"
assets
- - We added our "Link" the the head section of our subReddit.ejs file.
- <link rel="stylesheet" href="/css/styles.css">
Three simple steps to make our "static assets" available to our "server-side" ejs file.