Getting things prepared:
deno task serve
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
jsx
and these can be referenced from any content or layout file._includes
_data
data
scope). i.e. it is site.navigation
not site.data.navigation
._includes
scripts
directory here contains files that are bundled into the site javascript using esbuild.styles
directory here contains files that are bundled into the site css using sass.articles
, changelogs
, guides
/documentation/[collection]/[slug]/
.assets
uploads
ye_olde_images
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:
{% comp "Notice", info_type: "note" %}
Two genera of geese are only tentatively placed in the Anserinae; they may belong to the shelducks or form a subfamily on their own
{% endcomp %}
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="https://github.com/CloudCannon/platform-documentation/raw/main/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).