Wayback Restorator

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:

FieldPurpose
idUnique name for this invocation, also used in the report. Use 1–80 letters, digits, dots, underscores, tildes, or hyphens.
pluginRegistered plugin name.
optionsObject 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.

OptionDefaultPurpose
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.

OptionDefaultPurpose
from/wp-adminSource path prefix.
to/wp-extendReplacement 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_text

Add 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

HookPurpose
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.

On this page