Preview a Hugo Site Locally with hugo server

Fire up hugo server on the wrong interface and you have quietly published your draft posts to anyone on the same network. This guide starts it safely on loopback, then walks through the switches that decide what gets built and where. Examples target the installed Hugo 0.123.7 package.

Before you start

Confirm which executable runs and record its version:

$ command -v hugo
/usr/bin/hugo
$ hugo version
hugo v0.123.7+extended linux/amd64

The build metadata after the version string can differ between package builds. The part that matters here is the release: 0.123.7.

1. Start on the loopback address

Replace /path/to/site with the directory holding your Hugo configuration. An explicit port makes the address easy to recognise instead of relying on the default:

$ hugo server --source /path/to/site --bind 127.0.0.1 --port 1313

Hugo watches the site by default, rebuilds on changes, and normally enables live reload in open browser pages. A successful start looks like this:

Serving pages from disk
Running in Fast Render Mode. For full rebuilds on change: hugo server --disableFastRender
Web Server is available at http://localhost:1313/ (bind address 127.0.0.1)
Press Ctrl+C to stop

Checkpoint: leave this process running, visit http://127.0.0.1:1313/ in a browser, and from another terminal check the HTTP response without touching the site:

$ curl -I http://127.0.0.1:1313/

A response beginning HTTP/1.1 200 or HTTP/2 200 confirms a page was served. A 404 can still mean the server is healthy: an empty site, or one without a matching home template, may simply have no page at that path.

2. Decide what content belongs in the preview

Hugo excludes content marked draft, expired, or scheduled for the future by default. That is a useful publication boundary, and it is also the thing that surprises you mid-write. Add only the switch that matches what you are deliberately previewing:

$ hugo server --source /path/to/site --buildDrafts
$ hugo server --source /path/to/site --buildFuture --buildExpired

These flags change the build view; they do not edit front matter or publish anything. If a page still will not show, check its front matter, section, layout and URL before reaching for every build flag.

Checkpoint: stop the first server with Ctrl+C, then restart with the smallest set of switches you actually need. That stops you accidentally previewing unpublished material during a screen share or a local network test.

3. Fix a reload loop that gets in your way

A stale browser page is not proof that Hugo failed. Check the terminal for build warnings first, refresh manually, and only keep the full rebuild switch on while you are diagnosing: it makes repeated edits slower.

4. Choose where Hugo renders files

By default Hugo serves generated pages from disk. --renderToMemory keeps rendered output in memory, which can be faster at the cost of more RAM, useful for a quick preview where nothing else needs to inspect the generated files:

$ hugo server --source /path/to/site --renderToMemory

If static files need to stay on disk while dynamic files render in memory:

$ hugo server --source /path/to/site --renderStaticToDisk

These are server-mode choices, not a substitute for a production build. For a deployable output directory, stop the server and use your site's normal hugo build workflow.

5. Expose the server only when you mean to

Warning: the default bind address, 127.0.0.1, means other machines cannot connect. Binding to all interfaces can expose drafts, source-derived details and unfinished pages to every reachable device on the network, so do not change it casually.

If you have a controlled private network and genuinely need another device to test the site, bind explicitly and use a non-conflicting port:

$ hugo server --source /path/to/site --bind 192.0.2.10 --port 1313

Replace 192.0.2.10 with the host's actual private address; do not copy that documentation address literally. Check the listening socket before sharing the URL:

$ ss -ltn | grep ':1313'

Recovery: press Ctrl+C when finished. If you changed the bind address, stopping the process is the undo action: nothing persistent gets changed by the command above.

Common failures

Done means