🚀 New: WordPress Care Plans starting at $49/mo — see plans & pricing →
Fiverr
Upwork
LinkedIn
YouTube
WhatsApp
BD Local Guide
SEO Services
📝
On-Page Optimisation
🔍
Indexing & Crawling
Core Web Vitals
🔗
Backlinks & Off-Page SEO
📍
Local SEO & Map Pack
🛒
E-Commerce SEO
📈
Affiliate Content Scaling
🚨
Traffic Drops & Penalties
WordPress
🔧
WordPress Technical SEO
🛡️
Care Plans — from $49/mo
📦
Products & Tools
Resources
SEO Checklist 2026
💰
SEO Strategy & ROI
🛠️
Tools We Recommend
Company
👋
About Us
👋
Our Portfolio

WordPress SEO that actually ranks

Technical SEO, speed optimisation, and monthly care plans for WordPress sites that need to perform.

Free WordPress Plugin to Export Posts, Pages, Categories & Image URLs (2026 Download Guide)
WordPress dashboard on a laptop screen with code editor open
Free WordPress Plugin · 2026

Simple Content Exporter — The Lightweight WordPress Plugin to Export Every Post, Page, Category & Image URL

1. What Is Simple Content Exporter?

Simple Content Exporter is a small, single-file WordPress plugin built for one job and one job only: pulling a clean, structured list of your posts, pages, categories, and image URLs out of WordPress and into a file you can actually open in Excel, Google Sheets, a database, a static-site generator, or a migration script. It does not try to be a backup tool. It does not try to be a SEO suite. It does not bolt on dashboards, telemetry, opt-ins, or upsell screens. It is a single PHP file, under thirty kilobytes, that adds one screen under Tools → Content Exporter and gives you a CSV or JSON download in a couple of clicks.

The reason this plugin exists is simple. WordPress ships with a built-in WXR (XML) exporter, but WXR is a heavyweight format designed for full-site moves between WordPress installs. It is not what you reach for when a developer asks for “just a spreadsheet of every post title, its URL, its categories, and its featured image.” It is not what you reach for when you want to feed a list of image URLs into a CDN migration job, or when an SEO consultant says “send me a CSV of every published page so I can audit titles.” For those jobs, you need something narrow, fast, and predictable.

Spreadsheet and dashboard showing structured content data

That’s the gap this plugin fills. You activate it. You go to one page. You pick posts, pages, or both. You pick a status. You pick CSV or JSON. You click Download Export. You get a file. There is no configuration, no API key, no signup, no premium tier, no nag bar. The whole thing runs entirely on your server, against your own database, with no external network calls — which matters if you work in regulated industries or simply do not want yet another vendor watching what you publish.

Who built it and why

The plugin was assembled to solve a recurring problem editors and SEOs run into during content audits, replatforms, and image-CDN migrations. Most existing exporters either overshoot (full WXR with every post meta, every revision, every block attribute) or undershoot (titles only, no image URLs, no categories joined). Simple Content Exporter sits in the middle: it gives you the seven or eight columns you actually paste into a spreadsheet, plus the image URLs that almost every workflow ends up needing.

The shape of an export, in one sentence

Each row is one post or one page. Each row carries the post ID, post type, title, permalink, status, publish date, a pipe-joined list of category names, the featured image URL, and a pipe-joined list of every <img src=""> URL that lives inside the post body. That’s the contract. Nothing more, nothing less. If you’ve spent any time wrangling content out of CMSes you already know how rare and useful that level of restraint is.

The design philosophy: do one thing, then stop

The hardest part of building a WordPress plugin is not adding features — it’s resisting them. Every feature added to a plugin is a feature you have to maintain, document, support, and explain to confused users in support tickets. Every checkbox on a settings page is a decision someone has to make before they can finish their actual task. Every dropdown is a moment of cognitive load between intent and outcome. The plugins that get used the most are usually the ones that demand the least from the user before delivering value, and that demand the least from the developer to keep alive.

That principle shapes every decision in Simple Content Exporter. There’s no settings page, because there are no persistent settings — the form on the export screen is the whole UI. There’s no dashboard widget, because dashboard widgets are clutter unless they’re showing you something that changes. There’s no “Pro” tier, because gating features behind a paywall creates friction in support — half the conversation becomes “is your problem in free or pro?” There’s no telemetry, because the moment you add telemetry, you have to write a privacy policy, document what you collect, deal with GDPR consent, and explain to security-conscious customers what your plugin sends out from their server.

The result is a plugin that takes about ninety seconds to understand top to bottom and that you can read in a single sitting. If you’ve ever opened a 4-megabyte plugin folder with twenty subdirectories and given up trying to figure out where the actual code lives, the contrast will feel almost suspicious. There’s no missing piece. The single PHP file is the whole plugin.

What this plugin is not

Just to set expectations clearly: this is not a backup tool. It will not preserve post revisions, custom fields, post meta, comments, users, or attachments themselves — only the URLs that point to attachments. It will not migrate your site between WordPress installs (use the built-in WXR exporter or a tool like All-in-One WP Migration for that). It will not give you a downloadable ZIP of your media library files (use Export Media Library for that). It will not send your content to a third-party SEO platform, generate sitemaps, audit your titles, or rewrite your slugs.

What it does is hand you a flat, structured, image-aware spreadsheet of what’s on your site, in CSV or JSON, in under thirty seconds. That’s the entire scope, and the entire scope is the point.

↓ Download Simple Content Exporter (Free)

One PHP file. Works on every WordPress install since 5.5. No license key, no signup.

v1.0.0 ~30 KB GPL-2.0+ WP 5.5+ PHP 7.4+
Download .zip Read install steps

2. Why You Need a Content Export Plugin (Even If You Already Have a Backup)

A common reaction to a tool like this is “I already have UpdraftPlus / All-in-One WP Migration / Duplicator — why would I need another exporter?” The answer is that backups and content exports are two different jobs. A backup is for restore. A content export is for analysis, transformation, and movement. You cannot open a .wpress file in Google Sheets. You cannot grep a SQL dump for every featured image URL on your site without writing a query. You cannot hand a serialized PHP array to a freelance editor and ask them to flag thin content.

The five workflows where this plugin pays for itself in minutes

Content audits. An auditor needs every published URL, its title, and its primary category in one CSV. That used to mean a custom WP-CLI command or a copy-paste marathon out of the admin. Now it’s two clicks. If you’re working through why a website audit matters, this is the file you start with — not the one you finish with, but the seed.

SEO recovery investigations. When organic traffic drops, the first investigation step is almost always “which URLs are affected, and which categories do they belong to?” A flat CSV pivots beautifully against Google Search Console exports. If you’re in the middle of figuring out why your traffic dropped overnight, you want a clean inventory of every page on the site, sorted by date, with categories attached. That’s exactly what this plugin produces.

Image and CDN migrations. Moving from a self-hosted media library to a CDN, or rewriting old image paths, requires a master list of every image URL — not just featured images, but every <img> embedded in post bodies. That second list is the one most plugins forget about. Simple Content Exporter ships with content-image extraction enabled by default.

Replatforming and headless moves. If you’re piping WordPress content into a static site, a Next.js front end, or another CMS entirely, you need a deterministic source of truth. JSON output gives you arrays of categories and image URLs that map cleanly onto front-end data structures.

Editorial inventory for outsourced rewriting. Editors don’t want a database. They want a spreadsheet. Hand them a CSV with one row per post, and they can filter by category, sort by date, and mark up which titles need rewriting — all without touching WordPress.

Compliance and legal exports. Sometimes legal asks for a list of every URL that mentions a specific product, brand name, or claim. The fastest path is exporting everything as CSV, then filtering or text-searching the file locally. No data leaves your environment beyond the export — no third-party SEO tool sees the content, no crawler hits your URLs from outside.

SEO competitive baselines. Before you launch a new content strategy, you need a snapshot of what your site looked like at the starting line. Export everything as JSON, archive it, and you have a frozen reference of titles, categories, dates, and images at month zero. Six months later, export again and diff the two — you’ve just measured how your content footprint actually changed, not how Search Console says it changed.

Internal-link audit fuel. A list of every URL on your site, with categories attached, is the input to almost every internal-linking exercise. You can use the URL column as the seed for a crawler that maps internal links, or as the target list for a spreadsheet exercise that decides which posts should link to which other posts. This is doubly useful when you’re working through why keyword rankings are dropping and you suspect orphaned or under-linked pages are part of the cause.

The hidden cost of doing this manually

Before plugins like this existed, the alternative was usually one of three things: paying a developer two to three hours to write a custom WP-CLI script, copy-pasting rows out of Posts → All Posts page by page (which loses categories and image URLs entirely), or running a SQL query directly against wp_posts joined against wp_term_relationships joined against wp_postmeta for the thumbnail. The first costs money. The second costs your evening. The third costs a database backup if you mistype a JOIN.

The actual time saved by a plugin that does this in two clicks is measured in hours per audit, hundreds of dollars per migration, and several days per replatform. That’s the real value — not the plugin’s feature list, but the work it stops you having to do.

Note: If your organic traffic problem turns out to be a ranking issue rather than a content one, you’ll also want to read about why keyword rankings drop suddenly — but you’ll still want this CSV as your reference inventory.

3. Complete Feature Overview

Restraint is the headline feature, but there are a handful of small choices the plugin makes that are worth calling out. Each one is the result of having actually used WordPress exporters in production and getting bitten by the missing detail.

01

Posts and pages, both selectable

Tick what you want. Default is both. Categories only apply to posts; the column stays empty for pages, as it should.

02

Status filter

Export published only, drafts only, or every status (including private, pending, and future).

03

CSV with UTF-8 BOM

Excel opens accented characters and non-Latin scripts cleanly out of the box. No mojibake.

04

JSON with proper arrays

Categories and image URLs come back as real arrays, not pipe-joined strings, when JSON is selected.

05

Featured image URLs

The full-size URL of the post thumbnail, not a sized variant. Reliable for migrations.

06

Inline content image URLs

Every <img src=""> in the post body is extracted and deduplicated.

07

Capability-gated

Only users with manage_options (administrators) can export. Nonce-protected against CSRF.

08

Zero external calls

Runs entirely on your server. No telemetry, no opt-ins, no remote license checks.

The export schema, column by column

Each column was chosen because it answers a question that comes up in real export workflows. The post ID lets you cross-reference rows against other database queries. The post type tells you whether you’re looking at a blog post or a static page — different content types usually get different treatment in audits. The title and URL are the obvious ones. The status column is what makes the difference between “every URL on my site” and “every URL Google can see”; you’ll often want to filter to publish only. The date is the recency signal that drives most pruning decisions. Categories are the taxonomy signal. Featured images and content image URLs drive the entire migration-and-CDN class of workflows. Nothing on the list is there because it was easy to add; everything on the list is there because someone has needed it during a real project. The columns deliberately omitted — tags, custom taxonomies, post meta, comments, attachments themselves — are omitted because they vary significantly by site and would either bloat the schema or require configuration. Both outcomes work against the plugin’s design goal of “open it, click two buttons, get a file.”

Column Type Description Example
idintegerWordPress post ID1042
typestringEither post or pagepost
titlestringRendered post titleWhy Did My Traffic Drop
urlstringFull permalinkhttps://example.com/why-did/
statusstringWordPress post statuspublish
datedatetimePublish date in site timezone2026-04-12 09:30:00
categoriesstring / arrayPipe-joined names (CSV) or array (JSON)SEO|Recovery
featured_image_urlstringFull-size thumbnail URLhttps://example.com/wp-content/.../hero.jpg
content_image_urlsstring / arrayEvery <img> src in the bodyhttps://.../a.jpg|https://.../b.jpg

4. System Requirements & Compatibility

The plugin is intentionally narrow in what it depends on. It uses only core WordPress APIs — WP_Query, get_post_thumbnail_id, wp_get_attachment_image_src, wp_get_post_categories, and the standard admin-post handler — so it runs anywhere a modern WordPress install runs. There are no third-party libraries, no Composer dependencies, and no front-end JavaScript.

RequirementMinimumRecommended
WordPress version5.56.4 or newer
PHP version7.48.1 or newer
MySQL / MariaDB5.6 / 10.18.0 / 10.6
PermissionsAdmin (manage_options)Same
Memory limit64 MB256 MB for sites with 5,000+ posts
Disk space~30 KBSame — it’s one file

Multisite, classic editor, block editor — does it matter?

No. The plugin only reads from wp_posts and wp_term_relationships. It does not care whether your content was created in the block editor, the classic editor, Elementor, Bricks, Divi, or pasted in by a CLI script. It’s reading the rendered post object, not the editor that produced it. On multisite, network-activate the plugin or activate it on each subsite individually — exports run per-site, which is almost always what you want.

Themes, page builders, and custom post types

This first release exports only the two standard public post types: post and page. Custom post types (e.g. WooCommerce product, LearnDash sfwd-courses, news article) are not exported by default. Adding them is one line of code, covered in the advanced customization section. If you’ve been wrestling with custom post types not ranking, a CSV inventory of those CPTs is often the fastest way to spot the structural issue — and that’s a five-minute change to this plugin.

Hosting environments where this has been tested

Simple Content Exporter has been verified to run cleanly on the major shared and managed WordPress hosts: SiteGround, Bluehost, Hostinger, Cloudways, Kinsta, WP Engine, Pressable, Pantheon, Flywheel, and Rocket.net. It also runs cleanly on bare-metal LAMP stacks, on Docker-based WordPress images (the official wordpress:php8.1-apache image works without modification), and on serverless WordPress on AWS Lambda where it’s a simple read operation against the database. The plugin makes no assumptions about file system layout beyond standard WordPress conventions, so any host that runs WordPress at all should run this plugin without any host-specific configuration.

Browser compatibility for the admin UI

The admin form uses standard HTML form elements with no JavaScript dependency. It works in every browser WordPress core supports — Chrome, Firefox, Safari, Edge, and the more obscure ones your security team uses. There are no front-end frameworks, no React, no Vue, no jQuery dependencies beyond what WordPress core already loads. If your admin panel works, this plugin’s UI works.

5. Step-by-Step Installation Guide

There are three ways to install Simple Content Exporter: through the WordPress admin uploader (easiest), via SFTP (most reliable on locked-down hosts), and via WP-CLI (fastest if you live in the terminal). The admin uploader path is shown below in detail because it covers 95% of use cases. Each step has its own diagram so you can match what’s on your screen against the illustration before you click anything destructive.

Before you begin: take a fresh database backup. This plugin does not write to your database, but installing any plugin on a production site without a backup is a habit worth breaking. Five minutes of caution saves five hours of recovery.
STEP 01

Download the plugin .zip file

Click the download button at the top of this page. Your browser will save a file called simple-content-exporter.zip — most browsers drop it in your Downloads folder. Do not unzip it. WordPress wants the zip as-is.

Step 1 — Download the Simple Content Exporter ZIP file from the browser indxq.com/downloads/simple-content-exporter.zip Download Simple Content Exporter v1.0.0 · 30 KB · GPL-2.0 ↓ Download .zip .zip Saved to Downloads Click once →
STEP 02

Open WordPress → Plugins → Add New → Upload Plugin

Log in to /wp-admin as an administrator. In the left-hand menu, hover over Plugins and click Add New. At the top of the new page, next to the “Add Plugins” heading, click the Upload Plugin button. A small uploader panel slides down.

Step 2 — Open Plugins, Add New, then click Upload Plugin in WordPress admin My Site Dashboard Posts Media ▸ Plugins Add New Tools Settings Add Plugins Upload Plugin click here Search plugins… Choose File: simple-content-exporter.zip Install Now
STEP 03

Choose the .zip file and install it

Click Choose File, pick the simple-content-exporter.zip you downloaded, then click Install Now. WordPress copies the file into /wp-content/plugins/simple-content-exporter/ and shows a confirmation screen with two links: Activate Plugin and Return to Plugin Installer.

Step 3 — WordPress confirms successful plugin installation and offers an Activate link wp-admin → Plugins → Install Unpacking the package… Installing the plugin… ✓ Plugin installed successfully. Successfully installed: Simple Content Exporter 1.0.0 Activate Plugin Return to Plugin Installer click to enable
STEP 04

Activate the plugin

Click Activate Plugin. WordPress redirects you to the main Plugins list, where you’ll now see Simple Content Exporter in the active plugins section, marked with the standard blue left border. The plugin adds no settings page, no notice, and no dashboard widget. The only visible change is a new menu item under Tools.

Step 4 — Plugin appears as Active in the WordPress plugins list Plugins → Installed Plugins Plugin Description Simple Content Exporter Deactivate · Settings → Tools → Content Exporter Export posts, pages, categories, and image URLs to CSV or JSON. Active Akismet Anti-Spam

Alternative installation paths

If your host blocks file uploads through the admin (some managed hosts do), drop the unzipped simple-content-exporter folder into wp-content/plugins/ via SFTP, then activate from the Plugins screen. With WP-CLI, the whole sequence is one command:

wp plugin install /path/to/simple-content-exporter.zip --activate

Verify the installation actually worked

Once you’ve clicked Activate, do a thirty-second sanity check before you walk away. There are three places to look. First, the Plugins screen — the row for Simple Content Exporter should be highlighted blue and the link below the plugin name should read “Deactivate” rather than “Activate.” Second, hover the Tools menu in the left sidebar — you should see “Content Exporter” as a new submenu item. Third, click into Content Exporter and confirm the form renders with all four controls (Posts/Pages checkboxes, Status dropdown, Format radio, Include images checkbox) and a big orange Download Export button. If any of those three checks fails, the activation didn’t complete cleanly — usually a file-permission issue or a partial unzip — and you should deactivate, delete, and reinstall before trying to use it.

What the plugin does and doesn’t change on your site at install time

Some plugins make a lot of changes during activation: they add database tables, write options rows, schedule cron jobs, register custom post types, or enqueue scripts on the front end. Simple Content Exporter does none of that. Activation registers two action hooks (admin_menu for the page and admin_post_sce_export for the download handler) and that’s it. There is no database write, no cron registration, no settings row created, no transient cached. If you check wp_options immediately after activation, you’ll see no new entries with the plugin’s prefix, because the plugin doesn’t have a prefix to write under. This is by design — uninstall is a true uninstall.

6. Run Your First Export in Two Minutes

With the plugin active, exporting content is a guided four-screen flow. Pick your options, submit the form, get a file. There’s no queue, no email, no “we’ll send it to you when it’s ready” delay — the file streams directly to your browser as a download.

STEP 05

Open Tools → Content Exporter

In the left-hand admin menu, hover Tools and click Content Exporter. You’ll land on a single page titled “Simple Content Exporter” with one short form. There’s nothing else on the page — that’s deliberate.

Step 5 — Find Content Exporter under the Tools menu in WordPress admin Posts Pages Media Plugins ▸ Tools Available Tools Import / Export → Content Exporter click this Simple Content Exporter Export posts, pages, categories, and image URLs. ☑ Posts ☑ Pages Status: Published only ▾ ⦿ CSV ◯ JSON Download Export
STEP 06

Pick options, then click Download Export

The form has four controls. Tick Posts, Pages, or both. Choose a status from the dropdown — Published only, All statuses, or Drafts. Pick CSV or JSON. Decide whether to include images embedded in post content (this is on by default and almost always what you want). Then click Download Export.

Step 6 — Configure export options and submit the download form Export options CONTENT TYPE Posts Pages STATUS Published only ▾ FORMAT CSV (Excel-friendly) JSON (developer-friendly) EXTRAS Include image URLs from post content ↓ Download Export .csv streams to browser
STEP 07

Open the file in a spreadsheet or text editor

The file is named wp-content-export-YYYY-MM-DD-HHMMSS.csv (or .json). Open the CSV directly in Excel, Numbers, or LibreOffice — the UTF-8 BOM tells Excel to render Unicode correctly without an Import wizard. Open the JSON in any text editor or pipe it into jq if you live on the command line.

Step 7 — Open the exported CSV file in a spreadsheet application wp-content-export-2026-04-26-143015.csv id type title categories featured_image_url 1042postWhy Did My Traffic DropSEO|Recovery/uploads/hero.jpg 1108postYoast vs Rank MathSEO|Plugins/uploads/yoast.jpg 1174pageAbout Us/uploads/team.jpg 1198postCore Web VitalsPerformance/uploads/cwv.jpg 1232postImage SEO ChecklistSEO|Images/uploads/img-seo.jpg ✓ Opened cleanly in Excel — no encoding issues

What to do with the file once you have it

The export is the start of work, not the end of it. The first thing to do with a fresh CSV or JSON is to take a backup copy and then work on a duplicate. CSVs are easy to accidentally save over with Excel formatting that breaks downstream tooling, and JSONs are easy to edit in ways that break the syntax. Keep the pristine version, work on the copy. Second, give the file a meaningful name beyond the timestamp the plugin generates — something like 2026-04-content-audit-baseline.csv or 2026-04-pre-redesign-inventory.json tells you in six months what the file was for. Third, store it in a location that survives — your local Downloads folder is not a long-term archive. A team Drive folder, an S3 bucket, or a Git repository dedicated to content artefacts all work; what matters is that you can find the file again twelve months from now.

What the plugin’s roadmap looks like

Version 1 is intentionally narrow. The features being weighed for v2 are: optional custom-post-type support behind a checkbox, optional tags column, date-range filtering on the form, category filtering on the form, and a WP-CLI command. Features that are explicitly not in scope, even for future versions, include: scheduled exports, email delivery, dashboard widgets, settings persistence, telemetry, premium tiers, and any form of cloud sync. The principle of “do one thing, then stop” applies to the roadmap too — every potential feature is weighed against whether it would still let a new user understand the plugin in ninety seconds. If the answer is no, the feature stays out.

7. CSV vs JSON: Which Format Should You Pick?

Both formats carry the same data. The difference is what tools you’ll feed it into and how multi-value fields like categories and image URLs are represented. Pick CSV if a human is going to open the file. Pick JSON if a script is going to read it.

Aspect CSV JSON
Best for Editors, SEOs, content auditors Developers, migration scripts, headless feeds
Multi-value fields Pipe-joined string: SEO|Recovery Real JSON array: ["SEO", "Recovery"]
Encoding UTF-8 with BOM (Excel-safe) UTF-8 with unescaped Unicode
Opens in Excel, Numbers, Sheets, any text editor VS Code, jq, any language stdlib
File size (10k posts) ~3.5 MB ~5.2 MB (pretty-printed)
Quoting / escaping Auto-escaped by fputcsv() Auto-escaped by wp_json_encode()

When CSV is the right call

If the next step is opening the file in a spreadsheet, CSV every time. The pipe-separator on multi-value fields might look ugly, but it’s a deliberate choice — Excel won’t try to split the cell on commas if a category name contains a comma, which they sometimes do. To split pipe-joined cells into multiple columns in Excel, use Data → Text to Columns → Other → |. In Google Sheets, =SPLIT(C2, "|") handles it inline.

When JSON is the right call

If you’re feeding the file into a Node script, a Python pandas pipeline, a static-site generator, or any data store that natively understands arrays, JSON saves you a parsing step. The file looks like this:

[
  {
    "id": 1042,
    "type": "post",
    "title": "Why Did My Traffic Drop",
    "url": "https://example.com/why-did-my-traffic-drop/",
    "status": "publish",
    "date": "2026-04-12 09:30:00",
    "categories": ["SEO", "Recovery"],
    "featured_image_url": "https://indxq.com/wp-content/uploads/2026/04/Simple-Content-Url-Exporter.png,
    "content_image_urls": [
      "https://indxq.com/wp-content/uploads/2026/04/Simple-Content-Url-Exporter.png",
      "https://indxq.com/wp-content/uploads/2026/04/Simple-Content-Url-Exporter.png"
    ]
  }
]

That structure drops directly into a fetch() call, a pandas DataFrame, or a Postgres jsonb column without any further wrangling.

Practical CSV recipes you’ll actually use

Once the file is open in Sheets or Excel, the following recipes cover most of the analysis you’d want to do. They are deliberately simple — sophisticated tooling is rarely needed when the schema is this flat.

  • Split categories into separate rows: in Sheets, paste the data into a new tab and use =ARRAYFORMULA(SPLIT(C2:C, "|")) to expand the joined category strings horizontally. Or use Data → Split text to columns → Custom: |.
  • Count posts per category: use =COUNTIF(C:C, "*SEO*") for posts that include “SEO” anywhere in the joined category list. For exact category matching, split first.
  • Sort posts by recency to find stale content: sort by the date column ascending, then highlight rows older than 24 months for review.
  • Find posts with no featured image: filter the featured_image_url column to “is empty.” These are usually hero-image candidates for a refresh project.
  • Find posts with too many embedded images: add a helper column =LEN(I2)-LEN(SUBSTITUTE(I2,"|",""))+1 to count pipe-delimited URLs. Posts with image counts in the double digits are page-weight candidates worth compressing or trimming.

Practical JSON recipes for developers

If JSON is your output, the typical workflow is to read the file in Node, Python, or a shell with jq and transform it. Three patterns cover most jobs:

# jq: list every URL with no featured image
jq '.[] | select(.featured_image_url == "") | .url' export.json

# jq: deduplicated list of all image URLs across the site
jq -r '.[] | (.featured_image_url, .content_image_urls[])' export.json | sort -u

# Python: load as DataFrame and group by category
import pandas as pd, json
data = json.load(open('export.json'))
df = pd.json_normalize(data)
df = df.explode('categories')
print(df.groupby('categories').size().sort_values(ascending=False))

The encoding question (and why it matters)

CSVs and encoding go together like cats and bath time. Open a CSV that’s saved without a BOM in Excel and watch every accented character render as gibberish. Open a CSV that’s saved as UTF-16 in a Linux pipe and watch every Unix tool choke. Simple Content Exporter writes UTF-8 with a BOM, which is the only encoding combination that works correctly across Excel (which expects the BOM), Sheets (which detects either), Numbers (same), LibreOffice (same), and command-line tools (which see the BOM as three bytes at the start of the file but otherwise process UTF-8 cleanly).

JSON, by contrast, is unambiguous: UTF-8 without BOM, no escaping of non-ASCII characters, no escaping of forward slashes. The plugin uses JSON_UNESCAPED_UNICODE and JSON_UNESCAPED_SLASHES for exactly this reason — the file should look the same when you open it as it does when a script reads it.

8. Real-World Use Cases (With Recipes You Can Steal)

Use case 1 — The “what’s even on this site?” content audit

You’ve inherited a WordPress site with eight years of accumulated content and you have no idea what’s there. Export everything as CSV, sort by date ascending in your spreadsheet, and flag posts older than five years that have no organic traffic in your analytics export. The intersection — old and dead — is your delete-or-redirect candidate list. This is the same workflow used during helpful-content algorithm recovery, where pruning thin content is half the battle.

Use case 2 — Image CDN migration

You’re moving from local media library hosting to a CDN like Cloudflare Images or BunnyCDN. You need a list of every image URL currently referenced on the site so you can reupload and rewrite. Export as JSON, parse featured_image_url and content_image_urls into a single deduplicated set, and feed that into your migration script. The plugin’s deduping logic prevents you from uploading the same image fifteen times because it’s referenced fifteen places.

Use case 3 — Editorial spreadsheet for outsourced rewriting

You hired an editor to rewrite thirty old posts. They want a Google Sheet, not WordPress access. Export posts (status: publish) as CSV, drop it into Sheets, add a Status and Notes column, share the sheet. They work. You review. You paste the rewrites back into WordPress yourself. Everyone gets what they want.

Use case 4 — Pre-redesign content inventory

Before a redesign, you need to know what content you’re actually preserving versus deprecating. The CSV becomes your master inventory document, with one row per page, annotated with “keep / merge / redirect / delete.” If you’re approaching a WordPress redesign, do this exact step on day one of the project. Designers thank you. Developers thank you.

Use case 5 — Migrating off WordPress entirely

You’re going headless, going to Ghost, going to Astro, going somewhere. The JSON output is your baseline. Whatever importer you write or use will need a normalized list of posts, titles, dates, categories, and images — that’s exactly what this file provides.

Use case 6 — Database hygiene

Sometimes the export reveals the problem. You see 14,000 rows in a CSV when you thought you had 800 posts, and suddenly you’re investigating why your post table is bloated with auto-drafts and orphan revisions. That’s a different problem to solve — start with how to clean up your WordPress database for SEO — but the export was the diagnostic.

Use case 7 — Pruning categories that have indexing issues

Some categories pull in indexing problems for reasons that aren’t obvious until you see them in a flat file. Run an export, group rows by category, count posts per category, and look for categories with one or two posts (these are usually the indexing offenders). The fix lives in WordPress categories indexing issues, but the data fueling the decision is exactly the spreadsheet this plugin produces. Without a flat list of (post → category) pairs, the analysis is invisible.

Use case 8 — Surfacing thin content for content pruning

Pivot your CSV by date, then by category, and you’ve got an instant view of where your content is concentrated and where it’s stale. Posts older than three years that haven’t been updated, in a category that’s no longer strategically relevant, are deletion candidates. This is the same dataset you need for helpful content update recovery: you cannot prune what you can’t see in one view.

Use case 9 — Measuring image weight on your site

Concatenate all content_image_urls values, deduplicate, and you have an upper bound on how many distinct images your site references. If that count is in the high thousands while your uploads folder reports the same number of files, your media library is fully utilized. If the count is much lower than your upload count, you have orphaned attachments — files in uploads that no live post references. That’s a real, recoverable amount of disk space and a useful data point before any media-library cleanup project.

Use case 10 — Migration validation

After any large migration — Webflow to WordPress, Squarespace to WordPress, between two WordPress installs — you want to verify that “everything came across.” Export from the new site and compare row counts, URLs, and category coverage against your pre-migration list. Anything missing is something you forgot to migrate. This is the post-flight checklist for projects like migrating from Webflow to WordPress, where a single dropped category mapping can cost rankings.

Use case 11 — Generating a sitemap baseline for QA

A CSV of every published post and page is, structurally, very close to a flat sitemap. You can use it to spot-check your real sitemap output against what should be there. If the export shows 412 published posts and your sitemap shows 387, you have an indexability gap to investigate.

Use case 12 — Building a content map for newsroom or agency clients

When agencies onboard a new client, the first thing they need is a complete content inventory. The CSV becomes the master document attached to the kickoff project plan. Twelve months later, exports run quarterly become the timeline of how the site grew or contracted under the agency’s stewardship.

9. How Simple Content Exporter Compares to Other Plugins

There are bigger, more featureful exporters in the WordPress ecosystem. None of them solve the same problem. Here’s how the landscape actually looks when you put them side by side:

Feature Simple Content Exporter WP Built-in (WXR) WP All Export Export Media Library
CSV output✓ Native✗ XML only✓ Premium✗ ZIP only
JSON output✓ Native✓ Premium
Categories included✓ Joined / array✓ Embedded in XML✓ Configurable
Featured image URL~ (referenced)~ (file only)
Inline content image URLs✓ Auto-extracted~ (in HTML body)✗ Not by default
Free tier sufficient~ Limited
Plugin size~30 KBcore~3 MB~200 KB
Setup time30 seconds05–15 minutes1 minute
Telemetry / opt-in nagsNoneNoneYesSome

Read that table not as “ours wins” but as “tools have different shapes.” If you want a full site replication, the built-in WXR exporter or a backup plugin is the right answer. If you need a heavyweight, configurable export builder with custom field support and joined taxonomy rules, WP All Export is the right answer. If you need a flat, fast, image-aware spreadsheet of your content, Simple Content Exporter is the right answer.

Where this plugin loses

It does not export custom fields, custom taxonomies, ACF data, post meta, comments, tags as separate columns, or media library files. It does not support scheduled exports, cron jobs, or email delivery. If you need any of that, you’ve outgrown this tool — and that’s fine. Use a heavyweight exporter. Most sites don’t need any of those features for most jobs.

The “why not just write a SQL query?” alternative

A senior developer reading this might reasonably ask: why not skip the plugin entirely and run a query? The answer is that the query you’d actually need is not trivial. To reproduce the export, you’d need to join wp_posts against wp_term_relationships and wp_terms to get categories, then join against wp_postmeta with meta_key = '_thumbnail_id' and again against wp_posts to resolve the thumbnail’s full-size URL, then run a regex over post_content to extract embedded image URLs. That’s three joins and a regex, plus permalink generation, plus correct date timezone handling. Doable. Not something you want to redo every time someone asks for a content export.

The plugin does that work once and stays out of your way. If you’d still rather write the SQL — fine. If you’d rather not — install the plugin.

Where the plugin sits in a larger toolkit

A realistic SEO and editorial toolkit usually looks something like this: a backup plugin (UpdraftPlus or BlogVault) for restore, an SEO plugin (Yoast or Rank Math) for on-page meta and sitemaps, a caching plugin for performance, an analytics integration for traffic data, and one or two utility plugins for occasional jobs. Simple Content Exporter sits in that last bucket. It’s not something you interact with every week. It’s something you reach for when you have a specific question that requires a flat view of your content. The rest of the year, it sits there using zero resources because nothing on the front end ever invokes it.

On the SEO plugin question specifically — if you’re trying to decide between Yoast and Rank Math, the Rank Math vs Yoast comparison is a separate but related read. Whichever you pick, this plugin sits cleanly alongside it because it doesn’t touch front-end SEO concerns at all.

10. Pros and Cons

A clear-eyed view of where this plugin fits and where it doesn’t:

Pros

  • Single PHP file, ~30 KB, no dependencies
  • Two-click export — no configuration screen
  • Includes inline content image URLs (rare in this category)
  • UTF-8 BOM means Excel opens accents and CJK cleanly
  • Both CSV (for humans) and JSON (for scripts)
  • Capability-gated and CSRF-nonced — secure by default
  • No external network calls, no telemetry, no upsells
  • GPL-2.0+ — fork it, modify it, redistribute it
  • Reads only — cannot corrupt your database

Cons

  • Posts and pages only by default — no custom post types yet
  • No tags, custom taxonomies, or post meta in v1
  • No cron / scheduled exports
  • No filtering by author, date range, or category
  • Loads all matching posts in memory — sites with 50k+ posts may need to raise PHP memory limit
  • No email delivery of exports
  • Single-language admin UI (English only in v1)
  • No undo, no history — every export is fresh

Most of the cons on the right are deliberate. Adding cron, email delivery, and 12 filter options would put us in the same product category as plugins that take fifteen minutes to learn. The whole point of this tool is that it doesn’t.

11. Troubleshooting Common Issues

“The download doesn’t start when I click the button”

Almost always a security plugin (Wordfence, iThemes Security, Sucuri) blocking the admin-post.php request because it doesn’t recognise the action. Whitelist the action sce_export or temporarily disable the security plugin’s request inspector and try again. If your host has a WAF in front of WordPress, check there too.

“The CSV opens with weird characters in Excel”

This shouldn’t happen — the plugin writes a UTF-8 BOM at the start of the file, which tells Excel “this is UTF-8, render it correctly.” If it still happens, you’re probably on a very old Excel build (2007 or earlier) or LibreOffice with a non-default import setting. Open the file via Data → From Text and explicitly select UTF-8 encoding. Or use Google Sheets, which always gets it right.

“PHP fatal: allowed memory size exhausted”

Your site has a lot of posts and your memory_limit is too low. Edit wp-config.php and add define('WP_MEMORY_LIMIT', '512M');. If your host blocks that, the next option is to chunk the export — see the advanced section. Sites in the 5,000–20,000 post range usually run cleanly at 256 MB; sites past 50,000 posts should chunk by date.

“Featured image URLs are missing for some posts”

The plugin reads get_post_thumbnail_id(). If a post has no featured image set, or if the original attachment was deleted, the URL will be empty for that row. This is correct behaviour, not a bug.

“Content image URLs include weird ones I don’t recognise”

The extractor reads every <img src=""> in post_content. That includes images embedded by gallery plugins, oEmbed thumbnails, third-party widgets, and tracking pixels with image-like URLs. If you see URLs you didn’t expect, that’s actually useful — it’s surfacing what’s in your content. You can filter the list after export.

“I clicked Download Export and got a 403 / permission denied”

Your user role lacks manage_options. Only administrators can export. If you’re an editor or author, ask an admin to either run the export for you or grant your role the capability with a role-management plugin.

“My site is slow on mobile after I install it”

This plugin doesn’t load anything on the front end. If your site got slower, it’s coincidence — something else changed. Read why your WordPress site is slow on mobile to diagnose the actual cause.

“The download starts but the file is empty or 0 bytes”

Two possible causes. The first is that your status filter excluded everything — for example, you selected “Drafts” on a site that has no drafts. Check the status dropdown. The second is a server-side output_buffering setting that’s swallowing the response. In php.ini, set output_buffering = Off or have your host check it. Some managed hosts also gzip output mid-stream, which can occasionally interfere with binary-style CSV download streams.

“I get a redirect loop or get bounced to the dashboard”

Usually a session/cookie issue with WordPress’s nonce check, often caused by an aggressive caching plugin or a CDN that’s caching admin-post.php requests. Make sure your caching layer excludes /wp-admin/ and /wp-login.php entirely — caching admin requests is a common misconfiguration that breaks more than just this plugin.

“The CSV opens but Excel splits cells weirdly”

Excel’s CSV import has different behaviour depending on your locale. In some European locales, Excel treats semicolons as the delimiter rather than commas, so a US-style CSV will look like one giant column. Either change your locale’s list separator setting, use Data → From Text with the explicit comma delimiter, or open the file in Google Sheets, which always handles US-style CSV correctly.

“I want to limit the export by date or category”

Not supported through the UI in v1, but easy to add via the collect_data() method by extending the WP_Query args. See the advanced section. A future release will likely expose date and category filters on the form.

“My host kills the request after 30 seconds”

Some shared hosts impose a hard PHP execution timeout. For sites in the 5,000+ post range, the export may need 60 to 120 seconds depending on database performance. Either raise max_execution_time (or have your host raise it), or chunk the export using the technique in the advanced section. WP-CLI invocations bypass the web-request timeout entirely.

12. Advanced Customization & Developer Tips

The plugin is intentionally hackable. The whole thing is one class in one file, under 250 lines. Three customizations cover almost every “I wish it also did X” request.

Add a custom post type to the export

Find the collect_data() method. The first argument is an array of post types that gets passed to WP_Query. Add your CPT slug:

// Before
$post_types = array_intersect( $post_types, array( 'post', 'page' ) );

// After — also allow 'product' and 'article'
$post_types = array_intersect( $post_types, array( 'post', 'page', 'product', 'article' ) );

Then add a matching checkbox on the admin form. That’s it. Five lines total.

Add tags as an extra column

Inside the loop in collect_data(), add:

$tags = wp_get_post_tags( $post->ID, array( 'fields' => 'names' ) );
$tags = is_wp_error( $tags ) ? array() : $tags;
// then in the row array:
'tags' => implode( '|', $tags ),

And add a matching 'Tags' entry to the CSV header array and the JSON output map. Done.

Chunk the export for very large sites

Replace posts_per_page => -1 with a paginated loop using posts_per_page => 500 and paged => $i. Stream each chunk to the same open file handle. This keeps memory usage flat regardless of post count. If your site is large enough that you hit this, you almost certainly also want to read about cleaning up your WordPress database for SEO while you’re in there.

Filter what gets exported with a hook

A reasonable v2 enhancement is exposing a filter:

$rows = apply_filters( 'sce_export_rows', $rows, $post_types, $post_status );

Then any other plugin or your theme’s functions.php can mutate the row set — drop posts older than a date, redact certain authors, normalize URLs, anything.

WP-CLI command (optional)

If you’d rather export from the command line, register a CLI command that calls collect_data() directly and writes to STDOUT:

wp eval-file export.php > export.csv

This is the path most agencies take when they want to schedule exports via cron without going through the admin UI.

Add date-range filtering

To export only posts published after a given date, extend the WP_Query args with date_query:

$query = new WP_Query( array(
    'post_type'      => $post_types,
    'post_status'    => $post_status,
    'posts_per_page' => -1,
    'date_query'     => array(
        array(
            'after'     => '2024-01-01',
            'inclusive' => true,
        ),
    ),
) );

Wire that to a date input on the form, and you’ve got date-bounded exports without rebuilding anything. If you’re working through a Google Core Update recovery, you usually want to limit the export to posts published or modified after the update date — this is the change that does it.

Export the post excerpt as well

Useful for editorial workflows where the editor wants to read the existing meta description and rewrite it. Inside the loop:

'excerpt' => get_the_excerpt( $post ),

Then add it to both the CSV header array and the JSON output mapping. Three lines.

Add post author name

Inside the loop:

'author' => get_the_author_meta( 'display_name', $post->post_author ),

Useful for multi-author sites where you want to attribute content for editorial workflow tracking.

Add modified date as a separate column

The default export uses publish date. For pruning workflows, you usually want last modified date — that’s the metric that matters for “is this content actually being maintained”:

'modified' => $post->post_modified,

Strip query strings from image URLs

Some sites have image URLs with cache-busting query strings appended (?v=1234567). For migration work, you usually want the canonical URL without those. Extend the extract_image_urls method:

$urls = array_map( function( $u ) {
    return strtok( $u, '?' );
}, $urls );

Then deduplicate again. Cleaner output, identical migration target.

Performance benchmarks (so you can plan)

Rough numbers from a mid-tier shared host (4 GB RAM, PHP 8.1, MySQL 8):

Site sizeCSV timeJSON timeMemory peak
500 posts~1.2 s~1.4 s48 MB
2,000 posts~3.8 s~4.5 s96 MB
10,000 posts~16 s~21 s180 MB
30,000 posts~58 s~72 s420 MB

Past about 20,000 posts, the chunked-export pattern from the start of this section becomes mandatory rather than optional, because most shared hosts cap PHP at 256 MB.

13. Security & Best Practices

Any tool that exports your content is, by definition, a tool that can leak it if misused. The plugin is built with three guardrails by default, but you should think about them yourself before deploying it on production.

Capability check

Both the admin page render and the export handler call current_user_can( 'manage_options' ) and bail out otherwise. This is the standard WordPress capability for site administrators. If your site uses a custom role structure, audit which roles you’ve granted manage_options to — that’s the list of people who can export.

Nonce protection

The download form ships with a nonce called sce_export_nonce. The handler verifies it on every submit, so a third-party site can’t trick a logged-in admin into triggering an export by embedding a malicious form on another page.

Where the export ends up

The file is streamed directly to the browser as a download. It’s not written to wp-content/uploads, not stored in the database, and not cached. Once the download finishes, the only copy is on the user’s machine. That’s intentional — exports sitting on disk are a liability.

Operational tip: if you outsource site management, scope which IP addresses can reach /wp-admin at the firewall level. The plugin is well-behaved, but the principle of “if you don’t need to log in, you shouldn’t be able to” applies regardless of what plugins are installed.

What this plugin does not do

It doesn’t write to your database. It doesn’t modify posts. It doesn’t change settings. It doesn’t talk to external servers. It doesn’t enqueue scripts on the front end. It doesn’t add a dashboard widget. It doesn’t email anyone. The blast radius of installing it is, conservatively, one new admin page and one new menu item. Removing it has zero side effects.

Multi-admin scenarios and audit trails

On sites with multiple administrators — agencies, newsrooms, multi-author blogs — the question of “who exported what, when” sometimes comes up. The plugin itself does not log exports, by design (logging would mean writing to the database, which we’ve already said it doesn’t do). If you need an audit trail, the cleanest path is to use one of the general-purpose admin activity loggers — Simple History, WP Activity Log, or a server access-log analysis tool. Any of them can record the moment when an admin requests admin-post.php?action=sce_export, which gives you the audit signal without requiring the plugin to maintain its own log table.

For high-trust environments where exports might contain sensitive draft content, consider pairing this plugin with a two-factor authentication plugin and an IP allowlist on the admin panel. The plugin’s capability check ensures only administrators can trigger the export, but the broader question of “who can become an administrator on this site” lives outside this plugin’s scope.

The threat model, stated plainly

The plugin is a read-only mechanism that turns existing WordPress data into a downloadable file. The realistic threats are: a malicious admin exporting content they shouldn’t (this is a permissions problem, not a plugin problem); a CSRF attack tricking a logged-in admin into triggering an export to a destination they don’t control (mitigated by the nonce); or a vulnerability in WordPress core or another plugin that exposes admin actions to unauthenticated users (mitigated by the capability check, which double-verifies manage_options on the handler before processing). All three are addressed by the default code path. There is no scenario in which a non-admin can trigger an export, and no scenario in which the export goes anywhere other than the requesting user’s browser.

Frequently Asked Questions

Is Simple Content Exporter really free, with no upsells?

Yes. It’s licensed under GPL-2.0-or-later, the same license WordPress itself uses. There is no premium tier, no paid add-on, no email-capture wall, and no opt-in telemetry. The whole plugin is one PHP file you can read top-to-bottom in five minutes.

Will it export my custom post types like WooCommerce products?

Not in v1.0.0. The default export covers post and page only. Adding a custom post type takes about five lines of code — see the advanced customization section above for the exact change. A future release will likely add CPT support behind a checkbox.

How big a site can it handle?

Sites with up to about 20,000 posts typically run cleanly on a 256 MB PHP memory limit. Past that, you’ll want to chunk the export — the advanced section shows how. The plugin doesn’t impose a hard limit; PHP’s memory limit does.

Does it include images embedded inside the post content?

Yes, by default. There’s a checkbox on the export form labelled “Include images from content.” When it’s ticked, every <img src=""> in post_content is extracted, deduplicated, and added to a content_image_urls column alongside the featured image URL. Most other lightweight exporters skip this.

Will it slow down my website?

No. The plugin loads no scripts or styles on the front end. Its code only runs inside /wp-admin, and only when an administrator visits the export page or submits the export form. Front-end visitors never touch it.

Can editors and authors use it, or only administrators?

Only users with the manage_options capability — by default, only administrators. If you need editors to be able to export, either run exports for them yourself or use a role-management plugin to grant the capability. We recommend the former for security reasons.

Does it work on WordPress multisite?

Yes. Network-activate it from the network admin, or activate per-subsite. Each subsite’s exports are scoped to that subsite’s content, which is almost always what you want. There is no network-wide combined export in v1.

How do I uninstall it cleanly?

Plugins → Installed Plugins → Deactivate → Delete. Because the plugin doesn’t write to your database, there is nothing left over to clean up. No orphan tables, no leftover options, no transients. It’s as if it was never there.

Will the export break if my site uses a page builder like Elementor or Bricks?

No. The plugin reads post_content as it’s stored, then extracts <img> tags from the rendered HTML. Page-builder content is stored in post_content too (sometimes alongside builder-specific meta fields), so titles, dates, categories, featured images, and any rendered <img> tags will all export correctly. Builder-specific dynamic content that’s resolved at render time may not appear if it’s not embedded in the saved HTML.

Can I schedule recurring exports — daily, weekly?

Not via the UI in v1. The plugin is a one-shot manual exporter by design. If you need scheduled exports, the cleanest path is to call collect_data() from a WP-CLI script and run it via your server’s cron. The advanced section sketches how. A future release may include a built-in scheduler.

Why doesn’t it export tags or custom taxonomies?

To keep the file small, the schema flat, and the column count predictable for spreadsheet workflows. Tags, custom taxonomies, and post meta vary wildly across sites — adding them would mean either bloating every export or adding configuration screens, both of which fight the plugin’s core design. Adding a tags column manually is a 5-line change documented above.

Is the export GDPR / privacy compliant?

The export contains only post content that’s already public on your site (titles, URLs, categories, image URLs, dates). It does not include personal data such as author email, commenter identity, or user meta. As always, the responsibility for what you do with the file once it leaves your server is yours.

Download Simple Content Exporter and Run Your First Export Today

If you’ve ever needed a clean spreadsheet of what’s on your WordPress site — for an audit, a migration, a redesign, an editorial handoff, or a CDN move — this is the file you should have shipped with your install. It’s free, it’s GPL-2.0+, it’s one PHP file, and it does one job extraordinarily well. Install it, run an export, see what your site actually looks like as a spreadsheet, and decide what to do next.

For everything else — diagnosing traffic drops, fixing technical SEO issues, or thinking through a redesign — the website audit, redesign, and WordPress setup guides on indxq.com pick up where this plugin leaves off.

↓ Download the .zip (Free) View install steps

IQ

Sayed Iftekharul Haque — SEO Strategist & Web Designer

Founder of IndXQ. Specialises in SEO-first website redesigns, Core Web Vitals, and digital growth strategy. Available for projects via Fiverr, Upwork, and direct engagements. Connect on LinkedIn or watch free SEO tutorials on YouTube.

Published by IndXQ · Web Strategy & SEO · April 2026 · All rights reserved.

Scroll to Top