WP Manifestindependent plugin directory
manifest / updates / static-site-importer

Static Site Importer #6 in Updates & Deployment

Import static HTML sites into WordPress block themes

by Chris Huber · github.com/automattic/static-site-importer

45stars
847release downloads
≈60active sites
7forks

Install

The author publishes release zips, so WP-CLI can install straight from GitHub:

wp plugin install https://github.com/automattic/static-site-importer/releases/download/v1.9.5/static-site-importer.zip

Readme

Static Site Importer

Import a static site or generated website artifact into WordPress pages and an intentional companion block or classic theme.

Static Site Importer is a WordPress plugin. It requires the Blocks Engine PHP transformer Composer package and calls that package's canonical helper functions for generic artifact compilation and format conversion.

Development packages

Build a production-shaped development ZIP using immutable Blocks Engine source without changing this checkout's Composer files:

npm run build:dev-package -- --blocks-engine-path ../blocks-engine --blocks-engine-ref origin/trunk

The command resolves the requested ref once, archives php-transformer/ and figma-transformer/ from that commit into an isolated temporary snapshot, installs production dependencies there, and delegates ZIP assembly to homeboy review build. The ZIP and adjacent provenance JSON are written to build/. Use --output-dir <path> to select another destination. The receipt records SSI HEAD, a dirty worktree identity when present, the Blocks Engine ref and SHA, Composer lock digest, ZIP digest, and schema version.

Runtime package profiles

runtime-package-manifest.json is the canonical package-composition contract for constrained or embedded WordPress runtimes. Consumers locate the manifest inside the normal plugin release, select a named profile, copy only matching relative paths, and fail if any declared required_files entry is absent. The contract is deployment-neutral: storage, archive transport, scheduling, and runtime infrastructure remain consumer concerns.

website-artifact-import remains the default release profile and provides the full artifact import, validation, WordPress site-plan materialization, and manifest-inspection abilities. html-site-import provides those same abilities for HTML string, file, URL, ZIP, and HTML website-artifact inputs while excluding Figma, optional Markdown conversion dependencies, and SSI's root Composer runtime. Select it for a development package with npm run build:dev-package -- --runtime-profile html-site-import; package consumers select the same name from runtime-package-manifest.json. Markdown and MDX inputs return an explicit unsupported-capability diagnostic in that reduced runtime. The immutable contract is also available from static-site-importer/get-runtime-package-manifest for runtime discovery.

Canonical Site Plans

static-site-importer/materialize-wordpress-site-plan is the generic plan-only boundary for a blocks-engine/wordpress-site-plan/v2 produced by Blocks Engine. SSI calls the package's canonical validator and resolver, then owns WordPress/filesystem preflight, materialization, reconciliation, and the static-site-importer/materialization-receipt/v2 response. Plan, report, classic handoff, and receipt bindings use the producer's blocks-engine/wordpress-site-plan-identity/v1; the materializer keeps its prepared_resolved_projection_hash separate for prepare-to-write TOCTOU detection. It accepts no source HTML or transformer result envelope.

For an isolated runtime matrix, invoke the ability with plan, slug, and optional overwrite, or use:

wp static-site-importer materialize-wordpress-site-plan --plan=/path/to/plan.json --slug=generated-site

Client Script Policy

Every artifact is passed through client_script_policy before Blocks Engine compilation and WordPress materialization. The default is inert: SSI removes executable inline, local, remote, module, telemetry, and data: script markup, removes bundled JavaScript assets, and records each disposition in import_report.client_script_policy. JSON data scripts are quarantined in the report and are not emitted into the generated site.

isolated_preview is the sole preservation opt-in. It requires an explicit client_script_provenance object with a non-empty ref and a runtime isolation assertion. It is intended only for an isolated disposable preview runtime. Preserved scripts remain untrusted_imported_code; artifact carriage, local paths, and source type never establish trust. Current-site REST imports forcibly use inert. Existing include_scripts URL collection callers no longer preserve scripts; callers must request script_policy: isolated_preview, supply provenance, and run only in an isolated preview environment.

Architecture Stack

Static Site Importer is the WordPress materialization layer for static website inputs. It accepts two related shapes:

  • Static source imports: an HTML entry file, pasted HTML document, public HTML URL, bounded public static-site collection, direct HTML upload, or ZIP source tree.
  • Generated website artifacts: a blocks-engine/php-transformer/site-artifact/v1 bundle emitted by website generation or browser runtimes.

The conversion stack is split by responsibility:

  • Static Site Importer owns WordPress intake, safety checks, page/theme creation, asset placement, import reports, quality gates, and intentional block or classic theme materialization.
  • Blocks Engine PHP transformer owns the generic ArtifactCompiler, its diagnostics, and the source_reports.wordpress_site_plan v2 output. SSI materializes that plan into WordPress and returns the receipt and import report.

Content-Only Security Boundary

All HTML, folders, ZIPs, URLs, and website artifact objects are untrusted static content. SSI accepts only explicit static asset extensions and rejects server-side source markers before compilation. Compiler-produced companion payloads are independently revalidated before any generated plugin file is written or activated. Companion block renders accept static HTML only; SSI emits its own fixed PHP wrapper to output that markup, so source PHP cannot be preserved or executed. Existing payloads that relied on PHP render templates or PHP companion assets must migrate their behavior to blocks, data bindings, or client-side JavaScript.

When a generated artifact contains full-document HTML, Static Site Importer routes document metadata, head content, styles, scripts, and page body fragments to the right WordPress destinations before calling the conversion stack. A core/html block in imported page content is therefore a materialization/conversion quality issue to fix in this stack, not a product-layer workaround to hide upstream.

What It Does

  • Accepts pasted HTML, one public HTML URL, a direct .html / .htm upload, or a ZIP containing a static-site folder with an index.html shell/chrome entry point.
  • Allows ZIP/CLI source-site imports to include nested .md / .markdown content documents; .mdx is skipped with explicit diagnostics because MDX runtime components are not supported.
  • Provides one WP-CLI importer, wp static-site-importer import, for pasted HTML, website files, ZIP archives, and public URLs through the canonical static-site-importer/import ability.
  • Discovers readable sibling *.html files beside the selected entry file and recursive Markdown content documents under the source tree, then imports them as WordPress pages.
  • Compiles static HTML fragments and Markdown content through the Blocks Engine PHP transformer package helpers.
  • Stores converted page bodies on the imported WordPress pages as post_content.
  • Generates a block theme with shared header/footer template parts, core/post-content templates, page patterns for reusable/reference artifacts, theme.json, style.css, and optional assets/site.js.
  • Rewrites local .html links to the imported WordPress page permalinks.
  • Creates deterministic wp_navigation posts for supported header/footer navigation and references them from generated template parts.
  • Keeps imported pages native and editor-visible; page content belongs to WordPress pages while the generated theme owns shared chrome, background decoration, styles, scripts, and template wrappers.
  • Optionally activates the generated theme and assigns the imported index.html page as the front page when that page exists.
  • Names the generated theme from the resolved imported site title unless the caller supplies an explicit name.
  • Removes untouched WordPress installation content (Hello world!, Sample Page, and the sample comment) from fresh sites by default.

Requirements

  • WordPress 6.6 or later.
  • PHP 8.2 or later.
  • Composer dependencies installed with composer install.
  • Node dependencies installed only when running the JavaScript block-validation smoke tests.

SSI requires automattic/blocks-engine-php-transformer:^0.4.3. Until the package is published on Packagist, composer.json includes an explicit package repository for the php-transformer-v0.4.3 tag with autoloading rooted at the Blocks Engine monorepo archive's php-transformer/src/ directory. Remove that repository override once Packagist serves the package metadata.

At runtime, SSI loads the transformer package from vendor/ and calls blocks_engine_php_transformer_compile_artifact() and blocks_engine_php_transformer_convert_format() directly.

Runtime Interfaces

Static Site Importer is an infrastructure plugin. Its supported runtime surfaces are WordPress abilities, WP-CLI commands, REST endpoints, and PHP consumer APIs. It does not register an admin screen or ship an end-user Gutenberg block.

Browser Playground Demo

Open the separate demo interface in a disposable WordPress Playground site:

The release blueprint installs the infrastructure-only Static Site Importer package and a separate demo plugin built from demos/playground-importer/. The demo plugin owns the static-site-importer/importer block and consumes SSI's public REST contract to import into the disposable Playground site. The SSI plugin and its runtime package contain no demo UI or demo registration.

Testers can enter one public URL, upload static site files, choose a folder, upload a ZIP, or paste HTML. Figma upload is enabled only when the Playground runtime provides the optional zstd extension; all other source types remain available without it. Tagged blueprints and demo packages are published through the Playground publication contract, while the README uses the browser-verified playground/latest/blueprint.json alias.

Site Identity and Default Content

The imported site's resolved title is also the generated theme name, so a producer's generic package name does not replace the site identity. Callers can still pass name and slug. Developers can customize the final values with static_site_importer_theme_name and static_site_importer_theme_slug:

add_filter( 'static_site_importer_theme_name', static fn ( string $name ): string => $name . ' Theme' );
add_filter( 'static_site_importer_theme_slug', static fn ( string $slug ): string => 'custom-' . $slug );

Imports remove untouched core seed content on sites where WordPress still reports fresh_site. Records are fingerprinted before page materialization and checked again before deletion, so edited or replaced content is preserved. Set the canonical import argument remove_default_content to false, pass --keep-default-content to WP-CLI import commands, or use the static_site_importer_remove_default_content filter to disable cleanup.

Read the full README on GitHub →

Releases

TagPublishedAssetDownloads
v1.9.5 Sep 4, 2026 static-site-importer-html-site-import.zip 3
v1.9.5 Sep 4, 2026 static-site-importer.zip 11
v1.9.4 Sep 3, 2026 static-site-importer-html-site-import.zip 0
v1.9.4 Sep 3, 2026 static-site-importer.zip 7
v1.9.3 Sep 3, 2026 static-site-importer-html-site-import.zip 7
v1.9.3 Sep 3, 2026 static-site-importer.zip 7
v1.9.2 Sep 2, 2026 static-site-importer.zip 16
v1.9.1 Sep 2, 2026 static-site-importer.zip 6
v1.9.0 Sep 2, 2026 static-site-importer.zip 4
v1.8.6 Aug 31, 2026 static-site-importer.zip 5
v1.8.5 Aug 30, 2026 static-site-importer.zip 18
v1.8.4 Aug 29, 2026 static-site-importer.zip 5
v1.8.3 Aug 29, 2026 static-site-importer.zip 4
v1.8.2 Aug 29, 2026 static-site-importer.zip 7
v1.8.1 Aug 29, 2026 static-site-importer.zip 5
v1.8.0 Aug 27, 2026 static-site-importer.zip 12
v1.7.0 Aug 24, 2026 static-site-importer.zip 64
v1.6.0 Aug 22, 2026 static-site-importer.zip 14
v1.5.0 Aug 12, 2026 static-site-importer.zip 42
v1.4.0 Aug 4, 2026 static-site-importer.zip 28
v1.3.7 Jul 29, 2026 static-site-importer.zip 33
v1.3.6 Jul 28, 2026 static-site-importer.zip 12
v1.3.5 Jul 28, 2026 01-static-site-importer.zip 0
v1.3.5 Jul 28, 2026 static-site-importer.zip 2
v1.3.4 Jul 23, 2026 01-static-site-importer.zip 1

Active-site estimate ≈60 comes from the v1.7.0 cohort. Method.