Description
Broken links, missing meta descriptions, duplicate H1s, unembedded YouTube videos — small technical issues that quietly cost you rankings and clicks every day. SEOMedic finds all of them in one place and gives you the tools to fix them fast.
No more crawling through posts one by one. No more spreadsheets. One dashboard, every issue, fixed in minutes.
🔗 Broken Link Detection
Scan every post and page for broken external links. SEOMedic checks the live HTTP status of each URL and flags anything returning an error. Fix the URL inline — no need to open the post editor — then re-check immediately to confirm.
📝 Missing & Broken Meta Descriptions
See every post missing a meta description in one sorted list. Flags meta descriptions that are too short (rewritten by Google) or too long (truncated in SERPs).
🔍 Focus Keyword Assistant
See every post missing a focus keyphrase. Bulk-sync focus keywords to Yoast SEO or Rank Math with one click.
🧹 Content Pruning & Redirects
Find low-performing posts that drag the rest of your site down. Save 301 redirect targets per post (stored locally — no external service). Decide which trashed posts should redirect somewhere and which should 404 cleanly.
🖼️ Image Optimisation
Rename uploaded image files to SEO-friendly basenames, audit alt-text coverage, and find images embedded without dimensions.
H1 Tag Issues
Posts with more than one H1 confuse search engines. SEOMedic lists every offending post and shows you the exact text of each H1 so you know which ones to demote to H2 or H3.
▶️ YouTube & Video Issues
Three video problems caught in one panel: plain YouTube links that will never auto-embed, Gutenberg embed blocks missing the 16:9 aspect ratio class, and Classic Editor iframes with hardcoded dimensions that break on mobile.
🔀 Internal Link Health
Find orphan posts with no inbound internal links, and spot link opportunities where another post on your site already mentions the topic but does not link to it.
🗺️ Sitemap & Schema Audits
Verify your sitemap is reachable and well-formed. Scan every post for Schema.org markup coverage and surface missing types.
⚡ Core Web Vitals (optional)
Connect a free Google PageSpeed Insights API key and audit your site’s Core Web Vitals (LCP, INP, CLS) per page. The API key is yours — the plugin never proxies through us.
⚙️ Bulk Link Management
Browse every link across your entire site in one table. Apply nofollow, sponsored, UGC, or open-in-new-tab to hundreds of links at once. Find and replace a URL site-wide in seconds.
Works with Yoast SEO and Rank Math
Meta descriptions and SEO titles sync with Yoast SEO or Rank Math if active. Falls back to the native post excerpt when neither is installed.
Want AI generation, Search Console, and Bing?
Those features live in the separate SEOMedic Pro add-on plugin, which you can install alongside this one. Pro adds AI meta/title generation (Claude), Google Search Console integration with CTR opportunity scoring, Bing Webmaster Tools integration, and a Gutenberg post-insights sidebar. Install Pro from your account at the plugin author’s site — it is not hosted here.
External Services
This plugin only contacts third-party services in the two cases listed below, and only when you have explicitly opted in or provided your own credentials.
Google PageSpeed Insights API
- What it does: Retrieves Core Web Vitals (LCP, INP, CLS) for individual page URLs so you can audit performance.
- When it connects: Only when you have entered a PageSpeed Insights API key under SEOMedic Settings and you run the Core Web Vitals audit.
- Data sent: The page URL being audited. No post content, no user data.
- Service URL: https://www.googleapis.com/pagespeedonline/v5/runPagespeed
- Privacy Policy: https://policies.google.com/privacy
- Terms of Service: https://developers.google.com/terms
Freemius
- What it does: Handles plugin activation, opt-in usage telemetry, and software updates.
- When it connects: Upon plugin activation (opt-in only — users are shown a notice and can skip data sharing). Also during licence verification and update checks.
- Data sent: Site URL, WordPress version, plugin version, PHP version, and (if opted in) admin email address.
- Service URL: https://wp.freemius.com/
- Privacy Policy: https://freemius.com/privacy/
- Terms of Service: https://freemius.com/terms/
Source code & build instructions
The React admin UI in admin/build/ is built from the human-readable
TypeScript/TSX sources in admin/src/, which are included in this zip.
No third-party AI/Claude code is bundled into the free distribution —
those features live in the separate SEOMedic Pro add-on plugin.
To rebuild the admin UI from source:
cd admin
npm install
npm run build
Build tool: Vite 6 with @vitejs/plugin-react. See admin/package.json
and admin/vite.config.ts for the full configuration. The output is
written to admin/build/index.js and admin/build/index.css.
Screenshots






Installation
- Upload the
seomedic-seo-link-auditorfolder to/wp-content/plugins/, or install via Plugins Add New in your WordPress admin. - Activate the plugin through the Plugins screen.
- Navigate to SEOMedic in the WordPress admin sidebar.
For Core Web Vitals audits (optional):
- Get a free Google PageSpeed Insights API key.
- Enter it under SEOMedic Settings Performance.
FAQ
-
Does this work with any theme?
-
Yes. The plugin operates entirely through the WordPress admin area and the REST API — it is theme-independent.
-
Which SEO plugins are supported for focus keywords?
-
Yoast SEO and Rank Math. SEOMedic is compatible with both — use it as an SEO booster alongside either plugin. If neither is installed, the focus keyword is stored in the plugin’s own post meta field.
-
Will editing links here change my post content?
-
Yes. When you save a link change the plugin updates the post content in the database via the WordPress REST API, exactly as if you had edited the post in the block editor.
-
Does this plugin send any data to external servers?
-
Link checking, meta description scanning, focus keywords, redirect saving, image rename, H1/video/schema/sitemap detection, and internal link health all run entirely within your WordPress site.
Two optional connections exist:
- If you opt in to Freemius on activation (it shows a notice — you can skip), your site URL, WordPress version, PHP version, and admin email are sent to Freemius for licence management and usage telemetry.
- If you provide a Google PageSpeed Insights API key and run the Core Web Vitals audit, the plugin sends each page URL to Google PageSpeed Insights.
Nothing else leaves your server.
Reviews
There are no reviews for this plugin.
Contributors & Developers
“SEOMedic — SEO Booster & Link Auditor” is open source software. The following people have contributed to this plugin.
ContributorsTranslate “SEOMedic — SEO Booster & Link Auditor” into your language.
Interested in development?
Browse the code, check out the SVN repository, or subscribe to the development log by RSS.
Changelog
2.15.1
- Improved (Pro): the Ranked Queries panel in the post editor sidebar now explains itself. Every chip (position, clicks, impressions, search volume, and the “×N in post” phrase count) has a tooltip, and the “×N in post” count is now explicit that it’s context, not a target — the panel already shows real cases of pages ranking well for a phrase that appears zero times in the post.
2.15.0
- Fixed: a 301 redirect set in Content Pruning stopped working the moment you removed the page — which is exactly when it was needed. Redirects only applied while the page was still published, so trashing, deleting or unpublishing it left the old address returning “not found” instead of passing visitors and Google to the replacement. Redirects are now stored independently of the page and keep working after it is gone, whichever order you do things in. Redirects you set before this update are repaired automatically.
- Improved: you no longer need to know the destination address to set a redirect or a canonical. Start typing and search your own posts and pages by name, then pick one — including a one-click Homepage option for pages with no good match. Pasting a full address still works for sending visitors elsewhere. The same picker is now used for the trashed-post prompt and the Broken URL Monitor.
- Improved: the Content Pruning explainer now spells out the order to follow — set the redirect first, then remove the page.
2.14.1
- Fixed: a “Pro adds a Claude semantic deep-scan…” upgrade hint could appear near Find & Replace even on fully licensed Pro installs. The check compared a value WordPress always passes to the browser as text (“1″/””) against the exact boolean
true, so it could never match. Also fixed the same mistake in the Claude API key check, which could make configured installs show “Configure your API key” until you switched browser tabs and back.
2.14.0
- Improved: the statistics at the top of the dashboard (total links, external, internal, broken, redirects, nofollow) are now counted on the server and cached, instead of being worked out in your browser from the full content of every post. They appear from a single small request rather than waiting for the whole site’s content to download, and your browser no longer parses every post just to count links. The figures refresh automatically whenever you edit content or rescan.
2.13.19
- Fixed: the dashboard now loads as a single file instead of thirty separate ones. Splitting it up saved a little download size but was the source of every “section failed to load” problem — files cached from an old version, thirty simultaneous requests competing with the dashboard’s own data, and failures the browser refuses to retry. One file cannot hit any of those. Slightly larger first download, then cached until the next update.
2.13.18
- Fixed: the real cause of sections failing to load after an update. Section script filenames did not change between releases, but their contents did, so browsers kept serving a cached copy from the previous version alongside the freshly updated main script — a mismatch that made those sections fail permanently until the cache was cleared. Section filenames now include the plugin version, so every release gets fresh URLs and a stale copy can never be used.
- Improved: when a section does fail this way, the message now explains it is a cached-file problem and offers to reload, rather than describing it as a firewall issue.
2.13.17
- Fixed: section scripts no longer download while the dashboard is still loading its data. Every section requested its script the moment the dashboard appeared, competing with the data requests for the browser’s limited connections — on busy servers a few sections consistently lost that race and failed to load. They now wait until the data is in.
- Fixed: when a section’s script does fail, the recovery button now reloads the page instead of retrying in place. A failed script cannot be re-fetched by the browser without a fresh page load, so the old “Try again” could never succeed.
- Improved: diagnostics now record the actual error for a failed section script, not just that it failed.
2.13.16
- Fixed: the dashboard could reload itself in a loop, dropping back to the loading screen after it had already appeared. A 2.13.14 change removed the one-time retry marker from the URL but the loop guard was still reading it from there, so every failure looked like the first one and the reload cap never applied.
- Fixed: the dashboard no longer reloads at all once it is on screen. A section whose script fails now shows an error in just that section, instead of discarding a load that can take half a minute — and because reloading cancels in-flight requests, one failure was cascading into several.
- Improved: section scripts are retried for longer (5 attempts over ~30 seconds, up from 3 over ~1 second). On busy servers these requests queue behind the dashboard’s data requests, and the old budget gave up long before their turn came.
2.13.15
- Improved: the dashboard makes far fewer requests to your server on load. Four separate requests are now one, and Search Console / Bing data is loaded by an explicit “Load search data” button instead of automatically. Every request has to start WordPress from scratch, which on shared or busy hosting is the slowest part of opening the dashboard — this removes most of them.
- Improved: Search Console position and keyword history now records once a day in the background, so trends and Biggest Movers keep building whether or not you open the dashboard. Previously history only accumulated on days you loaded the dashboard.
- Improved: AI-referrer counting no longer writes to the database on every visit to your site. Counts are batched (using your object cache when available) or sampled, which removes a database write from every front-end page view.
2.13.14
- Fixed: the one-time asset-retry flag was never removed from the dashboard URL, so it stayed in the address bar and appeared in server logs long after the issue it recovered from was resolved — and it left the recovery unable to run again. It is now cleared as soon as the dashboard loads successfully.
2.13.13
- Improved: the diagnostics log now resets automatically when the plugin updates, and stamps every line with the version that produced it. Previously the log carried over across updates, so after installing a fix it still displayed the old version’s errors as though they were current.
2.13.12
- Fixed: dashboard section chunks (Sitemap Audit, Schema Audit, Broken URL Monitor, and others) could fail to load, sometimes leaving the dashboard stuck reloading. The build was generating chunk URLs relative to the site root instead of the plugin’s own folder, so on some hosts/install paths the browser requested them from the wrong location entirely. Chunk URLs are now resolved relative to the plugin’s own script, regardless of install path.
2.13.2
- Improved: Low-resource mode is now much more effective on limited or shared hosting. In addition to loading in smaller batches, it caches the post list — on the server (per page, cleared automatically whenever you edit or delete a post) and in your browser for the session — so reloading the dashboard no longer re-runs the heavy full scan against your server. A rescan or refresh still pulls fresh data. Normal mode is unchanged: nothing is cached unless low-resource mode is on.
2.13.1
- Fixed: opening the “Just Started Ranking” or “Keyword Explorer” report could crash the dashboard with a “removeChild” error once the data loaded. The two new sections updated their results on a different rendering priority than the loading indicator, which let React commit the two changes out of order. They now update together, matching every other section.
2.13.0
- New: Keyword Explorer — a sortable, filterable table of every search query your site appears for, right inside WordPress. Sort by impressions, clicks, CTR or position; filter by minimum impressions or position band (1–3, 4–10, 11–20, 21+); and type to filter by keyword. No need to switch over to Search Console.
- Each row shows the page that ranks best for the query, and flags when more than one of your pages competes for it (a keyword-cannibalization hint) — something Search Console makes you switch tabs to see.
- Bing Webmaster Tools impressions and position are shown as bonus columns when Bing is connected, matched by query text.
- Note: Google withholds queries from too few unique users, so the totals read slightly lower than your true traffic and won’t exactly match Search Console.
2.12.2
- Fixed: long search queries in the dashboard widget’s Top Queries lists ran past the edge of the widget and over the next dashboard column instead of being shortened.
- Improved: near-identical long-tail queries are now grouped into a single row with a “+N similar” note and their impressions combined. Bing in particular reports families of machine-generated queries that differ only in their last few words, and five variants of one phrase were filling the whole list. Short queries are never grouped, so genuinely different terms stay separate.
2.12.1
- Fixed: pages could appear twice in the dashboard widget’s Top Pages table — once with Google numbers and once with Bing — because the two integrations were normalising URLs differently after the 2.11.3 change. They now share one implementation.
- Fixed: the Top Pages table could run past the edge of the dashboard widget when both Google and Bing were connected. It now scrolls within its own box.
- New: “Just Started Ranking” now also appears on your WordPress dashboard widget, showing the three most recent pages with their top query. Press Sync now to populate it.
- Improved: if the plugin hits an unexpected error, the report now names the component involved, which makes it far easier to diagnose.
2.12.0
- New: “Just Started Ranking” — a dashboard section showing pages that got their first-ever Google impressions in the last 7, 14, or 28 days, along with the queries they’re appearing for. Publishing has a long feedback loop; this is the moment a new post stops being invisible in search.
- A page only appears here if it had no impressions at all in the 90 days before the window, so it’s genuinely new visibility rather than a page that comes and goes.
- Expand any row to see the search terms it surfaced for, with impressions, clicks, and average position for each.
2.11.6
- Fixed: Find & Replace still could not find URLs containing “&”. The 2.11.4 fix only handled one of the ways WordPress encodes an ampersand — content is commonly stored using the numeric form (&) rather than &, which the search still missed. All forms — literal, &, &, & and hexadecimal — now match, in both post content and widgets, whichever form you paste into the search box.
2.11.5
- Fixed: the same “&” search problem in Find & Replace also affected widgets, which are searched by the server rather than the browser. Widget search and replace now match encoded and decoded forms of a term, and widget match previews show the correct surrounding text for matches that live inside markup.
- Improved: searching for a term with a space now also matches text where WordPress inserted a non-breaking space.
- Improved: “N of your published pages got zero impressions” on the WordPress dashboard is now a link. It opens the Pages Google Isn’t Showing section directly, so you can decide what to redirect, expand, or prune.
2.11.4
- Fixed: searching Find & Replace for a URL containing “&” (such as an affiliate link with ?ref=…&utm_source=…) found nothing, even when the preview clearly showed that URL. WordPress stores “&” as “&” in post content while the preview displays it decoded, so the text you copied out of the results could never match. Searching now finds both forms, whichever you paste.
- Fixed: the same mismatch affected quotes and angle brackets in search terms.
- Improved: replacements now keep the encoding your content already uses, so replacing a link doesn’t quietly rewrite “&” as a bare “&” elsewhere in the tag.
2.11.3
- Fixed: pages with accented or non-Latin characters in their URL never matched their Search Console data, so they showed no search performance at all and could appear in “Pages Google Isn’t Showing” despite getting traffic.
- Fixed: impressions arriving on tagged URLs (?utm_source=…, ?fbclid=… and similar) were counted as a separate page rather than credited to the real one. They are now merged into the page’s totals, with position and CTR averaged by impressions so a handful of tagged visits can’t skew a page’s average.
- Improved: the dashboard loading screen now says it will open automatically when data has finished loading.
2.11.2
- New: “Pages Google Isn’t Showing” — a dashboard section listing your published pages that Google barely surfaced in the last 90 days, split into pages that got zero impressions and pages sitting under a threshold you choose. Noindexed and redirected pages are excluded, since their absence is intended.
- New: the Google Coverage line on your WordPress dashboard now also shows how many of your published pages got zero impressions — the actionable half of the count.
- Improved: Biggest Movers on the dashboard widget now stacks gaining and slipping full width instead of side by side, so query text is readable rather than cut off.
2.11.1
- Fixed: the top Google query shown for each page was picked arbitrarily rather than by impressions, so pages often showed a minor query instead of the one actually driving views.
- Fixed: automated rank-tracker and scraper queries (long strings full of “-site:” exclusions) are no longer treated as real search terms. They no longer appear as a page’s top query, feed into focus keyword suggestions, or influence generated meta descriptions.
- Improved: query data is no longer limited to terms ranking in the top 20. Pages that rank below position 20 for their main term now show it, giving a fuller picture of what each page is actually found for.
- Improved: the Sync button now refreshes query data too. Previously it only refreshed page-level performance, leaving query data to update on its own six-hour cycle.
- Improved: removed a duplicate Search Console API request — the plugin was fetching the same query dataset twice on every refresh.
2.11.0
- New: the Mixed Content audit now scans your whole site, not just post content. It loads your rendered home page plus a sample post and page — catching insecure URLs in your theme header and footer, nav menus, widget areas, and other plugins’ output — and reads your widget and menu settings directly.
- New: findings are split by severity. Sub-resources loaded over http:// (images, scripts, stylesheets, iframes) are flagged as blocking, because those are what actually break the padlock; plain http:// links are listed separately as lower priority.
- Improved: widget and menu findings link straight to the screen where you can fix them. Theme-sourced URLs are clearly marked as coming from your theme or another plugin.
- Improved: the SEOMedic dashboard widget now appears at the top of your WordPress dashboard by default. If you’ve rearranged your dashboard, your own order is respected.
2.10.0
- New: a “Search Analytics” widget on your WordPress dashboard home. See your search performance without leaving wp-admin.
- New (free): the dashboard widget shows a clearly-labelled sample preview of the Pro search-analytics charts — metric tiles, a clicks trend chart, and a Biggest Movers list — so you can see what upgrading unlocks.
- New (Pro): the widget adds a Biggest Movers section — the queries gaining and slipping the most in Google, each with an inline position sparkline, drawn from your existing snapshot history (no extra API calls).
2.9.0
- New (Pro): Refresh Impact tracking — after updating a post, click “✓ Done” in Refresh Opportunities to snapshot its last 28 days of Search Console data. SEOMedic then compares clicks/day, average position, and CTR before vs after the refresh, so you can see whether the update actually moved the needle.
- New (Pro): a “Recently refreshed — impact” panel at the top of Refresh Opportunities lists every tracked post with its before/after readout; the SEO Performance trend expander shows the same line for tracked posts.
2.8.21
- Fixed (Pro): the Gutenberg sidebar showed “No GSC queries yet for this URL” on www-hosted sites even when the post had Search Console data — the permalink was never matched against the normalised GSC URLs.
- Improved (Pro): LSI keywords missing from the post body now show as red pills (was grey) so gaps stand out at a glance.
- Improved (Pro): the “Load search volumes” buttons now note in a tooltip that each lookup spends Keywords Everywhere credits.
2.8.20
- Fixed: “Plugin could not be activated because it triggered a fatal error” when activating a new version while an older copy (or the free version) was still active. All functions in the main plugin file are now redeclaration-safe, so two copies can coexist during an upgrade and the free Pro auto-deactivation hand-off works as intended.
2.8.19
- Smoother free Pro upgrade: activating SEOMedic Pro now automatically deactivates the free version, so you’re never left with both plugins active and duplicate menus.
2.8.18
- New (Pro): sortable “GSC clicks” column on the Posts and Pages list screens — see 90-day Google Search clicks per post at a glance and sort by it. Populated automatically whenever Search Console data syncs.
- Improved (Pro): the Gutenberg sidebar’s Ranked Queries list now shows a clicks chip next to impressions for each query.
2.8.17
- Added a one-time, dismissible review request in wp-admin, shown two weeks after install. “Maybe later” snoozes it for 90 days; “No, thanks” hides it permanently. No tracking, no external calls — just a link to the WordPress.org review form.
2.8.14
- Fixed (Pro): “Analyze top 20” for AI Search Readiness could stop early with “Could not parse Claude response” — the AI response token limit was too low and truncated longer results. Raised the limit, and the bulk run now skips any post that fails instead of aborting the whole batch.
2.8.13
- Added an inline notice above the dashboard stat cards letting users know that on larger sites the counts can take a couple of minutes to populate, and each section scans on first expand — so a slower load isn’t mistaken for a problem.
2.8.12
- Fixed: rescanning a single section no longer throws you back to the full-screen loading screen (and no longer jumps the page to the top). The full loader now appears only on the first load; rescans show an inline spinner and keep the dashboard in place.
- Added a “Couldn’t load your content” retry screen with the Low-resource mode toggle, shown if the initial scan fails on a resource-limited host — so you can enable gentler loading and try again without getting stuck.
2.8.11
- Fixed a loading flicker where the dashboard briefly showed empty (0) stat cards before data finished loading. The staged loading screen now stays up — showing live progress and the Google Search Console / Bing steps — until your content has actually loaded.
- Clearer loading messaging that the first load can take a minute or more depending on how many posts and pages your site has.
2.8.10
- New “Low-resource mode” toggle on the load screen for shared/limited hosting — loads posts in smaller batches with a pause between them, so the scan is gentler on servers with CPU/memory/entry-process limits. Off by default; remembered per browser.
2.8.9
- Load on demand: the dashboard no longer auto-scans on every page load. It opens instantly with a “Load my content” button, and the heavy scan runs only when you click it (remembered for the session). Big improvement on large sites and resource-limited hosts.
2.8.8
- Resilience: if a dashboard module fails to load (e.g. a stale cached asset behind a CDN right after an update), the page now auto-reloads once to pull fresh files instead of showing an error.
2.8.7
- Performance: the dashboard now loads posts in pages instead of all at once. Large sites (hundreds of posts) no longer hit a server memory error (HTTP 507) on load, and the loading screen shows live progress (e.g. “150 / 504”).
2.8.6
- Added a clearly-marked, staged loading screen so large sites don’t look stuck while data loads.
- Hardened uninstall.php against direct file access.
2.8.5
- Fixed: Claude-powered features (AI Search Readiness, meta generation) could show “Configure Anthropic API key” on first load even when a key was saved — the key status now resolves immediately on page load instead of waiting for a window-focus event.
- Refreshed plugin screenshots and screenshot captions.
2.8.4
- Hardened the React dashboard against browser auto-translate extensions that could cause a “removeChild” crash on the main page.
- Compatibility and packaging polish.
2.4.7
- WP.org compliance pass: removed all Pro-only Claude/Anthropic handler code from the free distribution (moved to the separate SEOMedic Pro add-on plugin). The free zip no longer contains any calls to third-party AI APIs.
- Included the React UI source files (
admin/src/) and build configuration in the zip so the compiledadmin/build/index.jsis reproducible from human-readable source. - Tightened REST API permission checks:
GET/POST /seomedic/v1/settingsnow requiresmanage_options;POST /seomedic/v1/posts/{id}/dismissand/undismissnow verifyedit_poston the specific target post.
2.4.0
- Plugin split for WordPress.org compliance: AI generation, Google Search Console, Bing Webmaster Tools, and Keywords Everywhere features moved to a separate SEOMedic Pro add-on plugin.
- Unlocked: Content Pruning redirect saving and Image File Rename are now available to all users (no Pro requirement).
- Tightened REST API permission checks on
/trashed-pending/{id}/dismissand/check-link. - Renamed plugin text domain to
seomedic-seo-link-auditor(matches plugin slug). - Cleaned readme — removed entries for services this plugin no longer contacts.
2.3.x
- Dashboard refactor — bulk meta operations, scroll-to-top, sitemap audit upgrades, plugin checker fixes.
- Gutenberg post-insights sidebar (moved to Pro in 2.4.0).
- Various fixes for keyword cannibalisation detection, readme stable-tag sync, and WP.org plugin-checker warnings.
1.0.x
- Initial public releases — see git history for full per-version notes.
