ntropy site turns the vault into a static website: a set of files any
web host serves, and that a browser opens straight from disk, no server
needed. The pages take their look from a site theme; see
Themes.
Export and open
ntropy site -o ./public # every note
ntropy site -o ./public tag:public # only the notes a query selects
open "$(ntropy site -o ./public -p)" # export, then open the front page
-o is required. A non-empty output directory is refused unless you
pass --force, which empties it first. The optional query restricts the
exported notes; a link to a note outside the set stays plain text. -p
prints the path of index.html and nothing else. Without it, the
command ends with a report naming the directory, the page count, and the
warnings.
The output is plaintext, so writing it inside an encrypted vault prints a warning. Write it elsewhere.
What the site contains
The site mirrors the ways you reach a note in the vault:
- Every note is a page under
notes/. - The tag hierarchy is a tree of pages under
tags/, each listing the notes carrying the tag or any tag below it. - Every view becomes a tree under
views/, nested like its directory. A view overtagsis skipped, since the tag pages already are that view. - Images and files the notes link are copied under
files/, a linked directory with its tree. Links are relative, so the site works fromfile://and from any path on a host.
Every page carries:
- a sidebar with the views and the top-level tags, a drawer behind the menu button on a phone;
- breadcrumbs;
- an outline of the note's headings that follows your position while you scroll;
- a
#after every heading, shown when you hover or tab to it, whose address you can copy to link the section; - a light/dark/system switch that remembers your choice in the browser.
A note page ends with the notes that share the most tags with it, at most eight. Tags link to their pages wherever they appear, and note links point at the target's page.
Code blocks are highlighted in the browser for 72 languages, each page loading only the grammars its code needs. A fence language without one is an export warning, and the block stays plain.
The front page is the note named by [site] index in the vault config,
or a generated overview of the ten newest notes, the top-level tags, and
the views.
Shaping the navigation from frontmatter
A note shapes its place in the navigation through a site table in its
frontmatter, every key optional:
---
title: Basics
tags: [docs/start]
site:
index: true # this note is the landing page of docs/start
listing: false # true lists the group's contents below it
label: Getting Started # what the sidebar calls it (and its group)
order: 1 # its position; on a landing note, the group's
hidden: false # true keeps a note out of the sidebar and lists
related: false # no related notes under this page
template: splash # render with the theme's templates/splash.html
---
Inside a group, the entries with an order come first, then the notes
without one, newest first, then the child groups by name. A landing
note's title and body become its group's page, and links to the note go
there. The listing of what the group holds appears below it only when
the note asks for it. A hidden note keeps its page and stays searchable;
it just appears nowhere in the navigation.
Previous and next follow the sidebar's reading order across groups and sections, so a tag subtree with landing notes reads like a book. A link into another section is labelled "Previous chapter" or "Next chapter".
template names a template of the site theme that renders the note's
pages instead of the built-in page.html. That is how a landing page
gets a hero, or an impressum drops the sidebar. A name the theme has no
template for is a warning, and page.html is used.
The site table is never shown as a frontmatter field on the page.
The sidebar and the vault config
Where the sidebar starts, and what it holds, is the vault config's
business. root starts it at one tag or view group instead of the whole
vault, which is what a documentation site wants; exporting with a single
tag: query does the same without config. A [[site.nav]] table
assembles the sidebar by hand instead, and is then all of it:
[site]
root = "tags/docs" # the sidebar is the docs subtree
related = false # no related notes under the pages
[[site.nav]] # or: sections listed by hand
label = "Getting Started"
items = [
{ note = "01ARZ3NDEKTSV4RRFFQ69G5FAV" }, # a note, by ULID
{ label = "Gadgets", tag = "docs/start/gadgets" }, # a tag's subtree
]
[[site.nav]]
label = "Reference"
items = [
{ view = "by-status", group = "open" }, # one group of a view
{ view = "by-status" }, # a whole view
{ tags = true }, # the whole tag tree
{ label = "More", items = [ ] }, # a group made by hand
]
Every item takes an optional label, which wins over a landing note's.
An item that names something the export does not have is a warning and
is left out, so the site is still written. related = false drops the
related notes from every page, which suits a documentation tree whose
pages all share the same tags. A note's own site.related wins over it
either way.
The same table holds title (by default the vault directory's name),
index (the ULID of the front page's note), lang (the page language,
en by default), and theme, the site theme. A [site.vars] table is
free-form: ntropy reads nothing from it, and the theme's templates
receive it as vars. That is where a footer's copyright line or a row of header links
comes from. A date, time, or datetime in the table reaches the templates
as text in the form TOML writes it (2026-11-01,
2026-11-01T12:00:00+01:00).
Search
The search is a palette over the page, made for readers rather than for the query language. It runs in the browser over data exported with the site, so it works from disk.
| Key | Action |
|---|---|
/, Ctrl+K (Cmd+K on a Mac), or the header's search button |
Open the search |
| type | Search as you type |
| arrow keys | Move through the results |
Enter |
Open the selected result |
A word matches titles, tags, frontmatter values, and text, and two words
need both. tag:wis finds wisdome, and a matching tag or view page
appears above the notes. The typed terms of the
Query language still
narrow: tag:work and not status:done works, and text: is the same
regex as in the CLI.
Warnings
Warnings go to stderr, and the site is written anyway. --strict makes
them fail the exit code, which is what a build script wants. An export
warns about:
- a referenced file that is missing or lies outside the vault;
- a linked folder that has nothing to copy;
- a link to a file the export never copies (see below);
- a code fence whose language has no highlighting grammar;
- a link to a note outside the exported set;
- a link whose
#heading-idmatches no heading on the target's page; - a configured index note that is not exported;
- a
sitetable that is no mapping, or holds a key of the wrong type; - a
rootthat names no page; - a nav item the site cannot resolve;
- a
templatethe theme does not have.
Metadata the export leaves out of a linked folder, such as .DS_Store,
prints as a note: line instead, which --strict does not count.
Files an export never copies
Some files are never copied, whether a note links them directly or they sit in a linked folder or in the site theme, at any depth:
- note tools' configuration:
.ntropy,.ntropy-vault,.obsidian; - version control and its history:
.bzr,.fslckout,.git,.hg,.jj,.pijul,.svn,CVS,_darcs; - sync tools' state:
.dropbox.cache,.stfolder,.stversions; - trash:
$RECYCLE.BINand every name that starts with.Trash; - credentials:
.aws,.env,.gnupg,.netrc,.ssh; - file-manager metadata:
.DS_Store,Thumbs.db.
Names match in any letter case, except CVS, so a folder CVs is
copied. A linked folder also leaves out every hidden file and folder in
it; a hidden file that a note links by name is copied unless it is on
the list. A link to a listed file is a warning and keeps its text in the
page.
Notes the export leaves out are never copied either. A link to
all-notes/ or to a view's folder copies the files of the exported
notes only, and a link to another note's file keeps its text with a
warning. For this, every file directly in all-notes/ ending in .md
or .age, in any letter case, counts as a note.
The site is never copied into itself. An earlier render or site export stored inside the vault, though, is an ordinary folder, which a link to a folder holding it copies.
Only files inside the vault are copied. A file or folder that is a
symlink to somewhere else on the machine is left out with a warning,
wherever the symlink sits. That covers an asset folder like
assets -> ~/Pictures, and an all-notes/ that is itself a symlink,
whose notes still become pages but whose images and files beside them
are not copied. The rule has no exceptions, so copy such files into the
vault to have them in the site. A symlink that stays inside the vault
works as any other path.