Guide
Command line reference
Every flag wpexportjson export accepts, what it defaults to, and the configuration-file form of the same settings — plus the checkpoint that makes an interrupted export resumable instead of a restart.
Usage
Basic Export
1wpexportjson export --url https://your-wordpress-site.com
Advanced Options
1wpexportjson export \
2 --url https://your-wordpress-site.com \
3 --format markdown \
4 --output ./my-export \
5 --brute-force \
6 --max-id 10000 \
7 --download-media \
8 --concurrent 10
Configuration File
Create a config.yaml file:
1url: "https://your-wordpress-site.com"
2output: "./export"
3format: "json"
4brute_force: true
5max_id: 10000
6download_media: true
7concurrent: 10
Then run:
1wpexportjson export --config config.yaml
Command line options
| Option | Description | Default |
|---|---|---|
--url | WordPress site URL | Required |
--output | Output directory or file | ./export |
--format | Export format (json/ markdown/ ssg/ shopify/ magento/ wordpress/ drupal/ wix/ squarespace/ webflow/ weebly/ prestashop/ ghost/ strapi/ contentful) | json |
--brute-force | Enable brute force ID discovery | false |
--max-id | Maximum ID for brute force | 10000 |
--scan-range | Rescan a specific inclusive ID range for posts/pages/media, e.g. 100-200. It adds to what the listing walk found — it does not replace the walk, so it cannot be used to avoid a listing page the site will not serve | "" |
--max-media-mb | Per-file media download size cap in MB (0 = built-in default of 2048) | 0 |
--download-media | Download images and videos | true |
--no-media | Disable media downloads (alias for --download-media=false) | false |
--relevant-media-only | Download only featured images and media linked in content (images, PDFs, videos, etc.) | false |
--exclude-media-types | Media types to skip downloading (comma-separated: images,videos,audio,documents,archives,pdf,gif). The listing is what states a file's type, so this cannot skip listing pages | - |
--media-path-style | Form of rewritten media paths: root (/media/…, resolves at any URL depth) or relative (media/…) | root |
--link-style | Form of link/canonical_url/hreflangs: absolute (source URL) or root (root-relative path) | absolute( root for ssg) |
--extract-meta | Which meta tags to keep beyond the named SEO fields: all, none, or a comma-separated allow-list | all |
--report-a11y | Write a11y-report.md flagging WCAG 2.2 contrast and missing alt-text issues | false |
--concurrent | Concurrent downloads | 5 |
--zip | Create ZIP archive of export | false |
--no-files | Remove export files after creating ZIP (requires --zip) | false |
--no-posts | Skip exporting blog posts | false |
--no-pages | Skip exporting pages | false |
--no-products | Skip exporting WooCommerce products | false |
--no-custom-types | Skip the custom post types a theme or plugin registered | false |
--custom-types | Export only these custom types (comma-separated slugs, e.g. cpt_services,cpt_portfolio) | - |
--skip-unaddressable-types | Drop custom types whose every entry is published at a query-string address (/?modula-gallery=1289) — a plugin's data store rather than pages. Off by default: a site on plain permalinks publishes everything that way | false |
--no-users | Skip exporting users | false |
--no-tags | Skip exporting tags | false |
--no-menus | Skip exporting navigation menus (they need authentication — see the navigation menus guide) | false |
--no-comments | Skip exporting reader comments | false |
--path-filter | Filter posts/pages by URL path pattern (e.g., /fr/arts/) | - |
--flat-html | Convert HTML to Markdown (Bricks Builder, Elementor support) | false |
--basic-html | Clean HTML to basic elements (tables, lists, links - for Shopify) | false |
--ssg-sections | Markdown: emit ## Excerpt/## Content sections and omit the duplicate body H1 (for ssg) | false |
--preserve-classes | CSS classes whose elements travel as HTML rather than being converted (comma-separated, wildcards like klaviyo-form-*). Applies to markdown/ssg as well as --flat-html and --basic-html — a heading's class is where a theme keeps its colour, and Markdown has nowhere to put it | - |
--preserve-styling | How much a conversion holds on to when it cannot express a class: auto (keep a heading whose classes mean something), none (convert everything, the 1.8.14 behaviour), all (keep every element carrying a class) | auto |
--boilerplate-classes | Classes this theme stamps on everything and that mean nothing a ## is missing, added to the ones every WordPress emits (comma-separated, wildcards) | - |
--crawl-content-mode | Which pages --crawl-content re-reads: auto (empty bodies and page-builder scaffolding), empty (only empty, the 1.8.14 question), always | auto |
--builder-classes | Class prefixes marking this site's page-builder markup, added to the recognized ones — the next builder is on nobody's list (comma-separated, wildcards) | - |
--content-selector | Where this theme keeps the page: tag, .class, #id or tag.class, tried before the built-in list (comma-separated) | - |
--max-sitemap-documents | Read at most N child documents of a sitemap index. 0 (the default) reads them all; a bound makes the run name the documents it skipped | 0 |
--post-loop-markers | This theme's listing elements — shortcode, block or class names — added to the recognized ones (comma-separated) | - |
--read-more-phrases | The read-more text this theme appends, for a site with too few excerpts for the run to learn it from their repetition (comma-separated) | - |
--preserve-ids | Element IDs whose elements travel as HTML rather than being converted (comma-separated, wildcards allowed) | - |
--assisted-crawl | Crawl URLs to extract SEO metadata (title, description, og tags) | false |
--exclude-tags | SEO tags to exclude (comma-separated: title,meta:description,og:title,canonical,lang,hreflangs) | - |
--crawl-content | Take the rendered page wherever the stored body is not the page: served empty, or a page builder's scaffolding — many containers and almost no text (King Composer, WPBakery, Divi, Elementor, Bricks, Beaver Builder, Oxygen) | false |
--skip-empty-content | Skip posts/pages with empty content from export | false |
--auth-user | Username for Basic Auth (prompts for password if --auth-pass not provided) | - |
--auth-pass | Password for Basic Auth | - |
--auth-token | Bearer token for authentication | - |
--rate-limit | Delay between API requests in milliseconds (prevents server rate limiting) | 0 |
--no-inventory-check | Skip reading the site's sitemap and feed after the export to report what it did not cover | false |
--frontmatter-style | Form of the structured front-matter values (meta, hreflangs): nested (YAML structure) or flat (one JSON string each, so they survive a store that holds only string lists — mddb and the like) | nested |
--from-sitemap | Read what the site publishes when the REST API will not serve it: the feed's posts, and — where the export carries no document for them — the sitemap's addresses, fetched and written as pages. Turns itself on for a WordPress older than 4.7, which has no content API at all | false |
--limit | Export at most N documents in total, newest first. The walk stops when the budget is spent, so a preview of a site does not download the site; media is limited to what those documents reference, and the summary says Posts: 5 (limited from 75) | 0 (no limit) |
--limit-per-type | At most N of each kind, or kind=N pairs, or both: 5, posts=5,media=10, 5,media=10. A kind is a collection name (posts, pages, media, products) or a custom type's slug. Combines with --limit, whichever is smaller | - |
--limit-posts, --limit-pages, --limit-media, --limit-products | Shortcuts for the kinds a preview is usually shaped around. Where one names a kind --limit-per-type also names, the dedicated flag wins and the run says so | 0 (no limit) |
--user-agent | The User-Agent to send. Bot protection matches on the default, so a browser's string is the remedy that most often works against a 403 from a wall | WordPress-Export-JSON/1.0 |
--retries | Attempts for a request the site answers with 5xx or 429, or drops. Exponential backoff with jitter, honouring Retry-After | 3 |
--resume | Resume from checkpoint if previous export was interrupted | false |
--timeout | HTTP request timeout in seconds (increase for slow servers) | 30 |
--verbose, -v | Enable verbose output | false |
--quiet, -q | Suppress all output, only return exit code | false |
--config | Configuration file path | - |
Resume / checkpoint
When exporting large sites, the --resume flag enables automatic checkpoint saving. If the export is interrupted (network error, server timeout, etc.), you can resume from where it left off:
1# First export attempt (interrupted at 90%)
2wpexportjson export --url https://large-site.com --resume -f markdown
3# Error: connection timeout...
4
5# Resume from checkpoint
6wpexportjson export --url https://large-site.com --resume -f markdown
7# Resuming from checkpoint: export/large-site.com.2026-02-02/.wpexport_checkpoint.json
8# Checkpoint: posts=1500 (done=true), pages=42 (done=false)...
The checkpoint file (.wpexport_checkpoint.json) is automatically deleted on successful completion.