# Upgrade to Oink 0.4.0

> Upgrade an Oink 0.3.x site to the consolidated Scenario Components release and review its pager, navbar, footer, keyboard, and output changes.

---

LLMS index: [llms.txt](/llms.txt)

---

Oink 0.4.0 is the consolidated Scenario Components release. Reading & Release,
Landing, and Book were originally designed as 0.4, 0.5, and 0.6 tracks but ship
together under the single public `v0.4.0` tag. Do not pin the historical design
numbers.

Ordinary Docsy-compatible content, existing homepage data, and the module path
remain compatible. Most work is reviewing new default shell behavior and
replacing two removed ICP-specific footer parameters.

## 1. Pin the immutable release {#pin-release}

Create an upgrade branch and update the Hugo Module:

```sh
hugo mod get github.com/pgsty/oink@v0.4.0
hugo mod tidy
hugo mod graph | grep github.com/pgsty/oink
```

The graph must resolve `github.com/pgsty/oink@v0.4.0`, not a pseudo-version or
`main`. Oink 0.4.0 requires Hugo Extended 0.160.1 or newer and still requires no
consumer Node.js, PostCSS, or CDN pipeline.

When developing against a sibling checkout, remember that `go.work` overrides
the public module pin. Validate the public tag separately with both `GOWORK=off`
and `HUGO_MODULE_WORKSPACE=off` before calling the release dependency verified.

## 2. Review new defaults {#review-defaults}

### Sequential pager {#pager}

`docs`, `book`, and `blog` now receive a sequential pager by default. Docs and
Books follow the visible sidebar tree; blogs follow time order. If a page or
section deliberately has no sequence, opt it out:

```yaml
---
pager: false
---
```

If site-root manuals already use `params.ui.docs_root: home`, confirm the pager
and sidebar traverse the same intended tree. Do not create a separate pager
manifest.

### Universal navbar {#navbar}

The navbar now appears on every layout. Its compact state keeps one icon-based
navigation row; there is no second mobile accordion. Remove local scripts or
tests that assume a separate mobile menu. `navbar_accordion_single_open` is
retired and ignored.

To preserve a deliberately navbar-free section, use the validated override:

```yaml
cascade:
  navbar_enabled: false
```

The site setting lives at `params.ui.navbar_enabled`; a section cascade or page
front matter sets the top-level `navbar_enabled` key. All three accept only a
boolean, and the closest page value wins.

### Site-wide footer {#footer}

`footer_style` defaults to `fat` and now applies to every layout. It accepts
only `fat`, `slim`, or `none`. Legacy footer data in `data/home/<language>.yaml`
still works, but now appears site-wide instead of only on the homepage. Move it
to `data/footer/<language>.yaml` when convenient.

Readers can collapse a fat footer's link grid; the preference persists locally.
Use `slim` for only the bottom line or `none` to remove the footer from a page
or section.

### Keyboard and page actions {#keyboard-and-actions}

Single-key navigation is enabled by default on docs, blog, and Swagger shells.
The `/` key now opens full search, while `\` opens command-only mode. Review any
training text or custom scripts that assumed the previous `/` behavior.

Page actions now live in a split button beside the breadcrumb. Remove local CSS
or browser tests that target the old collapsible TOC-rail action group. See
[Keyboard navigation](/docs/advanced/keyboard/) for the complete key contract.

## 3. Replace removed footer parameters {#footer-parameters}

Oink no longer reads the ICP-specific pair:

```yaml
# Before 0.4.0
params:
  footer_icp: 京ICP备00000000号
  footer_icp_url: https://beian.miit.gov.cn/
```

Replace it with one inline-Markdown string:

```yaml
# Oink 0.4.0
params:
  footer_center_info: '[京ICP备00000000号](https://beian.miit.gov.cn/)'
```

An explicit empty string hides the center region. When omitted, it defaults to
`Powered by Oink`. Docsy's `params.copyright` string/map contract and Hugo's
top-level `copyright` fallback remain supported.

## 4. Enable mathematics deliberately {#mathematics}

If content uses `\(...\)`, `\[...\]`, or `$$...$$`, enable Goldmark passthrough
in the consuming site because Hugo does not merge theme markup configuration:

```yaml
markup:
  goldmark:
    extensions:
      passthrough:
        enable: true
        delimiters:
          block: [['\[', '\]'], ['$$', '$$']]
          inline: [['\(', '\)']]
```

The theme owns the render hook and local KaTeX assets. `math: true` alone is not
an enable switch. Existing parameter-free `eq` calls remain valid and
unnumbered; only a quoted `num` selects the Book form.

## 5. Adopt scenarios only where useful {#adopt-scenarios}

No ordinary content conversion is required. Introduce the stricter models
incrementally:

- [Sequential reading](/docs/scenarios/reading/) is already active; configure
  only exceptions and root choice.
- [Releases and downloads](/docs/scenarios/releases/) replace copied release
  URLs, checksums, and install commands with local facts.
- [Landing pages](/docs/scenarios/landing/) replace bespoke full-width templates
  or new Docsy block-shortcode compositions. Existing homepage data remains
  compatible.
- [Book publishing](/docs/scenarios/book/) is opt-in. Inventory existing IDs,
  captions, references, and output requirements before conversion.

Legacy `home/` partial names remain thin adapters, and Docsy block shortcodes
still render. They are compatibility paths, not the recommended basis for new
Landing work.

## 6. Run the upgrade matrix {#validation}

Build every language and output from both the production base URL and a subpath
preview. At minimum inspect:

| Surface       | What to verify                                                   |
| ------------- | ---------------------------------------------------------------- |
| Docs/Book     | Sidebar order, pager, head relations, headings, page actions     |
| Blog          | Time-order pager, RSS ownership, navbar, footer                  |
| Landing/home  | No-JS content, compact menu, reduced motion, print, local facts  |
| Release       | Derived URLs, complete checksums, pending/published behavior     |
| Book print    | Chapter order, unique IDs, local xrefs, skipped `no_print` pages |
| Accessibility | Keyboard-only use, focus order, both themes, forced colors       |
| Deployment    | Internal links and assets retain the base-path prefix            |

For this official project site, the complete consumer gate is:

```sh
npm test
npm run test:browser
```

For another site, run its equivalent build, link, output, accessibility, and
browser checks. A green local build does not prove the signed tag, public module
cache, hosted deployment, or CDN state; record each separately.

## Roll back safely {#rollback}

If the site-specific migration fails, restore the prior pinned release in
`go.mod` and rebuild. Do not delete authored content or reset the worktree as a
rollback shortcut. Keep the upgrade branch and validation evidence so the
failing contract can be corrected without losing unrelated work.

See the [0.4.0 release note](/blog/release/0.4.0/) for the complete feature and
behavior summary.
