# Website SEO Audit — Shopify, WordPress, Wix & More (`anywhere-web-repair/website-seo-audit`) Actor

Crawl any website and get a 0–100 SEO score, ranked findings with step-by-step fixes written for the site's actual platform, a 'handled by your platform' list so nothing is flagged falsely, a 30-day fix plan, and a branded HTML report.

- **URL**: https://apify.com/anywhere-web-repair/website-seo-audit.md
- **Developed by:** [Jeremy](https://apify.com/anywhere-web-repair) (community)
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $10.00 / 1,000 audited pages

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.

Learn more: https://docs.apify.com/actors/running/actors-in-store.md#pay-per-event

## What's an Apify Actor?

Actors are web data automations that power AI and operations. They run on the Apify platform to scrape websites, process data, connect APIs, and automate workflows.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.
Actors are written with capital "A".

## How to integrate an Actor?

If asked about integration, you help developers integrate Actors into their projects.
You adapt to their stack and deliver integrations that are safe, well-documented, and production-ready.
The best way to integrate Actors is as follows.

- **AI agents and MCP clients** — the [Apify MCP server](https://docs.apify.com/integrations/mcp.md) at `https://mcp.apify.com` (remote, streamable HTTP, OAuth on first use).
- **Agentic workflows and local Actor development** — [Agent Skills](https://apify.com/.well-known/agent-skills/index.json) with the [Apify CLI](https://docs.apify.com/cli/docs.md): `npm install -g apify-cli`, then `apify login`.
- **JavaScript/TypeScript projects** — the official [JS/TS client](https://docs.apify.com/api/client/js/docs.md): `npm install apify-client`.
- **Python projects** — the official [Python client](https://docs.apify.com/api/client/python/docs.md): `pip install apify-client`.
- **Any other language** — the [REST API](https://docs.apify.com/api/v2.md).

For usage examples, see the [API](#api) section below.

For more details, see Apify documentation as [Markdown index](https://docs.apify.com/llms.txt) and [Markdown full-text](https://docs.apify.com/llms-full.txt).

# README

## Website SEO Audit — platform-aware

Point it at a website and get back a 0–100 SEO score, ranked findings with **fixes written for the platform the site actually runs on** (Shopify, WordPress, Wix, Squarespace, Webflow), a list of checks the platform already handles for you so nothing is flagged falsely, a week-by-week 30-day fix plan, and a branded single-file HTML report you can send to a client as-is.

Most audit tools shout "no sitemap!" at a Shopify store that has always had one, or tell a WordPress owner to "add a canonical tag" with no idea which admin screen that lives on. This one detects the platform first, downgrades anything the platform manages automatically, and phrases every fix as *where to click*.

### What it checks

Per page: title (present, unique, length), meta description (present, length), exactly one H1, mobile viewport, canonical, `lang`, image alt text (an empty `alt=""` counts as missing — that's what Shopify emits when nobody wrote one), word count / thin content, JSON-LD structured data (present and valid), Open Graph tags, HTTP errors.

Site-wide: robots.txt, XML sitemap (robots-declared location, `/sitemap.xml`, `/sitemap_index.xml`, `/wp-sitemap.xml`, sitemap indexes expanded), server response time (TTFB), identical documents served for different URLs, empty JavaScript app shells.

Platform extras: Shopify password page, `.myshopify.com` primary domain, the four standard `/policies/` pages; WordPress version exposure and missing SEO plugin (Yoast / Rank Math / AIOSEO / SEOPress detected).

### How pages are chosen

The audit reads the sitemap and samples pages **across every section of the site** (products, collections, blog, pages…) so 25 pages still represent a 2,000-page store, then follows internal links to fill any remaining budget. Pages disallowed for all crawlers in robots.txt are skipped (unless you turn that off for a site you own). Add `extraUrls` to force specific pages in.

### Input

| Field | Meaning |
| --- | --- |
| `startUrl` | The homepage. `https://` is assumed if omitted. The crawl never leaves this domain. |
| `maxPages` | Pages to audit (1–500, default 25). Each audited page is one billable event. |
| `includePageRows` | Default on: one dataset row per page in addition to the summary. Off = summary row only. |
| `extraUrls` | Same-domain pages that must be included. |
| `respectRobots` | Default on. |
| `concurrency`, `delayMs` | Politeness controls (default 4 at once, 250 ms between batches). |

### Output

**Dataset** — first row is the summary:

```json
{
  "type": "summary",
  "site": "https://example.com",
  "platform": "shopify",
  "score": 88,
  "categoryScores": { "Technical": 100, "Metadata": 80, "Content": 60, "Mobile": 100, "Performance": 100 },
  "pagesCrawled": 25,
  "totalSiteUrls": 203,
  "findings": [
    { "severity": 2, "severityLabel": "High", "area": "Metadata", "title": "Missing meta descriptions on 11/25 pages",
      "detail": "…", "fix": "In Shopify Admin, open each page or product → \"Search engine listing\" → Edit …", "key": "metadesc" }
  ],
  "handledByPlatform": [ { "check": "XML sitemap", "why": "Shopify auto-generates and serves /sitemap.xml for every store." } ],
  "fixPlan": [ { "week": "Week 1 (Days 1-7)", "items": [ { "title": "…", "fix": "…" } ] } ],
  "reportUrl": "https://api.apify.com/v2/key-value-stores/…/records/report.html"
}
```

then one `"type": "page"` row per page: `url`, `status`, `title`, `titleLength`, `metaDescription`, `metaDescriptionLength`, `h1Count`, `h1`, `hasViewport`, `noindex`, `canonical`, `lang`, `imageCount`, `imagesMissingAlt`, `wordCount`, `structuredData`, `hasOpenGraph`, `internalLinks`, `htmlBytes`, `error`.

**Key-value store** — `report.html` (the branded report: score ring, category bars, findings with fixes, handled-by-platform table, 30-day plan, page-by-page table; printable) and `SUMMARY` (the summary row as JSON).

### Scoring

Five categories start at 100. Each finding deducts from its category by severity: Critical −35, High −20, Medium −10, Low −5. Findings the platform normally handles are capped at Low. Server response over 1.2 s costs Performance 20; over 2.5 s costs 40. Overall = average of the five. It's a consistent yardstick for tracking a site over time and comparing pages — not a prediction of Google rankings.

### Common uses

- Agencies and freelancers: run it on a prospect's site before the first call; send the report as the pitch.
- Store owners: audit before and after a theme change, an app install, or a migration.
- Monitoring: schedule it monthly and diff the summary rows.
- Bulk: feed a list of domains through the API and rank them by score.

### Limits and honesty

It reads the HTML your server sends to crawlers and does not execute JavaScript, so structured data or content injected client-side is not counted — the report says so, and the WordPress/Shopify fix text tells you to confirm with Google's Rich Results Test before acting. It does not measure Core Web Vitals (only server response time). Very large sites are sampled, not exhausted; the coverage line in the report says exactly how many of how many.

### Pricing

Pay per event: a small charge per run plus a charge per page audited. `maxPages` is your cost control, and the actor honours the max-charge limit you set on a run — it will audit fewer pages rather than exceed it.

***

Built and maintained by **Anywhere Web Repair** (anywherewebrepair.com) — the same checks and platform fix guidance behind our human-reviewed audits. If you'd rather have a person go through the findings, write the fix plan and implement it in your admin, that's what we do.

# Actor input Schema

## `startUrl` (type: `string`):

The site's homepage, e.g. https://example.com (https:// is assumed if you leave it off). The audit stays on this domain.

## `maxPages` (type: `integer`):

Pages are sampled across the site's sitemap by section (products, collections, blog, …) so a small number still represents the whole site. Each audited page is a billable event.

## `includePageRows` (type: `boolean`):

On: the dataset holds the audit summary plus one row per page (title, description, H1s, alt text, word count, status…). Off: only the summary row — cheapest way to get a score and findings.

## `extraUrls` (type: `array`):

Optional specific URLs or paths on the same domain to audit no matter what the sampler picks, e.g. /pricing or https://example.com/blog/launch.

## `respectRobots` (type: `boolean`):

Skip paths disallowed for all crawlers in robots.txt. Turn off only for a site you own.

## `concurrency` (type: `integer`):

How many pages to fetch at once. Keep it low for small shared hosts.

## `delayMs` (type: `integer`):

Politeness delay after each batch of requests.

## Actor input object example

```json
{
  "startUrl": "https://anywherewebrepair.com",
  "maxPages": 25,
  "includePageRows": true,
  "respectRobots": true,
  "concurrency": 4,
  "delayMs": 250
}
```

# Actor output Schema

## `audit` (type: `string`):

First row is the audit summary (score, category scores, findings with fixes, handled-by-platform list, 30-day plan); the following rows are one per audited page.

## `report` (type: `string`):

Branded single-file HTML report — score ring, findings, platform-handled checks, 30-day plan, page-by-page table. Printable.

## `summary` (type: `string`):

The summary row as a standalone JSON record.

# API

You can run this Actor programmatically using our API. Below are code examples in JavaScript, Python, and CLI, as well as the OpenAPI specification and MCP server setup.

## JavaScript example

```javascript
import { ApifyClient } from 'apify-client';

// Initialize the ApifyClient with your Apify API token
// Replace the '<YOUR_API_TOKEN>' with your token
const client = new ApifyClient({
    token: '<YOUR_API_TOKEN>',
});

// Prepare Actor input
const input = {
    "startUrl": "https://anywherewebrepair.com"
};

// Run the Actor and wait for it to finish
const run = await client.actor("anywhere-web-repair/website-seo-audit").call(input);

// Fetch and print Actor results from the run's dataset (if any)
console.log('Results from dataset');
console.log(`💾 Check your data here: https://console.apify.com/storage/datasets/${run.defaultDatasetId}`);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((item) => {
    console.dir(item);
});

// 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/js/docs

```

## Python example

```python
from apify_client import ApifyClient

# Initialize the ApifyClient with your Apify API token
# Replace '<YOUR_API_TOKEN>' with your token.
client = ApifyClient("<YOUR_API_TOKEN>")

# Prepare the Actor input
run_input = { "startUrl": "https://anywherewebrepair.com" }

# Run the Actor and wait for it to finish
run = client.actor("anywhere-web-repair/website-seo-audit").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print(f"💾 Check your data here: https://console.apify.com/storage/datasets/{run.default_dataset_id}")
for item in client.dataset(run.default_dataset_id).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{
  "startUrl": "https://anywherewebrepair.com"
}' |
apify call anywhere-web-repair/website-seo-audit --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,anywhere-web-repair/website-seo-audit"
        }
    }
}
```

The hosted server signs you in with OAuth on first connect, so no API token belongs in this config. Clients without OAuth support can send an `Authorization: Bearer <APIFY_API_TOKEN>` header instead, using a token from API & Integrations in Apify Console (https://console.apify.com/settings/integrations).

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/gTlwkNEo7ysM8Cl2z/builds/wcGmdfdABdlC3RtZx/openapi.json
