Home / Alt manpages / hugo-new-content(1)

  • hugo-new-content(1)
  • User command
  • linux

Create Safe Hugo Content Files with hugo new content

hugo new content writes a new content file with generated front matter, so you never start a page with a blank, badly formed header. The examples were checked with Hugo 0.123.7 on Linux. Allow about ten minutes for a first page, including a quick review of the result.

You need Hugo installed and a Hugo project directory containing its configuration file. Run the command from the project root, not from content/. It writes a file, but doesn't publish it, start a server, or need elevated privileges.

1. Check the version and project root

Start by confirming which Hugo you're using and locating the project configuration:

$ hugo version
hugo v0.123.7+extended linux/amd64 BuildDate=2026-03-17T19:51:14Z VendorInfo=ubuntu:0.123.7-1ubuntu0.3+esm2
$ pwd
/srv/www/example
$ ls hugo.toml
hugo.toml

The exact version line will differ on your machine. If ls hugo.toml fails, check for hugo.yaml or hugo.json instead, then change to the project root before continuing:

$ cd /srv/www/example

Checkpoint

The next command should create a path below this project. If the printed path points somewhere unexpected, stop and fix the working directory first.

2. Create an ordinary Markdown post

Pass a path relative to the content directory. A dated-looking name isn't required; the filename and its parent section are your choice:

$ hugo new content posts/first-deploy.md
Content "/srv/www/example/content/posts/first-deploy.md" created

On a standard project, Hugo creates content/posts/first-deploy.md. Inspect it before adding prose:

$ sed -n '1,12p' content/posts/first-deploy.md
+++
title = 'First Deploy'
date = 2026-09-24T12:55:43+01:00
draft = true
+++

The title comes from the filename, the date is set automatically, and a new file is a draft by default on this installation. Your timestamp will naturally differ. Keep draft = true while the page is unfinished, and change it only once your site's publishing workflow is ready.

3. Let the path express the content section

Hugo guesses the kind of content from the path. This, for example, creates a page under a documentation section:

$ hugo new content docs/installation.md
Content "/srv/www/example/content/docs/installation.md" created

The section is docs, the filename is installation.md. That convention keeps the URL and template lookup predictable, but it doesn't mean every path should be left to guesswork. When the kind actually matters, say so explicitly with -k or --kind:

$ hugo new content --kind tutorial tutorials/backup.md
Content "/srv/www/example/content/tutorials/backup.md" created

If the project or theme has an archetype for tutorial, Hugo uses it. Archetypes are templates for new content, so they may add front matter beyond the title, date and draft fields. Read the generated file rather than assuming the template matches your plan.

4. Check for an existing file before using force

Hugo refuses to overwrite an existing path:

$ hugo new content posts/first-deploy.md
Error: /srv/www/example/content/posts/first-deploy.md already exists

Safety boundary

That guard stops you from losing a draft by accident. Don't reach for --force as a routine fix, since it overwrites the file at the requested path and can destroy edits or front matter outright. Before an intentional replacement, make a recoverable copy and inspect the target:

$ cp -- content/posts/first-deploy.md /tmp/first-deploy.md.backup
$ sed -n '1,20p' content/posts/first-deploy.md
$ hugo new content --force posts/first-deploy.md
Content "/srv/www/example/content/posts/first-deploy.md" created

That backup is your undo path. Restore it only if you genuinely mean to discard the newly generated file:

$ cp -- /tmp/first-deploy.md.backup content/posts/first-deploy.md

Warning

Don't run the force example against a valuable draft until you have a backup outside the target path. The command gives you no recycle bin.

5. Use a non-default content directory when the project needs one

Projects can mount content somewhere other than the default content directory. Supply that location with --contentDir:

$ hugo new content --contentDir site-content posts/first-deploy.md
Content "/srv/www/example/site-content/posts/first-deploy.md" created

Use this option when the project configuration and repository layout require it. Otherwise a successful command can still put the file where the site's templates never look. Verify the actual path in Hugo's output, then check it directly:

$ test -f site-content/posts/first-deploy.md && printf '%s\n' 'content file exists'
content file exists

--contentDir is a path for this one invocation. It's not a fix for a project whose configuration points at the wrong content mount.

6. Open the new file only after creation succeeds

You can ask Hugo to open the generated file with an editor:

$ hugo new content --editor "$EDITOR" posts/release-notes.md

--editor is entirely optional, and if your editor command needs arguments, test it separately first. A simpler, less distracting workflow is to create the file, inspect its path, then open it yourself:

$ hugo new content posts/release-notes.md
Content "/srv/www/example/content/posts/release-notes.md" created
$ ${EDITOR:-vi} content/posts/release-notes.md

Don't confuse the filename with the page title. Hugo derives an initial title, but you should still edit the front matter if the public heading needs different spelling or capitalisation.

7. Verify the draft without publishing it

Finish by checking that the file exists, the front matter is present, and the draft flag is still set:

$ test -f content/posts/release-notes.md
$ sed -n '1,10p' content/posts/release-notes.md
+++
title = 'Release Notes'
date = 2026-09-24T12:55:43+01:00
draft = true
+++

If you use the development server, remember that drafts may need the server's own draft option to appear. That's a preview concern, not something hugo new content changes; the command itself only ever creates the source file.

Done means

  • Version and root confirmed. You ran Hugo from the project root and confirmed the installed version.
  • Path is correct. The requested path sits inside the content directory the project actually uses.
  • Front matter checked. The generated file has the expected title, date and draft state.
  • Kind used deliberately. You chose an explicit kind when an archetype or template required one.
  • Force used carefully. You never used --force without a backup and a deliberate replacement decision.