Getting things prepared:
- Install Deno. Either the curl shell or brew.
- Serve the website locally:
deno task serve
- Build the static website:
deno task build
Deno doesn't have a specific step for installing dependencies, instead the first run will download and cache what is needed.
_components
- Components are a primary concept in Lume, can be written in many different syntaxes, and referenced from other syntaxes.
In this repo, we have components written injsx
and these can be referenced from any content or layout file.
Generally, anything written in here will be used as a snippet inside our content files. Otherwise put it in_includes
- Components are a primary concept in Lume, can be written in many different syntaxes, and referenced from other syntaxes.
_data
- A data directory, very similar to Jekyll or Eleventy. Files in this directory are available on the global scope (not a
data
scope). i.e. it issite.navigation
notsite.data.navigation
.
- A data directory, very similar to Jekyll or Eleventy. Files in this directory are available on the global scope (not a
_includes
- An includes directory. Various nunjucks templates live in here for building the site layouts.
Thescripts
directory here contains files that are bundled into the site javascript using esbuild.
Thestyles
directory here contains files that are bundled into the site css using sass.
- An includes directory. Various nunjucks templates live in here for building the site layouts.
articles
,changelogs
,guides
- Our main collections, output at
/documentation/[collection]/[slug]/
.
Written as MDX to enable nicer snippets, otherwise standard markdown.
- Our main collections, output at
assets
- Files that are part of the site/layouts. SCSS and JS files here will be processed through the appropriate bundler. Other files will not be passed through.
Most SVGs in here will likely be inlined into the site. More on that below.
- Files that are part of the site/layouts. SCSS and JS files here will be processed through the appropriate bundler. Other files will not be passed through.
uploads
- Our directory for CMS-uploaded files.
ye_olde_images
- All images migrated from the old docs codebase, flattened to images that are actually referenced in the content.
Lume is configured in the _config.ts
file. This is where we import and define all of our plugins
Components are available under the comp
namespace wherever you are.
In a njk
file:
In an mdx
file:
<comp.Notice info_type="info">
Alternatively, drag and drop files into the File Browser.
</comp.Notice>
In a jsx
file:
export default function ({ comp }) {
return (
<comp.Notice info_type="info">
Alternatively, drag and drop files into the File Browser.
</comp.Notice>
);
}
A good sample is _components/DocsImage.jsx
:
Usage:
<comp.DocsImage path="/img.png" alt="Alt text" type="screenshot" />
export default function ({comp, type, path, alt}, helpers) {
let imageClass = "c-docs-image";
if (type === "screenshot") {
imageClass += " c-docs-image--type-screenshot";
}
return (
<div className="c-docs-image__wrapper">
<div className={imageClass}>
<img className="c-docs-image__image" src={helpers.url(path)} alt={alt} loading="lazy" />
</div>
</div>
);
}
The first argument is an object that contains the comp
namespace, as well as any props that were passed to the component. If it is a component that wraps markdown, that content will be available as children
in this object.
The second argument contains any helpers on the site — e.g. the filters that would be available for a njk
template. Where the layout might do {{ title | md }}
, your JSX component can do { helpers.md(title) }
Lume allows us to write rich postprocessing using a DOM as part of the SSG, for example to add hash links to all of our headings we can write:
site.process([".html"], (page) => {
page.document.querySelectorAll('h1').forEach((el) => {
el.addAttribute("id", slugify(el.innerText));
}
});
The inline
attribute can be added to an img
tag, and the build process will convert that to an inline image rather than a URL. If the path leads to an SVG, the img
tag will be turned into an svg
one.
This lets us keep our SVG icons in a sane location within assets, but inline them as needed without the indirection of an include. e.g.:
<img src="/assets/img/arrow.svg" class="my-class-name" inline>
becomes:
<svg class="my-class-name" width="8" height="12" viewBox="0 0 8 12" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M0.589844 1.41L5.16984 6L0.589844 10.59L1.99984 12L7.99984 6L1.99984 0L0.589844 1.41Z" fill="#393939"/>
</svg>
The esbuild flow on this website utilizes Deno rather than Node for module resolution, so Deno packages should be imported by URL. Node packages can be imported by their npm name & version, prefixed with npm:
. See _includes/scripts/alpine.js
:
import Alpine from 'npm:alpinejs@latest'
import intersect from 'npm:@alpinejs/intersect@latest'
These don't need to be added to a package.json
anywhere, Lume/Deno will fetch them on first run. (This repo should never have a package.json
in it).