krz/orgo

Lightning fast org-mode static site generator.

clone: git clone https://gitbay.org/krz/orgo.git

57bf33c26554f1e88965a824a72c363a81e4ba56

verified · cmc

author: Christian Cleberg <hello@cleberg.net> · 2026-08-11T06:58:33Z

docs: explain what the two path arguments mean

The quick start showed `serve my-site -o _site` straight out of `init` and never said
what either path was, so adapting it to org files you already have meant guessing.

SOURCE is the URL root, not "the project directory": SOURCE/blog/post.org publishes at
/blog/post.html. That matters because guessing wrong still *works*. Pointing at a
repository root instead of its content/ subdirectory builds every page one level deep —
/content/blog/post.html — and copies README.md, build scripts and licence files into the
site as assets. Verified both ways against a real 179-file repository: the content
directory gives the 179 pages at the right URLs, the repository root gives the same 179
pages at the wrong ones plus 19 files that are not content.

Documents the rule, both symptoms of getting it wrong, a table of common layouts, that
OUTPUT may live inside SOURCE, that config and templates live in SOURCE and are not
published, --config for keeping the config elsewhere, and a worked example that audits
before it builds.
 docs/guide/01-cli.org | 17 +++++++++++
 docs/quickstart.org   | 79 +++++++++++++++++++++++++++++++++++++++++++++------
 2 files changed, 87 insertions(+), 9 deletions(-)

diff --git a/docs/guide/01-cli.org b/docs/guide/01-cli.org
index e127de0..c8e9ab3 100644
--- a/docs/guide/01-cli.org
+++ b/docs/guide/01-cli.org
@@ -2,6 +2,23 @@
 #+DESCRIPTION: Every command and flag, and what each is actually for.
 #+LEDE: Six commands: build, serve, watch, audit, init, clean.
 
+* The two paths
+
+=build=, =serve= and =watch= all take the same pair:
+
+#+BEGIN_SRC sh
+org-ssg <command> <SOURCE> -o <OUTPUT>
+#+END_SRC
+
+*SOURCE is the URL root*, not "the project". =SOURCE/blog/post.org= is published at
+=/blog/post.html=, so if your writing lives in a =content/= subdirectory you point at
+=content/= and not at the repository around it. Choosing the directory above the one you
+meant still builds — it just prefixes every URL with that directory's name and copies
+your build scripts in as assets. [[file:../quickstart.org][Quick start]] works through it.
+
+*OUTPUT* may live inside the source; it is recognised and skipped, so a build never
+consumes its own output.
+
 * build
 
 #+BEGIN_SRC sh
diff --git a/docs/quickstart.org b/docs/quickstart.org
index 5830fe0..64ecc6a 100644
--- a/docs/quickstart.org
+++ b/docs/quickstart.org
@@ -29,27 +29,88 @@ my-site/
     feed.xml              an RSS feed
 #+END_EXAMPLE
 
-* Or skip all of that
+* Adapting it to org files you already have
 
-You do not need =init=, a config file, or templates. Point the builder at org files you
-already have:
+You do not need =init=, a config file, or templates. Every command takes the same two
+paths:
 
 #+BEGIN_SRC sh
-org-ssg build ~/notes -o _site
+org-ssg serve <SOURCE> -o <OUTPUT>
 #+END_SRC
 
-You get a complete site with a built-in layout, navigation across your top-level pages,
-and syntax highlighting. Nothing in your files has to change.
+** SOURCE is the URL root
 
-Before trusting it with a large collection, ask what it makes of your writing:
+This is the one thing worth getting right, and it is not "the project directory" — it is
+*the directory whose contents should sit at the top of your site*. A file at
+=SOURCE/blog/post.org= is published at =/blog/post.html=.
+
+So if your writing lives in a =content/= subdirectory, point at =content/=, not at the
+repository around it:
+
+#+BEGIN_SRC sh
+cd ~/my-site
+org-ssg serve content -o _site        # → /blog/post.html
+#+END_SRC
+
+Pointing one level too high still builds, which is what makes it worth saying out loud.
+It just builds the wrong site:
+
+#+BEGIN_SRC sh
+org-ssg serve . -o _site              # → /content/blog/post.html
+#+END_SRC
+
+Every URL gains a =/content/= prefix, and every non-org file in the repository —
+=README.md=, build scripts, licence files — is copied into the output as a site asset.
+If you see either symptom, you picked the directory above the one you meant.
+
+** Common layouts
+
+| Your files | Command |
+|------------+---------|
+| =~/notes/*.org= | =org-ssg serve ~/notes -o /tmp/notes-site= |
+| =my-site/content/**/*.org= | =cd my-site && org-ssg serve content -o _site= |
+| =my-site/*.org= at the top level | =cd my-site && org-ssg serve . -o _site= |
+| Org files scattered in a code repo | Do not. Copy or symlink the ones you publish into one directory. |
+
+** OUTPUT can live inside the source
+
+=org-ssg serve . -o _site= is fine: the output directory is recognised and skipped, so
+the build never copies its own output back into itself. Nothing dot-prefixed is published
+either, so =.git= stays out of a site built from a repository root.
+
+** Where config and templates go
+
+Both live in the *source* directory — =SOURCE/org-ssg.toml= and =SOURCE/templates/= — and
+neither is published. If you would rather keep the config elsewhere, name it:
+
+#+BEGIN_SRC sh
+org-ssg serve content -o _site --config config/org-ssg.toml
+#+END_SRC
+
+** A worked example
+
+A repository laid out as =content/= (org files), =theme/= (unrelated), =build.py=:
 
 #+BEGIN_SRC sh
-org-ssg audit ~/notes
+cd ~/my-site
+
+# What is actually in there, before trusting anything with it.
+org-ssg audit content
+
+# Build it somewhere disposable and look.
+org-ssg serve content -o /tmp/preview
+
+# Happy with it? Build for real, failing on broken links.
+org-ssg build content -o _site --strict
 #+END_SRC
 
-That reports which org constructs appear, how often, and whether each is supported. See
+The audit reports which org constructs appear, how often, and whether each is supported —
+names, counts and line numbers only, never your text. See
 [[file:guide/09-auditing.org][Auditing a corpus]].
 
+Nothing in your files has to change. With no config you get a complete site: a built-in
+layout, navigation across your top-level pages, and syntax highlighting.
+
 * Write a page
 
 Any =.org= file under the source directory becomes a page at the matching path.