The CSS-based preview in the browser is a reconstruction of what Hugo would render, and for anything beyond plain Markdown it’s a guess. The desktop app can do better because it has a real filesystem and, if you’ve installed it, a real Hugo. It starts hugo server for the site you’ve opened and shows the actual rendered page in the preview pane, with Hugo’s live reload rebuilding it every time you save.
The web dev server can do this too, against a hugo server you’ve started yourself; see Hugo server preview. What’s specific to the desktop app is that Emet starts, stops and watches the process for you.
What you’ll need#
Hugo on your PATH. Emet looks it up with which hugo (or where hugo on Windows) and uses the first result. There is a stored setting for a custom binary path, kept in hugo-settings.json in Electron’s user data directory, but at the moment nothing in the app lets you set it, so in practice PATH is the only option.
Starting and stopping#
You don’t start the server yourself. The first time you open an entry after opening a site, Emet starts Hugo in the background; the preview pane shows “Hugo Server Starting…” while it builds and switches to the rendered page once Hugo reports that it’s listening. On a site of any size the initial build is the slow part, so give it a few seconds.
The preview pane’s header has a Markdown / Hugo toggle for switching between the CSS preview and the Hugo one. The toggle, and the server itself, can be turned off for a site with preview.hugo_server.enabled: false in admin/cms.yaml, which is handy if you’ve got a site that takes minutes to build.
Under the preview, when the Hugo view is selected, there’s a collapsible Server bar with a status dot and a few buttons:
- A start button (shown when the server is idle or has failed), a stop button (while it’s starting or running) and a restart button (while it’s running). Restart stops the process, waits half a second for the port to free up and starts a new one. You’ll want it after editing Hugo’s config, which
hugo serverdoesn’t always reload on its own. - A clear button that empties the log.
Click the bar to expand the log. It holds the last 500 lines of Hugo’s output, with stderr in amber, and it pops open by itself if the server errors out. Stopping the server sends SIGTERM (or taskkill /f /t on Windows); quitting the app kills it too, so you won’t end up with orphaned Hugo processes.
What Emet runs#
hugo server --port <free port> --bind 127.0.0.1 --buildDrafts --buildFutureThe port is whatever the OS hands out when Emet asks for a free one, so it won’t collide with a hugo server you’re running in a terminal. The server binds to 127.0.0.1 only, so nothing else on your network can reach it. --buildDrafts and --buildFuture are there so you can preview the things you’re actually working on, which tend to be drafts and scheduled posts. The working directory is the site root, so Hugo finds its config the usual way.
The preview iframe then loads http://localhost:<port> plus the entry’s permalink. Note that with a managed server the preview.hugo_server.url setting in cms.yaml is ignored; it’s only used when Emet isn’t managing the process, i.e. in the web dev server.
Statuses and what they mean#
| Status | Meaning |
|---|---|
| idle | Not running. |
| starting | Hugo has been spawned and Emet is waiting for “Web Server is available at” in its output. |
| running | Serving pages. |
| stopping | A stop was requested and Emet is waiting for the process to exit. |
| error | Failed to start, or exited while it was supposed to be running. |
If Hugo hasn’t reported ready within 30 seconds, Emet gives up, kills it and reports “Hugo server failed to start within 30 seconds”. If the process exits on its own while running, you get “Hugo process exited with code N”. Either way the status goes to error, the log panel opens and the start button comes back so you can try again once you’ve fixed whatever Hugo was complaining about.
When it doesn’t work#
“Hugo binary not found” means which hugo came back empty. Install Hugo, make sure the shell that launched Emet can see it and restart the app; Electron inherits PATH from wherever it was launched, which on macOS can differ between a terminal and the Dock.
If the status is running but the preview is blank or wrong, the problem is almost always the site rather than Emet. Expand the log and look for Hugo’s own errors, and try hugo server -D -F in a terminal to see the same thing without the app in the way.
If it starts but times out, check for a theme that isn’t installed (Hugo modules need Go and a network connection the first time) or a site that genuinely takes longer than 30 seconds to build. There’s no way to raise the timeout at the moment.
Where next?#
- Hugo server preview for the preview pane itself and the same feature in the web dev server.
- CSS preview for the fallback you get without Hugo.