Configuration lives in a .wikven.yaml file in your source directory. It follows the same shape as MediaWiki's own YAML settings format: a top-level extensions list, a skins list, and a config map.

The file name is flexible. Wikven accepts .wikven.yaml, .wikven.yml or .wikven.json, and the same three without the leading dot (wikven.yaml, wikven.yml, wikven.json); the .json forms use the same structure, since YAML is a superset of JSON. If more than one is present the first wins, in that order, and the rest are ignored with a warning, so a dotted name beats a plain one, YAML beats JSON, and .yaml beats .yml.

Wikven ships its own defaults (a sensible MediaWiki configuration for a static wiki) and loads your file on top of them, so anything you set here overrides the default. The defaults live in a default.yml that uses this same format; see #Defaults below.

extensions:
  - SyntaxHighlight_GeSHi
  - ParserFunctions
skins:
  - MinervaNeue
config:
  Sitename: Wikven
  WikvenEditUrl: https://github.com/yourname/some-repository/edit/branch-name/path/to/$1
  WikvenHistoryUrl: https://github.com/yourname/some-repository/commits/branch-name/path/to/$1

extensions

A list of extension names to load. An extension that ships inside Wikven works by name alone; any other name is treated as third-party and fetched from a source you declare in the WikvenRepositories map. See Extensions for what ships and what does not.

skins

A list of skin names to enable. Vector is built too, whatever else is listed, unless WikvenBuildVector is false; from 2.0 the list replaces it instead. Which one the site is read in is set with DefaultSkin under config, and without it the first skin built. As with extensions, a non-bundled name is fetched from the WikvenRepositories map. See Skins.

config

A map of configuration variables, each named without the wg prefix, just like in MediaWiki's YAML settings format. Any configuration setting can be defined here, and so can one an extension or skin you load declares for itself, and so can Wikven's own variables, which the sections below describe one by one.

Seven more exist and are not for you to set. WikvenSourceDirectory, WikvenHtmlDirectory and WikvenSourceHistoryFile are derived from WIKVEN_WORKDIR by the build itself (see Commands). WikvenSkins, WikvenMainSkin, WikvenMissing and WikvenRefused are worked out from the lists above: which skins the site builds, which of them it is read in, what it asked for that nothing here provides, and what it asked for that a build will not do. Setting any of them in your file does nothing useful, and the build overwrites them anyway.

WikvenLogos

Default: empty

The site's header logos. It mirrors MediaWiki's $wgLogos, with the same keys (icon, 1x, svg, wordmark, and so on), except each value is the name of an image file in your source directory rather than a URL:

config:
  WikvenLogos:
    icon: logo.svg

The values are file names rather than URLs because the file's address is decided by the build, not by you. Each named file is uploaded into the File: namespace like any other source image, and Wikven points $wgLogos at the upload for you, so you only name the file. The export then copies the logo to a single shared file in the asset directory and rewrites the reference to it, the same as for any other image, so the logo is not embedded into every page. Name none and the skin keeps whatever logo MediaWiki itself would show.

Wikven also ships a small default favicon so browsers do not 404 on /favicon.ico; override it with config.Favicon (a URL or a data URI).

WikvenEditUrl, WikvenHistoryUrl and WikvenViewSourceUrl

Default: empty

The targets the "Edit", "View history" and "View source" links point at, so a reader can jump from a rendered page to its source in your repository. In each URL, $1 is replaced with the page's source file name relative to your source directory, including its extension. A page whose title carries its own content model keeps its extension (MediaWiki/Common.css, MediaWiki/Common.js, a .json config page, a page in Module/, ...); every other page is a .wikitext file, so a normal page becomes Getting Started.wikitext. Leave any of them unset to drop that link; a generated page (such as the Licenses page, when the build writes it) has no source file, so these links are omitted for it.

WikvenMainPage

Default: index

The title of the page a static host serves at the top of the site. Every page is written as its own title with .html after it, so this is the one whose title has to be index -- naming your entry file index.wikitext therefore takes no configuration at all. Point this at a page called something else and it is written as <that title>.html, and the site has no index.html for a host to serve. The page must be one you imported; the build fails if it is missing.

WikvenLicensesPage

Default: Licenses

The title of the page saying what your site publishes that is not your own, and under which licenses, which the footer links from every page. A built site publishes MediaWiki's own scripts and each skin's and extension's styles alongside your words, so something has to acknowledge them, and a page nothing links to does not. The build lists what it ran on — MediaWiki, PHP and the database — and then your extensions and skins with the version and license each declares for itself. Only MediaWiki's license is named among the first three: its scripts go out with the site, and PHP and the database do not, so naming a license beside them would read as a claim that your site ships them. On a site with translations it is written once per language, at Licenses/<language>, so the footer link lands on a copy the reader can read; the languages are the ones your pages have translations in. Write a source page of that name and it is used exactly as written instead, and the build writes no language copies under it either. Set it empty to write no page at all, and the footer link goes with it.

MediaWiki's own "About" footer link is a separate thing, and not one the build fills in: with no page where MediaWiki:Aboutpage points, that entry is blanked along with the other dead ones. A site that wants it writes its own introduction and a MediaWiki/Aboutpage.wikitext naming that page.

WikvenFooterBadge

Default: true

A built page's footer in Vector: the wikven badge beside MediaWiki's own.

Whether the footer of every page carries a wikven badge, drawn to match MediaWiki's own badge and shown beside it. Set it false and the build writes none; what your site publishes alongside your own words is still acknowledged on the licenses page, which the footer links from every page. That MediaWiki badge belongs to MediaWiki rather than to wikven and stays either way, and a FooterIcons you write for yourself is left alone whichever way this is set.

WikvenFooterUrl

Default: empty

A link added to the site footer, pointing at your project (typically its repository). The footer shows the host name for known forges (GitHub, GitLab, Codeberg, ...). With no URL there is no such link.

WikvenSiteUrl

Default: empty

The address this site will be published at, path and all, ending in a slash — https://example.org/wiki/. The build cannot work this out for itself: it installs against a local server, and it writes every page link as a file beside the one asking, which is exactly what lets an export work from any directory and any host. Anything that has to name a page from outside the site is built from this: given an address the bake writes sitemap.xml, naming every page it exported, and where it is empty — the default — no sitemap is written, because a URL a reader cannot resolve is worse than none. Nothing about the pages changes either way: their links stay relative and the export still moves anywhere. The scheme and host also become $wgCanonicalServer, so an absolute URL that MediaWiki or an extension builds names the right host. A value that is not an http or https URL is reported and read as empty.

WikvenSettingsPage

Default: Settings

The title of a page the build writes for the reader's own display choices: the colour theme, and, on a site built with more than one skin, which skin to read it in. The choices are kept in the reader's browser and apply to that site alone; no account is involved. It stands in for the preferences a live wiki would offer, which a static export has no server for.

Write a source page of that name and it takes precedence, exactly as for the Licenses page. Set it empty to write no page at all, and the entries pointing at it go with it. See Skins for what the page offers a reader.

WikvenBundleWebfonts

Default: false

When set, and UniversalLanguageSelector is enabled, the build bakes that extension's webfonts for the languages your pages use into a stylesheet the export serves itself, so a reader whose system has no font for a script sees the intended typeface instead of empty boxes. It is off unless asked for, because the fonts are extra payload for a site whose readers may not need them. It does nothing without UniversalLanguageSelector; see Translating.

WikvenFailOnCategories

Default: the faults MediaWiki and the bundled extensions already track

Categories no page may be in when the build finishes. A build that puts a page in one of them stops and says which pages did.

MediaWiki does not refuse a page it cannot render properly; it renders what it can and files the page in a tracking category. A template used without a required argument draws its placeholder, a Lua error prints where the module's answer should be, a reference points at a source the page never gives, a page whose template expansion ran past its limit is cut short — and each of those is a page that builds, publishes, and reads as something nobody wrote. The category is the only thing that says so, and a static export does not carry it.

The default is every one of those MediaWiki and the bundled extensions already track, so a site that sets nothing stops on them. Left out are the categories that record a choice rather than a fault — hidden categories, indexed and noindexed pages, magic links, and the counts of a deprecated syntax's remaining uses — none of which is a reason to refuse a build.

Write an entry as the tracking category's message key, which is how MediaWiki names these: nothing in it says “Pages with template loops”, it says template-loop-category, and a wiki reading in another language answers that key with its own name. A key belonging to an extension the site does not load names nothing and is passed over. To drop one of the defaults, edit its message to -, MediaWiki's own way of switching a tracking category off.

Anything that is not a message key is read as a category name, with or without the Category: prefix, and what a site writes is added to the default rather than replacing it. A template can file a page itself:

{{#if:{{{1|}}}||[[Category:Pages with template errors]]}}

Give the category __HIDDENCAT__, so it stays off the page footer. The export does not include a category page, and a link to one it does not have is a link to nothing.

WikvenFileNames

Default: readable

How a page is named in the output, and so what every link to it says. The default names each page as its title is written — Vector_(skin).html, File:Bakery_oven.jpg.html — which makes the plainest URLs, and is what this documentation site is published under. What a link carries is that name URL-encoded, since a static server decodes the path it is asked for before looking for the file.

Set it to encoded where the output directory is a Windows filesystem. Windows cannot hold a file whose name has a colon in it, so a bind mount from Docker Desktop cannot take a page outside the main namespace under the default; encoded leaves every escape the page cache made in place — File%3ABakery_oven.jpg.html — which any filesystem can hold. The cost is in the URLs, which carry that percent sign doubled: the link to that page reads ./File%253ABakery_oven.jpg.html, because a link is the name URL-encoded and the name itself has a percent in it.

Four characters a Windows path cannot hold either — a quote, an asterisk, a question mark and a backslash — stay escaped under both, so a page called What? is written as What%3F.html either way. They are rare in a title and keeping them escaped costs nothing legible, which saves the sites that never have one from needing encoded at all.

Changing this changes every URL the site serves. A link somebody else made to a page keeps pointing at the old name, which is no longer there. Pick one before publishing rather than after.

WikvenBuildFor

Default: site

Set it to skin-preview and the chrome is left as the skin drew it: the personal menu, the toolbox, the tabs and the footer are the skin's own work rather than Wikven's reading of them, which is what a skin author baking a few pages wants to look at. Everything that makes the output a working set of files is unchanged.

This mode is experimental, and will stay so. A skin is written against several MediaWiki releases; a bake renders on the one Wikven carries. What you get is your skin on that version and no evidence about any other, which is less than a skin author needs and more than this project can widen. examples/skin-preview in the Wikven repository is a source tree to bake with it, and its README is where the mode is described.

WikvenBuildVector

Default: true

Set it to false to build without Vector, which the defaults otherwise add to every site's skins. Vector is still built if the site lists it itself, or lists no other skin, since a site needs one. It is a stopgap: in 2.0 a site's skins list replaces the default, so listing the skins you want is how to leave Vector out, and this setting is deprecated. See Skins.

WikvenAssetDirectory

Default: assets

Where under the output directory the build writes everything it generates: the stylesheets and script bundles it dumps out of MediaWiki, and the images and webfont files their CSS names. The path is relative to the output directory and the build writes the links to match, so nothing else needs telling.

One directory rather than one per kind, because a stylesheet reaches its images by a path relative to itself — they cannot be parted. Set it to . to put them all in the output root among your pages instead.

config:
  WikvenAssetDirectory: .

WikvenRepositories

Default: empty

Sources for the third-party extensions and skins you list in extensions and skins. The lists stay plain names (the shape MediaWiki itself uses); this map says where to get the ones that are not bundled with wikven. They are fetched at build time, before MediaWiki loads them. Whether an entry is an extension or a skin is taken from which list its name appears in, so you never write the name twice. A name listed in extensions or skins that is neither bundled nor declared here fails the build, since a site published without what its author asked for is worse than one that did not build.

Each entry chooses one of three methods by the key it carries:

config:
  WikvenRepositories:
    # 1. A tarball, e.g. from Special:ExtensionDistributor, whose archive already
    #    bundles the extension's dependencies. Add sha256 to verify the download.
    Foo:
      tarball: https://extdist.wmflabs.org/dist/extensions/Foo-REL1_46-abc1234.tar.gz
      sha256: 4f5e...  # 64 hex characters; the build aborts on a mismatch
    # 2. A Git repository. Pin it with commit (an exact SHA, reproducible) or
    #    reference (a tag or branch). Add composer: true to run Composer inside
    #    the cloned directory.
    Bar:
      repository: https://github.com/example/Bar.git
      commit: 1a2b3c4d5e6f7a8b9c0d1e2f3a4b5c6d7e8f9a0b
      composer: true
    # 3. A Composer package, resolved through MediaWiki's composer.local.json.
    SemanticMediaWiki:
      package: mediawiki/semantic-media-wiki:~4.1

A name in WikvenRepositories that is already bundled with wikven is left untouched. A name that is not also listed in extensions or skins is an error.

With package, the name is Composer's to choose rather than yours: a mediawiki-extension package is installed into a CamelCased directory with any trailing -extension cut off (mediawiki/tabber-neue-extension becomes extensions/TabberNeue), while a mediawiki-skin package is not CamelCased at all (mediawiki/chameleon-skin becomes skins/chameleon). The name you list has to be that directory, because that is what the build loads. It is checked after the install and named if it does not match, so this is a build that stops rather than a site published without the component.

A package constraint that is not an exact version — ~4.1, ^4, * — is warned about in the build log for the reason the note below gives. It is not an error: taking whatever the registry serves is a bargain you are entitled to make, the same one a moving reference makes, and the build only says you have made it.

Each method needs a host tool present at build time: tarball uses tar, repository uses git (and Composer when composer: true), and package uses Composer. The Docker image bundles all of these; with the standalone binary they must be on your PATH.

The build downloads and runs the code you name here, with network access: a cloned extension's PHP and any Composer scripts execute during the build. Only declare sources you trust. For a tamper-evident, reproducible build, pin a tarball with sha256 and a repository with commit (an exact SHA); a mutable reference tag/branch or a floating package constraint can change underneath you.

Nothing moves an exact pin for you, though: this file belongs to no ecosystem a dependency bot reads, so a pin left alone is a pin left behind. See Deploying for keeping one current.

Moving wikven moves the core underneath these pins. A wikven major accompanies every bump of the bundled MediaWiki, which is about twice a year, and a site that declares WikvenRepositories is carrying code wikven does not test, released on a calendar that is not wikven's. Crossing a major hands that code a MediaWiki it has never run on.

Two things can happen then, and only one of them is caught. A component that declares a core range excluding the new core stops the build: MediaWiki's VersionChecker raises incompatible-core, naming the component and the range it asked for. A component that declares only a lower bound and breaks anyway is not detected at all. The second is the normal case rather than the exception — Citizen v3.21.0 and TabberNeue v4.0.2, both pinned by this site, require MediaWiki: >= 1.43.0 with nothing above it. That is the honest thing for them to declare: the requirement is written at release, before the core it would have to exclude exists, and the ecosystem has nowhere to record the incompatibility once someone finds it. No check can be written for what nobody can write down.

Re-check your pinned components yourself, then, whenever you move wikven across a major: build the site and read the pages they render. A green build says the pins resolved and the ranges they declared were satisfied; it is not evidence that anything still works.

This very site fetches TabberNeue this way (see its .wikven.yaml): the tabbed Docker/binary command examples on Getting Started are rendered by the fetched extension. (TemplateStyles, used by this site's templates, is bundled in MediaWiki and so needs no source here.)

ContentNamespaces

Default: [0, 6]

A standard MediaWiki setting ($wgContentNamespaces) that decides which pages wikven exports: only pages in a content namespace are written to the static site. Wikven sets the main and File: namespaces, so file description pages are exported without dumping every Template: or MediaWiki: page. Add the Category namespace (14) to export category pages too; see Pages#Categories. Because a config value replaces the default rather than extending it, list the full set you want, including the defaults you keep.

RawHtml

Default: false

Another standard MediaWiki setting ($wgRawHtml), and one wikven leaves off but a site can turn on. Set it true and a page can carry HTML of its own inside an <html> tag, which the build writes into the page exactly as given: elements and attributes wikitext does not allow, <script> and event handlers included.

config:
  RawHtml: true
<html><iframe src="https://example.org/embed" width="560" height="315"></iframe></html>

A live wiki keeps it off because anyone who can edit a page could then run script in every reader's browser. A Wikven site has no editors but the people who can change its source directory, and they can already change its MediaWiki:Common.js, so turning it on hands nobody anything they did not have. What it does hand you is the whole of what that HTML says: nothing checks it, and it reaches readers unchanged.

Unchanged also means not rewritten. A link in wikitext becomes the relative path of the file it builds to; a link inside <html> stays exactly as you wrote it, so write the built file's name (Getting_Started.html, with the underscore) and, from a subpage, the path back up to it. The tag works in pages and in the templates they use, but not in interface messages: a MediaWiki: page the skin draws, such as MediaWiki:Sitenotice, shows an error in its place.

Defaults

Before reading your .wikven.yaml, Wikven applies its own defaults from a default.yml bundled with wikven. It is written in the same format as your configuration, so it doubles as a reference for what Wikven sets for you: the site name, page titles kept as written, InstantCommons, local image uploads (including SVG), the Vector 2022 skin options, and so on. It also ships an extensions and a skins default, so every site gets SifterSearch search and the Vector skin without listing them. Your .wikven.yaml is merged on top, with your config keys overriding the defaults and your extensions and skins appended.

Titles are kept as written (rather than first-letter-capitalized, MediaWiki's default) so the entry page can be the lowercase index, which the build writes as index.html, the file a static host serves at the site root. The file is otherwise commented; each comment notes why Wikven sets that value.

To see the current defaults, read the bundled default.yml. From the Docker image:

docker run --rm --entrypoint cat ghcr.io/chaotic-ground/wikven extensions/Wikven/default.yml

It is also in the repository.