One entry in the configuration, but six roles in the build. Knowing which runs when explains most of the plugin’s quirks by itself.
| Role | When | What it does |
|---|---|---|
| Transformer | while processing each page | detects the language, sets frontmatter.lang and fileData.multilanguage |
| Linking | after all pages are read | groups translations with one another |
| Filter | before rendering | removes languages that are not being published (chapter 8) |
| Emitter | while writing | creates the redirect pages, the root index.html and static/multilanguage.json for the script |
| Component | while building the layout | renders the switcher |
| Script | in the browser | notices, remembered language choice, localized dates |
Why the linking comes afterwards
A transformer only ever sees one page. Whether de/kaffee has an English version can only be
said once every page has been read — which is why the grouping happens in a step of its own after
that.
Something practical follows from it: a page removed from the build by a filter — a draft, an unlisted page — is not there for the linking either. The switcher then does not show it.
For the switcher that always holds, because it reads the list after every filter. For hreflang
it depends on the order the filters run in among themselves — see the second box below.
Why order almost never matters
order sets the order of the transformers. For language detection it is almost irrelevant — it only
needs the frontmatter, which note-properties (order 5) has long since read.
The one exception, for the transformer
rewriteCrossLanguageLinksreads thedata-slugthatcrawl-links(order 60) leaves on every link while resolving it. The rewriting therefore has to run aftercrawl-links, andorder: 65does exactly that. Put the plugin earlier and you get no message — you get links that silently stay uncorrected. Anyone not using that option may leave the line out.
And a second one, for the filter
orderapplies to this plugin’s filter too, not only to its transformer — and that filter has two jobs: it removes languages that are not published and records every page it lets through in the listhreflanglater draws from. Below 50, that is beforeremove-draft, it records drafts before they are removed; thehreflangof a published page then names an address that does not exist, and nobody sees it. Measured: atorder: 40the draft appears inhreflang, atorder: 65it does not. The switcher is unaffected.
The script
Three things happen only in the browser, because they concern the visitor rather than the page: the notices about translations (chapter 7), remembering the language choice and formatting the dates.
Everything else happens at build time. Without JavaScript the switcher, hreflang and the redirects
keep working — only those three things do not.