krz/orgo

Lightning fast org-mode static site generator.

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

v0.20.1: docs/guide/08-workflow.org · raw

  1#+TITLE: Watching and serving
  2#+DESCRIPTION: The write-save-see loop, and what the development server does and does not do.
  3#+LEDE: Filesystem events, debounced rebuilds, and a browser that reloads itself.
  4
  5* serve
  6
  7#+BEGIN_SRC sh
  8orgo serve content -o _site
  9#+END_SRC
 10
 11Builds, watches, serves at [[http://127.0.0.1:3000][127.0.0.1:3000]], and reloads the
 12browser when a rebuild lands. This is the command to leave running while you write.
 13
 14Add =--drafts= to see work in progress, =--port= to move it, and =--host 0.0.0.0= to
 15reach it from another device.
 16
 17** It binds loopback deliberately
 18
 19A development server serves unreviewed drafts off your laptop. Exposing that to whatever
 20network you are on — a café, a conference, an office — should be something you ask for,
 21so the default is =127.0.0.1= and =--host= is the way out.
 22
 23** The reload script never reaches disk
 24
 25The script is injected into HTML *responses*, not into the built files. What you deploy
 26is the site as built, with no development machinery in it. If you are curious, compare a
 27served page with the file in your output directory.
 28
 29** How reload works
 30
 31The page carries the build generation it was rendered from, and asks the server "anything
 32newer than N?". The server holds that request open until there is, then answers — so a
 33reload is immediate rather than polled, but the mechanism is ordinary HTTP with no
 34WebSocket.
 35
 36Baking the generation into the page closes a race: if a rebuild lands between a page
 37being served and its first request going out, the server answers at once instead of the
 38tab sitting on stale content until your *next* edit.
 39
 40A reload only follows a *successful* rebuild. Reloading onto an unchanged page because
 41the build just failed tells you nothing — the error is already on your terminal.
 42
 43* watch
 44
 45#+BEGIN_SRC sh
 46orgo watch content -o _site
 47#+END_SRC
 48
 49The same rebuilding without the server, for when something else already serves the output.
 50
 51* What counts as a change
 52
 53Rebuilds are driven by OS filesystem events, so nothing happens while nothing happens.
 54The rule for what triggers one is deliberately *not* the rule the build uses to find
 55content — the question is "would this change the site?", not "is this a page?".
 56
 57*Triggers a rebuild:* any =.org= file, any asset, =orgo.toml=, and anything in the
 58templates directory. The last two are skipped by the build when looking for content, but
 59both change the output.
 60
 61*Does not:*
 62
 63- The output directory. Without this the build's own writes would raise events that
 64  trigger a rebuild, forever.
 65- Dot-directories. =.git= churns on every command, and rebuilding a site because git
 66  wrote an index lock would make watching useless in a repository.
 67- Editor scratch files: =file.org~=, =#file.org#=, =.#file.org=, =*.swp=, =*.tmp=. Emacs'
 68  backup files matter here — they do not start with a dot, so they would otherwise look
 69  exactly like content.
 70
 71* Debouncing
 72
 73Saving a file is rarely one event: an editor writes a temp file, renames it over the
 74original, and touches the directory. Events are collected for 120ms of quiet before a
 75rebuild starts, so one save is one rebuild.
 76
 77* Rebuild failures do not stop the session
 78
 79A build that fails prints the error and keeps watching. The usual cause is a half-saved
 80file, and the next keystroke fixes it. Nothing needs restarting.
 81
 82#+BEGIN_EXAMPLE
 83blog/post.org changed: build failed: parsing blog/post.org: ...
 84blog/post.org changed: 2 rendered, 180 cached
 85#+END_EXAMPLE
 86
 87* Where native watching is unavailable
 88
 89Some network and container filesystems have no event API. orgo falls back to polling
 90every two seconds and says so, rather than failing:
 91
 92#+BEGIN_EXAMPLE
 93note: native file watching unavailable (...); polling every 2s
 94#+END_EXAMPLE
 95
 96* Serving details
 97
 98- =/= and any directory URL serve =index.html=.
 99- Content types are set by extension; unknown extensions are served as binary.
100- Everything is sent =Cache-Control: no-store=, because a cached dev response makes an
101  edit look like it did not land.
102- URL resolution refuses to leave the output directory. =..=, percent-encoded =..=,
103  backslashes, absolute paths and embedded NULs all resolve to nothing.
104
105* A typical session
106
107#+BEGIN_SRC sh
108# One terminal, left running.
109orgo serve content -o _site --drafts
110
111# Write. The browser keeps up.
112
113# Before publishing, check what a real build says.
114orgo build content -o _site --strict
115#+END_SRC