Plugins
Configure output transformations or write your own plugin.
Plugins transform restored files after built-in HTML and CSS rewriting and before
the ZIP is packaged. Configure them with --plugins-json in the CLI, or paste
the same JSON array into Output plugins JSON in the dashboard.
Enable a plugin
wayback-restorator restore 'https://web.archive.org/web/20260925084419/https://example.com/' \
--plugins-json '[{"id":"clean","plugin":"strip_external_urls","options":{}}]'Each entry has three fields:
| Field | Purpose |
|---|---|
id | Unique name for this invocation, also used in the report. Use 1–80 letters, digits, dots, underscores, tildes, or hyphens. |
plugin | Registered plugin name. |
options | Object overriding that plugin's default settings; use {} for defaults. |
Built-in plugins
Clean external references
strip_external_urls cleans references to other sites in restored HTML. It
changes external links and form actions to #, removes external stylesheet,
script, and iframe elements, and neutralizes external media references.
Same-site links are preserved.
| Option | Default | Purpose |
|---|---|---|
extensions | [".html", ".htm"] | Additional filename matching. Files with an HTML content type are also processed. |
For example, include restored .php pages:
[
{
"id": "clean",
"plugin": "strip_external_urls",
"options": { "extensions": [".html", ".htm", ".php"] }
}
]Change a path prefix
path_prefix renames an output path prefix and rewrites matching root-relative
references in selected file types.
| Option | Default | Purpose |
|---|---|---|
from | /wp-admin | Source path prefix. |
to | /wp-extend | Replacement path prefix. |
extensions | [".html", ".js"] | File types whose references are rewritten. |
Both prefixes start with / and name a path within the restored website.
[
{
"id": "move-docs",
"plugin": "path_prefix",
"options": {
"from": "/old-docs",
"to": "/docs",
"extensions": [".html", ".js", ".css"]
}
}
]This maps old-docs/index.html to docs/index.html and changes matching
/old-docs/ references to /docs/ in HTML, JavaScript, and CSS files.
Combine plugins
Plugins run in JSON array order. This configuration changes a prefix, then cleans external references:
[
{ "id": "move", "plugin": "path_prefix", "options": {} },
{ "id": "clean", "plugin": "strip_external_urls", "options": {} }
]Check the plugins array in the result report for
each invocation's counters.
Write a plugin
Plugins are part of the source code. Set up a development checkout
first, then add src/wayback_restorator/plugins/replace_text.py. This example replaces a
phrase in HTML output:
from dataclasses import dataclass
from .support.base import FileContext, Plugin, PluginConfig, check_options
DEFAULT_OPTIONS = {"old": "Old name", "new": "New name"}
@dataclass(frozen=True)
class ReplaceTextConfig(PluginConfig):
old: str
new: str
def parse(plugin_id: str, options: dict[str, object]) -> ReplaceTextConfig:
check_options(options, set(DEFAULT_OPTIONS), f"plugin {plugin_id} options")
settings = {**DEFAULT_OPTIONS, **options}
if not all(isinstance(value, str) for value in settings.values()):
raise ValueError(f"plugin {plugin_id} old and new must be strings")
if not settings["old"]:
raise ValueError(f"plugin {plugin_id} old must not be empty")
return ReplaceTextConfig(plugin_id, settings["old"], settings["new"])
class ReplaceTextPlugin(Plugin):
name = "replace_text"
def __init__(self, config: ReplaceTextConfig) -> None:
super().__init__(config.id, (".html", ".htm"))
self.old = config.old.encode("utf-8")
self.new = config.new.encode("utf-8")
def transform_file(self, context: FileContext, content: bytes) -> bytes:
return content.replace(self.old, self.new)Register it
In src/wayback_restorator/plugins/registry.py, add the import:
from .replace_text import ReplaceTextConfig, ReplaceTextPlugin, parse as parse_replace_textAdd an entry to the existing REGISTRY dictionary:
"replace_text": (ReplaceTextConfig, parse_replace_text, ReplaceTextPlugin),Run it
From the development checkout:
wayback-restorator restore 'https://web.archive.org/web/20260925084419/https://example.com/' \
--plugins-json '[{"id":"rename-site","plugin":"replace_text","options":{"old":"Old name","new":"New name"}}]'Choose a distinct --job-id when comparing separate outputs.
Plugin hooks
| Hook | Purpose |
|---|---|
matches(context) | Select files by extension, content type, or other context. |
map_path(local_path) | Rename output files with unique relative paths. |
transform_file(context, content) | Transform a selected file's bytes. |
site_start(context) | Prepare per-site state before files are written. |
site_finish(context) | Finish per-site work after files are written. |
report() | Return the plugin's identity and counters. |
FileContext provides original_url, local_path, content_type, and
allowed_hosts. SiteContext provides the output directory and allowed hosts.
Add a focused test in tests/test_plugins.py for your transformation and
run the tests.