# Oink 0.7.1 — Nothing leaves the page, and bad input stops breaking builds

> Oink 0.7.1 is a security and validation patch. Swagger UI stops sending your spec URL to a third party, misconfigured values warn instead of killing an ordinary build, and the OpenAPI and terminal components finally behave in print, Markdown and RSS the way every other component already did.

---

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

---

Oink 0.7.1 changes no component API and needs no content edits. It closes the
code findings from an external review of the 0.7.0 line: one real privacy leak,
a class of configuration values that could stop a build outright, and three
components that had never been taught what a non-HTML output is.

**v0\.7\.1 · 2026-08-26**
- [View release](https://github.com/pgsty/oink/releases/tag/v0.7.1)
- [Source · tar\.gz](https://github.com/pgsty/oink/archive/refs/tags/v0.7.1.tar.gz)
- [Source · zip](https://github.com/pgsty/oink/archive/refs/tags/v0.7.1.zip)
- [pgsty\/oink](https://github.com/pgsty/oink)

## At a glance {#at-a-glance}

- Swagger UI no longer contacts the online validator. A published API page made
  a third-party request on every view; it no longer makes any.
- A URL written into site configuration now passes the same safety check as one
  written by an author.
- A mistyped number or boolean in `params` warns and falls back instead of
  ending an ordinary `hugo server` session.
- `swagger`, `redoc` and `asciinema` emit a plain link in print, Markdown and
  RSS, and load their runtime only in interactive HTML.

## Swagger stopped phoning home {#swagger-validator}

Swagger UI ships with an online validator enabled by default, pointed at
`validator.swagger.io`. It skips that request for `localhost`, which is why no
local preview and no browser test ever showed it — and why every *deployed*
API page was quietly handing your spec URL to a third party. On an intranet
that URL is an internal hostname.

The initializer now pins `validatorUrl: null`, and it moved out of an inline
`<script>` into a cacheable `js/chunks/swagger-init.js`. A normal build still
downloads nothing, and now a normal *view* uploads nothing.

## Configured URLs go through the same gate as authored ones {#url-policy}

Two settings reached an `href` unchecked: the custom links in
`params.ui.page_context_menu.links` and the archived-site banner's
`params.url_latest_version`. A `javascript:` URL in either one rendered as a
working, clickable script.

Both now run through the theme's shared URL policy: an unsupported scheme
warns and the link is dropped rather than repaired. The archived-version
banner additionally escapes its URL where it is written into the page, because
clearing the scheme is not the same as being safe inside an HTML attribute.

Custom links also skip entries with a missing or non-text name, and the
separator above them only appears when a link actually survives.

## Bad configuration warns; it no longer kills the preview {#validation}

The theme's rule has always been that invalid author or config input warns,
falls back to a documented default, and keeps `hugo server` usable — with
`--panicOnWarning` turning that warning into a failure where you publish.
A group of numeric and boolean keys had never been wired into it.

Before 0.7.1, a value like `blog_index_size: nope` ended the build with a Go
template error. Others were worse for being quiet: `sidebar_width_min: -50`
emitted a negative pixel width without a word, and `blog_index_columns: 2.5`
fed a fraction into a CSS grid.

Every numeric and boolean key now resolves through the shared validator:

| Input | Before | Now |
| --- | --- | --- |
| `blog_index_size: nope` | build fails | warns, uses `12` |
| `blog_index_size: 0` | silently becomes `12` | warns, uses `12` |
| `sidebar_width_min: -50` | emits `-50px` | warns, uses `220` |
| `sidebar_width_min: 300` with `max: 200` | inverted layout | warns, uses `220`/`480` |
| `blog_index_columns: 2.5` | fraction into CSS | warns, uses `3` |
| `sidebar_item_overflow: clip` | silently `ellipsis` | warns, uses `ellipsis` |
| `print.toc: nope` | silently `true` | warns, uses `true` |

The same treatment reaches the Landing sections: the hero's `media.ratio` and
`media.max_width`, the capabilities board's `columns` and `rules`, and a
marquee's `rows`. The hero's two style inputs were the notable ones — they were
written straight into a `style` attribute, so a page's own front matter could
put arbitrary CSS on the page. `ratio` now takes exactly two track sizes
(`'1fr 240px'`), `max_width` a plain CSS length.

If you have been running with a value the theme silently corrected, you will
see a new warning. That is the point — build once with `--panicOnWarning` after
upgrading to find them.

## OpenAPI and terminal recordings respect the other outputs {#outputs}

Every Oink component renders once and then adapts to the output it lands in:
interactive HTML, static print, plain Markdown for agents, and RSS. Sixteen
components already did this. `swagger`, `redoc` and `asciinema` did not — they
rendered their interactive markup into all four.

The result was a Markdown output carrying `<div class="td-asciinema">` and a
JSON config block, a printed page holding an empty container where a player
should be, and a single-page print that actually downloaded the player runtime
to show one frozen frame.

All three now read the output format:

| Output | What you get |
| --- | --- |
| HTML | the full interactive component |
| Print | a labelled static link showing the URL |
| Markdown / LLMS | a plain Markdown link, nothing else |
| RSS | the same plain link |

Only interactive HTML registers the runtime, so print and machine outputs load
no player, no Swagger bundle and no ReDoc bundle. A cast or spec URL now also
goes through the shared URL policy, and a mistyped `speed`, `cols`, `rows` or
marker time warns and is ignored instead of ending the build.

## Smaller repairs {#smaller-repairs}

- The capabilities board's rule bars render at their authored widths. The
  template had always emitted them; the stylesheet never read them.
- The generated configuration schemas match what Hugo actually parses. Trailing
  comments in `hugo.yaml` were leaking into eleven default values — `print.toc`
  shipped as the *string* `"true # section print views…"` — and four comment
  blocks documented the wrong key. Keys that exist only to warn about a rename
  no longer appear in editor completion.
- A `hero` whose `media` is not a map warns and drops the media instead of
  ending the build.

## Upgrading {#upgrading}

```bash
hugo mod get github.com/pgsty/oink@v0.7.1
hugo mod tidy
```

No content, configuration or template changes are required. One thing to do
after upgrading: run a build with `--panicOnWarning` once. Configuration that
used to be corrected silently now says so, and that build is where you will
see it.

The complete list is in [CHANGELOG.md](https://github.com/pgsty/oink/blob/main/CHANGELOG.md).

---

Backlinks:

- [2026-08-26 review](/docs/design/research/2026-08-26-comprehensive-review/)
