Bundles are the main way to collect CSS and JavaScript files, concatenate and minify them, copy referenced assets to the output, and inject <link> and <script> tags into your pages.
All bundle configuration is done in config.scriban using the with bundle block.
with bundle
css "/css/main.scss"
js "/js/main.js"
concat = true
minify = true
end
The default bundle (internally named "site") applies to all pages unless a page specifies a different bundle in its front matter.
The css function adds a stylesheet to the bundle:
with bundle
css "/css/main.scss"
end
With a resource handle (see Resources module):
with bundle
$bootstrap = resource "npm:bootstrap" "5.3.8"
css $bootstrap "/dist/css/bootstrap.min.css"
end
SCSS files (.scss) are automatically compiled to CSS by the SCSS module before bundling.
The js function adds a script to the bundle:
with bundle
js "/js/main.js"
end
With a resource handle:
with bundle
$bootstrap = resource "npm:bootstrap" "5.3.8"
js $bootstrap "/dist/js/bootstrap.bundle.min.js"
end
By default, all <script> tags are emitted with the defer attribute. You can change this by passing an explicit mode as the last argument:
with bundle
js "/js/main.js" # defer (default)
js "/js/analytics.js" "async" # async
js "/js/critical.js" "" # no attribute (blocking)
end
When concat = true, scripts with different modes are concatenated into separate output files (e.g. site-defer.js, site-async.js).
contentThe content function copies files from a resource or your site to the output. Content files are never concatenated or minified — they are raw file copies.
with bundle
# Copy from a resource using a wildcard
$icons = resource "npm:bootstrap-icons" "1.13.1"
content $icons "/font/fonts/bootstrap-icons.*" "/fonts/"
# Copy from your site
content "/img/*" "/img/"
end
When the source path contains *, the destination must end with / (it is treated as a folder).
A common pattern is to download npm packages with the resource function and use them in bundles. You can store resource handles as variables inside the with bundle block:
with bundle
# Download resources (cached locally)
bootstrap = resource "npm:bootstrap" "5.3.8"
bootstrap_icons = resource "npm:bootstrap-icons" "1.13.1"
tocbot = resource "npm:tocbot" "4.36.4"
# Add SCSS include paths from resources
scss.includes.add bootstrap.path + "/scss"
scss.includes.add bootstrap_icons.path + "/font"
# Add CSS files from resources
css tocbot "/dist/tocbot.css"
css "/css/main.scss"
# Add JS files from resources
js bootstrap "/dist/js/bootstrap.bundle.min.js"
js tocbot "/dist/tocbot.min.js"
js "/js/main.js"
# Copy font files from a resource to the output
content bootstrap_icons "/font/fonts/bootstrap-icons.*" "/fonts/"
concat = true
minify = true
end
Create a named bundle for pages that need different assets:
with bundle "docs"
css "/css/docs.scss"
end
Select it in page front matter:
bundle: docs
Note: Only bundles that are actually referenced by at least one page are processed during the build. A bundle defined in
config.scribanbut not used by any page is ignored.
The bundle plugin automatically registers a built-in include that outputs <link> and <script> tags into the <head> of your pages:
_builtins/bundle.sbn-html
CSS <link> tags are emitted first, then <script> tags. For JavaScript, the mode attribute is applied (e.g. defer, async). Content-type entries (file copies) do not produce any HTML tags.
Most themes include this automatically. If your theme does not, add it from config.scriban:
site.html.head.includes.add "_builtins/bundle.sbn-html"
All options are set inside the with bundle block in config.scriban:
| Option | Type | Default | Description |
|---|---|---|---|
concat |
bool | false |
Concatenate all CSS/JS files into a single file per type and mode |
minify |
bool | false |
Minify each file individually (see Minifier module) |
minify_ext |
string | ".min" |
Extension inserted before file type when minifying (e.g. .min.js) |
minifier |
string | null |
Name of the minifier to use; null picks the first registered minifier |
url_dest.js |
string | "/js/" |
Output folder for JavaScript files |
url_dest.css |
string | "/css/" |
Output folder for CSS files |
Override output folders:
with bundle
url_dest.js = "/assets/js/"
url_dest.css = "/assets/css/"
end
When a bundle is processed, the following steps happen in order:
* in their path are expanded to individual files.minify = true, each file is minified individually. Files ending with .min.js or .min.css are skipped (see Minifier module).sourceMappingURL comments are stripped from all files.concat = true, files are merged per type and mode into output files named {bundle}.{type} (e.g. site.css, site-defer.js).Note: During CSS concatenation,
@charsetrules are deduplicated — only the first one is kept at the top of the output.