Frontend Bundling (CSS/JS/etc.)
Bridgetown comes with a default configuration of Webpack to handle building and exporting frontend assets such as JavaScript/TypeScript/etc., CSS/Sass/etc., and related files that are imported through Webpack (fonts, icons, etc.)
The default configuration is defined in config/webpack.defaults.js
. You can add or override config options in webpack.config.js
.
The default configuration can be updated to the latest version provided by Bridgetown using the webpack
CLI tool:
bundle exec bridgetown webpack update
All options provided by the webpack
CLI tool can be viewed by running:
bundle exec bridgetown webpack
Files to be processed by Webpack are placed in the top-level frontend
folder within your site root. This folder is entirely separate from the Bridgetown source folder where your content, templates, plugins, etc. live. However, using relative paths you can reference files from Webpack that live in the source folder (so you could keep CSS partials alongside Liquid templates, for example).
Bridgetown uses Yarn to install and manage frontend NPM-based packages and dependencies. Gem-based plugins can instruct Bridgetown to add a related NPM package whenever Bridgetown first loads the gem.
Table of Contents
- JavaScript
- CSS
- Linking to the Output Bundles
- Additional Bundled Assets (Fonts, Images)
- Multiple Entry Points
JavaScript
The starting place for JavaScript code lives at ./frontend/javascript/index.js
. Here you can write your custom functionality, use import
statements to pull in other modules or external packages, and so forth. This is also where you’d import all relevant CSS. (By default it imports ./frontend/styles/index.scss
.)
Because Bridgetown utilizes standard Webpack functionality, you can trick out your JavaScript setup with additional language enhancements like TypeScript or add well-known frameworks like LitElement, Stimulus, Alpine, React, Vue, and many others. For example, to add slick page transitions to your website using Swup, you would simply run:
yarn add swup
And then update ./frontend/javascript/index.js
with:
import Swup from "swup"
const swup = new Swup()
And the update your HTML layout according to the Swup install guide.
CSS
By default Bridgetown uses Sass, a pre-processor for CSS; but you can pass --use-postcss
to bridgetown new
to setup PostCSS
which is popular with the Webpack community.
Sass
The starting place for CSS code lives at frontend/styles/index.scss
.
Importing common CSS frameworks such as Bootstrap, Foundation, Bulma and so forth is often as easy as running:
$ yarn add name-of-css-framework
And then adding:
@import "~css-framework/css-framework";
to index.scss
. For example, to add Bulma which is a modern CSS-only (no JavaScript) framework built around Flexbox, you’d simply run:
$ yarn add bulma
and then add:
@import "~bulma/bulma";
to index.scss
.
PostCSS
You can run bridgetown new mysite --use-postcss
to configure your site with PostCSS right out-of-the-box.
The default PostCSS
config is largely empty so you can set it up as per your preference. The only two plugins included by default are postcss-flexbugs-fixes
and postcss-preset-env
.
If you’d like to use Sass
with PostCSS
, you’ll need to install a plugin for it:
$ yarn add @csstools/postcss-sass
And then include it at the top of the plugins
object in postcss.config.js
:
module.exports = {
plugins: {
'@csstools/postcss-sass': {},
'postcss-flexbugs-fixes': {},
'postcss-preset-env': {
autoprefixer: {
flexbox: 'no-2009'
},
stage: 2
}
}
}
The popular TailwindCSS framework can be added to your project by following their setup guide for PostCSS.
Linking to the Output Bundles
Bridgetown’s default Webpack configuration is set up to place all compiled output into the _bridgetown
folder in your output
folder. Bridgetown knows when it regenerates a website not to touch anything in _bridgetown
as that comes solely from Webpack. It is recommended you do not use the site source folder to add anything to _bridgetown
as that will not get cleaned and updated by Bridgetown’s generation process across multiple builds.
To reference the compiled JS and CSS files from Webpack in your site template, simply add the webpack_path
Liquid tag or Ruby helper to your HTML <head>
. For example:
<link rel="stylesheet" href="{% webpack_path css %}" />
<script src="{% webpack_path js %}" defer></script>
This will automatically produce HTML tags that look something like this:
<link rel="stylesheet" href="/_bridgetown/static/css/all.6902d0bf80a552c79eaa.css"/>
<script src="/_bridgetown/static/js/all.a1286aad43064359dbc8.js" defer></script>
Additional Bundled Assets (Fonts, Images)
By default starting with Bridgetown 0.20, both fonts and images can be bundled through Webpack’s loaders. This means that, in CSS/JS files, you can reference fonts/images saved somewhere in the frontend
folder (or even from a package in node_modules
) and those will get transformed and copied over to output/_bridgetown
within an appropriate subfolder and with a hashed filename (aka photo.jpg
would become photo-31d6cfe0d16ae931b73c59d7e0c089c0.jpg
).
There’s a catch with regard to how this works, because you’ll also want to be able to save files directly within src
that are accessible via standard relative URLs (so src/images/photo.jpg
is available at /images/photo.jpg
within the static output, no Webpack processing required).
So here’s what you’ll want to do:
- For any files saved inside of
src
, use server-relative paths. For example:background: url(/images/photo.jpg)
in a frontend CSS file would simply point to what is saved atsrc/images/photo.jpg
. - For any files saved inside of
frontend
, use filesystem-relative paths. For example:background: url("../images/photo.jpg")
infrontend/styles/index.css
will look forfrontend/images/photo.jpg
. If the file can’t be found, Webpack will throw an error. - For a Node package file, use Webpack’s special
~
character, aka~package-name/path/to/image.jpg
.
When bundling, Webpack will place image files (jpg, png, gif, svg) in output/_bridgetown/static/path/to/image.ext
and font files (woff, woff2, eot, ttf) in output/_bridgetown/static/fonts
. You can edit webpack.config.js
if you wish to change this default behavior.
You can also use the webpack_path
Liquid tag/Ruby helper to reference assets as well.
<img src="{% webpack_path images/folder/somefile.png %}" />
Multiple Entry Points
If you need to manage more than one Webpack bundle, you can add additional entry points to the webpack.config.js
file (in Bridgetown 0.20 and above). For example:
config.entry.somethingElse = "./frontend/otherscript/something_else.js"
Then simply reference the entry point filename via webpack_path
wherever you’d like to load it in your HTML:
<script src="{% webpack_path something_else.js %}"></script>