Are you looking to build a website that is easily updatable/maintainable? Do you hate Wordpress and other bloated website platforms? Do you understand that simple websites do not require the use of a SPA framework? Do you still want to needlessly optimize your site to the nth degree, and get a 100 on Google PageSpeed? Well this is the project for you.
You can see a working demo of this project here.
So you're ready to build an awesome new website. Good, this is the place to be. This project helps you setup a site using Bootstrap 4, TypeScript, SASS, Handlebars, NodeJS/Express, Markdown, and a few optimizations for serving webp, AMP, bundling js/css, inlining js/css, and helping with SEO/Structured Data.
The site has the following directories
build
: Contains some build scripts for running the serverpublic
: Where all the public assets go. Note that the CSS and JS folders will be created automatically by the build process.scss
: Where you put all your SASS files.includes
: Used for global styles, bootstrap overrides, etclayouts
: Used for main layout stylespartials
: Used for partial layout styles
server
: Contains all the files necessary to run the serverblogs
: Put all your blog markdown hereconfig
: Stores global configuration for the serverhelpers
: Stores handlebars helperslog
: A simple logging utility classmiddleware
: Has files for CORS, errors, setting meta context, serving webp, handling redirects, and parsing/compiling Handlebars filesroutes
: Defines all the pages for the sitetypings
: Adds some types to the projectutils
: Has utility methods and a caching class
ts
: Where you put all your TS files.layouts
: Used for TS scripts that can be included in many pagespartials
: Used for TS scripts that need only be included in specific pages
views
: Where you put all your Handlebars files for your pages.layouts
: Used for Handlebars layout pagespartials
: Used for Handlebars partials
Here are a few cool things this project is designed to do.
The express server can serve webp assets alongside pngs and jpgs. So in your html you might have <img src="path/to/image.jpg">
, and if the server finds a file path/to/image.webp
it will serve it instead.
This project comes with blog scaffolding for you, which includes an AMP template. If you run the project and go to any blog post, you can see the AMP version by visiting the blog <url>/amp
.
The build process includes a few custom scripts in the build
directory. There is a minify
script that will compile and minify TypeScript files and output to a public JS directory. There is also a lib
build script that will build 3rd-party libraries for you and output to a public/js/lib.js
. By default it builds bootstrap and its dependencies (jQuery, popper, etc). The last script is the scss
script. This will compile your SASS files (in the scss
directory) per-page. So you don't have to worry about including unnecessary css per page, and you also don't have issues with overriding styles.
When this project was created, the intention was to perform all optimizations to make the site as fast as possible while allowing for ease of deployment. The express server is designed to allow you to declare styles and scripts that you with to inline with your HTML pages. If you put the following in a .hbs page:
<!-- Remove Script -->
<script src="/public/lib/lib.js"></script>
<!-- /Remove Script -->
<!-- Remove Style -->
<link rel="stylesheet" href="/public/css/about.css">
<!-- /Remove Style -->
There is a method that runs after the Handlebars page is rendered. It pulls out the scripts and styles, concatenates them, and then puts them in 1 style or script tag. After that it caches the pages to save some time with multiple requests. Of course there are times when you don't want to concatenate the styles/scripts. You can do so using an "ignore" attribute like so:
<link ignore="true" href="https://fonts.googleapis.com/css?family=Lato:100,300,400,700,900" rel="stylesheet">
There is a simple reading time calculator for blog posts, which can help entice users to read a post knowing that it should only take 3-5 minutes.
This project has example structured data that you can replace with your own properties. There is structured data for an Organization, Breadscrumbs, and Articles. It's also designed to allow you to specify title, description, image, and video meta information for every page when you add a new route.
You will notice in server/blogs
there are blog markdown files. They include some front matter that has information about the blog. The server interprets this and sets the right context when rendering a page.
The only requirements to build this project are Node and npm.
Setting up this project is incredibly simple:
npm install
npm run lib
npm run dev
Then navigate to http://localhost:3000/ and see a sample mini-site built out for you.
NOTE: You only need to run npm run lib
whenever you change the lib.js
in /build
, or when one of the libraries updates.
When you want to add a page, there are a couple things to do:
- Create a new Handlebars file in
views
- Create a new route in
server/routes
- Add the route to the Express router in
server/routes/index.ts
build
: Builds everything (srver, client, lib, and sass)clean
: Cleans the compiled filesdev
: Run this in dev mode, watches files and starts a dev serverformat
: Runsprettier
to format all the TS files according to theprettier.config.js
lint
: Runstslint
using thetslint.json
, also uses some addons fromtslint-microsoft-contrib
start
: Starts node server
This site can be deployed on AWS, GCP, Azure, Heroku, etc. I didn't include any deployment instructions, so you will have to figure that part out on your own.
- Express - Used to render pages and serve assets
- Bootstrap 4 - Used for the easy layout, duh
- Handlebars - Used to render pages and apply simple context
- Remarkable - Used for markdown rendering on blog pages
- TypeScript - Used to allow you to write simple scripts in TypeScript that will be included with your pages
- SASS - CSS precompiler
You can see a working demo of this project here.
- William Johnston - Initial work - wjohnsto
- Jesse Li - veggiedefender
This project is licensed under the MIT License - see the LICENSE.md file for details