Setup wizard

Emet needs an admin/site.yaml in your repository before it can show you anything, and writing one by hand for a site with a dozen sections is tedious. The setup wizard does it for you: it scans the repository, guesses sections, fields and shortcodes from what’s already there, and commits the result.

When it runs#

The wizard appears when you’ve signed in, picked a repository and branch, and Emet can’t find admin/site.yaml on that branch (or <base_path>/admin/site.yaml if your site is in a subdirectory). There’s no button for it anywhere; it only triggers on a missing config.

It also only runs in GitHub mode. The local dev server generates the same files silently on first run instead, because it can just write to disk. The desktop app doesn’t generate anything: it expects admin/site.yaml to exist in the folder you open, and tells you to create it if not.

Warning
If you see the wizard on a site you’ve already configured, something went wrong loading the config, most likely a transient GitHub error. Don’t commit. Reload and your existing config will almost certainly still be there. The wizard also refuses to overwrite an existing site.yaml without an explicit extra click, for exactly this reason.

The steps#

Scan#

Emet fetches the repository tree and looks for a Hugo site: one of hugo.toml, hugo.yaml, hugo.yml, hugo.json, config.toml, config.yaml, config.yml, config.json or a config/_default/ directory. If it finds exactly one, it scans it. If it finds several (a monorepo with a docs/ site and a www/ site, say), it asks you which one to manage and remembers your answer as base_path. If it finds none, it says so and offers to let you pick a different repository.

The scan reads a sample of content files from each section to infer field types, and reads layouts/shortcodes/, layouts/_shortcodes/ and the same directories under each theme for shortcodes.

Sections#

A list of every content section it found, with a checkbox to include it and an editable label. Expand a section to see its fields; you can change the inferred type of each one and mark it required. Shortcodes get the same treatment below.

Field types are guessed from the values in your frontmatter. A string that parses as a date becomes datetime, true/false becomes boolean, a .jpg path becomes image and so on. It’s usually right, and the ones it gets wrong are quick to fix here.

Options#

Site name and URL (used for preview links and SEO), the media folder (which decides where uploaded images go), frontmatter format (YAML or TOML, matching what your site already uses) and the default editor mode.

Publish#

Optional. Tick Enable review workflow if you want edits to land on a working branch and go to production via pull request. You choose the working branch, the production branch and the merge method. This writes production_branch, working_branch and allowed_branches to site.yaml. See Publication for what this workflow actually does.

Integrations#

Also optional. SEO analysis (on by default), Google Search Console (needs the site URL as registered in GSC), and AI. For AI you pick one or more providers and can enter API keys to be shared by everyone using the CMS.

If the repository is public, the wizard warns you before you put API keys in it. Leave them blank and each person can add their own key in the AI settings instead.

Confirm#

The generated admin/site.yaml and admin/cms.yaml, shown in two tabs. Read them. When you click Commit to repository, both files are committed together in a single commit to the branch you selected, and Emet reloads with the new configuration.

What it writes#

your-hugo-site/
└── admin/
    ├── site.yaml   # sections, fields, shortcodes, media, branches, GSC
    └── cms.yaml    # editor mode, SEO toggle, AI providers

Both files are plain YAML and are meant to be edited by hand afterwards. The wizard’s output is a starting point, not a spec. On a multilingual site it does write the languages block, taking names, content directories and the default language from your Hugo config (or from the per-language folders under content/ when the config has no languages map), and the final step lists what it found so you can check before committing; see Languages for exactly what gets generated. The full reference is in site.yaml and cms.yaml.

The deploy setting deploy.skip_ci: "[skip ci]" is written too, so that saves on the working branch don’t trigger a site build on every keystroke. See Sync for how that interacts with scheduled posts.