docs/quickstart.org
226 lines · 7028 bytes
15 symbols in this file
Two commandsWhat init createdAdapting it to org files you already haveSOURCE is the URL rootCommon layoutsOUTPUT can live inside the sourceWhere config and templates goA worked exampleWrite a pageControl the URLKeep something unfinished out of the buildChange the designAdd a blog indexBuild for realNext
1#+TITLE: Quick start
2#+DESCRIPTION: A working site in two commands, then your own writing, then your own design.
3#+LEDE: Five minutes from nothing to a site that reloads as you type.
4
5* Two commands
6
7#+BEGIN_SRC sh
8orgo init my-site
9orgo serve my-site -o _site
10#+END_SRC
11
12Open [[http://127.0.0.1:3000][127.0.0.1:3000]]. Edit =my-site/index.org= in your editor, save, and the page reloads
13on its own.
14
15=init= writes only files that do not already exist, so running it inside a directory that
16already has content is safe and additive.
17
18** What init created
19
20#+BEGIN_EXAMPLE
21my-site/
22 orgo.toml every setting, commented — all at their defaults but `theme`
23 index.org the home page
24 blog/first-post.org a post, to show the collection working
25 templates/
26 base.html the page layout — edit this
27 list.html the blog index
28 tags.html the tag index
29 feed.xml an RSS feed
30#+END_EXAMPLE
31
32* Adapting it to org files you already have
33
34You do not need =init=, a config file, or templates. Every command takes the same two
35paths:
36
37#+BEGIN_SRC sh
38orgo serve <SOURCE> -o <OUTPUT>
39#+END_SRC
40
41** SOURCE is the URL root
42
43This is the one thing worth getting right, and it is not "the project directory" — it is
44*the directory whose contents should sit at the top of your site*. A file at
45=SOURCE/blog/post.org= is published at =/blog/post.html=.
46
47So if your writing lives in a =content/= subdirectory, point at =content/=, not at the
48repository around it:
49
50#+BEGIN_SRC sh
51cd ~/my-site
52orgo serve content -o _site # → /blog/post.html
53#+END_SRC
54
55Pointing one level too high still builds, which is what makes it worth saying out loud.
56It just builds the wrong site:
57
58#+BEGIN_SRC sh
59orgo serve . -o _site # → /content/blog/post.html
60#+END_SRC
61
62Every URL gains a =/content/= prefix, and every non-org file in the repository —
63=README.md=, build scripts, licence files — is copied into the output as a site asset.
64If you see either symptom, you picked the directory above the one you meant.
65
66** Common layouts
67
68| Your files | Command |
69|------------+---------|
70| =~/notes/*.org= | =orgo serve ~/notes -o /tmp/notes-site= |
71| =my-site/content/**/*.org= | =cd my-site && orgo serve content -o _site= |
72| =my-site/*.org= at the top level | =cd my-site && orgo serve . -o _site= |
73| Org files scattered in a code repo | Do not. Copy or symlink the ones you publish into one directory. |
74
75** OUTPUT can live inside the source
76
77=orgo serve . -o _site= is fine: the output directory is recognised and skipped, so
78the build never copies its own output back into itself. Nothing dot-prefixed is published
79either, so =.git= stays out of a site built from a repository root.
80
81** Where config and templates go
82
83Both live in the *source* directory — =SOURCE/orgo.toml= and =SOURCE/templates/= — and
84neither is published. If you would rather keep the config elsewhere, name it:
85
86#+BEGIN_SRC sh
87orgo serve content -o _site --config config/orgo.toml
88#+END_SRC
89
90** A worked example
91
92A repository laid out as =content/= (org files), =theme/= (unrelated), =build.py=:
93
94#+BEGIN_SRC sh
95cd ~/my-site
96
97# What is actually in there, before trusting anything with it.
98orgo audit content
99
100# Build it somewhere disposable and look.
101orgo serve content -o /tmp/preview
102
103# Happy with it? Build for real, failing on broken links.
104orgo build content -o _site --strict
105#+END_SRC
106
107The audit reports which org constructs appear, how often, and whether each is supported —
108names, counts and line numbers only, never your text. See
109[[file:guide/09-auditing.org][Auditing a corpus]].
110
111Nothing in your files has to change. With no config you get a complete site: a built-in
112layout, navigation across your top-level pages, and syntax highlighting.
113
114* Write a page
115
116Any =.org= file under the source directory becomes a page at the matching path.
117=notes/rust/borrowing.org= becomes =notes/rust/borrowing.html=.
118
119#+BEGIN_SRC org
120,#+TITLE: Borrowing
121,#+DATE: <2026-02-02 Mon>
122,#+FILETAGS: :rust:notes:
123,#+DESCRIPTION: How the borrow checker thinks about lifetimes.
124
125An opening paragraph, which becomes the excerpt in listings when there is no
126description.
127
128,* A heading
129
130Ordinary org: *bold*, /italic/, ~code~, [[https://orgmode.org][links]], and lists.
131
132,#+BEGIN_SRC rust
133fn main() {}
134,#+END_SRC
135#+END_SRC
136
137The keywords are all optional. =#+TITLE:= names the page, =#+DATE:= orders it in
138listings, =#+FILETAGS:= groups it on tag pages, and =#+DESCRIPTION:= is its summary.
139
140** Control the URL
141
142By default the filename decides the URL. =#+SLUG:= overrides it, which is how a
143date-prefixed filename becomes a clean address:
144
145#+BEGIN_SRC org
146,#+TITLE: Borrowing
147,#+SLUG: borrowing-explained
148#+END_SRC
149
150=2026-02-02-borrowing.org= now publishes as =borrowing-explained.html=.
151
152** Keep something unfinished out of the build
153
154#+BEGIN_SRC org
155,#+DRAFT: t
156#+END_SRC
157
158The page is not written, and does not appear in listings or navigation. Preview it while
159you work with =--drafts=:
160
161#+BEGIN_SRC sh
162orgo serve my-site -o _site --drafts
163#+END_SRC
164
165* Change the design
166
167Everything visual lives in =templates/base.html=. It is an ordinary
168[[https://docs.rs/minijinja][minijinja]] (Jinja2) template, and replacing it replaces the
169whole layout:
170
171#+BEGIN_SRC html
172<!DOCTYPE html>
173<html lang="{{ site.language }}">
174<head>
175 <meta charset="utf-8">
176 <title>{{ page.title }} — {{ site.title }}</title>
177 <link rel="stylesheet" href="{{ root }}style.css">
178</head>
179<body>
180 <nav>{% for item in nav %}<a href="{{ item.url }}">{{ item.title }}</a>{% endfor %}</nav>
181 <h1>{{ page.title }}</h1>
182 {{ body | safe }}
183</body>
184</html>
185#+END_SRC
186
187=root= is the =../= prefix back to the site root, so the same template works at any
188depth. Any other file in the source directory — =style.css=, images, fonts — is copied to
189the output untouched.
190
191Editing a template rebuilds every page that uses it, so the browser reloads while you are
192still looking at it. The full list of variables is in [[file:guide/04-templates.org][Templates]].
193
194* Add a blog index
195
196Listing pages have no source file; they are declared in =orgo.toml=:
197
198#+BEGIN_SRC toml
199[[collections]]
200source = "blog"
201output = "blog/index.html"
202template = "list.html"
203title = "Blog"
204sort = "date"
205order = "desc"
206nav = true
207#+END_SRC
208
209That is also how you get tag pages, pagination and an RSS feed — same mechanism, more
210settings. See [[file:guide/03-collections.org][Collections]].
211
212* Build for real
213
214#+BEGIN_SRC sh
215orgo build my-site -o _site --strict
216#+END_SRC
217
218=--strict= turns broken internal links and parse diagnostics into a non-zero exit, which
219is what you want in CI. Deployment is just copying =_site= somewhere; see
220[[file:guide/10-deploying.org][Deploying]].
221
222* Next
223
224- [[file:guide/01-cli.org][Command reference]] — every command and flag.
225- [[file:guide/02-configuration.org][Configuration]] — every setting in =orgo.toml=.
226- [[file:guide/05-org-support.org][Org support]] — exactly which org syntax is handled.