Website Migration QA — Redirects, Canonicals & Content avatar

Website Migration QA — Redirects, Canonicals & Content

Pricing

from $15.00 / migration qa report

Go to Apify Store
Website Migration QA — Redirects, Canonicals & Content

Website Migration QA — Redirects, Canonicals & Content

Audit up to 100 old/new URL pairs: redirect targets and traces, missing destinations, HTML canonicals, indexing directives and content differences. Prioritized checklist, printable HTML and JSON. Free fictional demo. No AI key.

Pricing

from $15.00 / migration qa report

Rating

0.0

(0)

Developer

El Fajad

El Fajad

Maintained by Community

Actor stats

0

Bookmarked

2

Total users

1

Monthly active users

2 days ago

Last modified

Categories

Share

Website Migration QA

Turn an old → new URL map into a prioritized repair and review checklist. Check up to 100 URL pairs for wrong redirect targets, missing destinations, redirect chains and loops, title/heading differences, HTML canonical conflicts and indexing directives. Get printable HTML, JSON, redirect traces and reusable page snapshots.

Built for agencies and site teams checking a launch. This Actor checks the URLs you supply; it does not discover or certify an entire website. No AI API key, external paid scraper, browser automation or VPS is required.

Try the fictional demo

{"mode":"demo"}

Demo uses fixed synthetic responses for four example mappings: a correct redirect, a wrong destination, missing pages and changed static text. It does not fetch real websites or trigger the migration-report event. The startup event in Pricing still applies. Custom URLs are ignored in demo mode.

Open Migration brief → Open printable report. Evidence sections open by default. Print the page to save a PDF, or use the JSON for a team checklist.

Audit your URL map

{
"mode": "audit",
"phase": "postlaunch",
"reportLabel": "Client website launch QA",
"urlPairs": [
{
"oldUrl": "https://old.example.com/about",
"newUrl": "https://new.example.com/about",
"label": "About page"
},
{
"oldUrl": "https://old.example.com/services",
"newUrl": "https://new.example.com/services",
"label": "Services page",
"baseline": {
"title": "Earlier services title",
"h1": "Earlier services heading",
"noindex": false,
"observedAt": "2026-09-28T12:00:00Z"
}
}
]
}

The domains above are placeholders. Replace them with the public pages you intend to check.

  1. Export your old/new page mapping from the migration plan. Paste 1–100 pairs into Old → new URL mapping.
  2. Choose Audit my URL map. Choose After launch when old URLs should redirect, or Before launch to compare pages without a missing-redirect finding.
  3. Add pre-migration baseline fields where available. If omitted, the Actor may compare two distinct live pages, explicitly labeled as a current comparison.
  4. Set maximum charge to at least $15.01, then run. Account spending limits must allow that budget. The saved small default is intended for the demo.
  5. Review the checklist, pair traces and unknowns. Download output before your account's retention period expires.

In postlaunch mode, an old URL identical to its new URL does not require a redirect. Each old URL may have only one destination. Exact duplicate pairs are merged; conflicting destinations or baselines are rejected.

What is checked

CheckEvidence and interpretation
Old URL mappingIts terminal redirect URL compared with the mapped new URL's terminal URL
Redirect behaviorServer response codes, Location targets, multiple hops, loops and missing Location
Missing destinationsTerminal HTTP 404/410; intentionally retired pages still need owner review
Server/access failuresServer errors are review items; 403/429 and network failures remain unknown
Destination HTMLTitle, description, H1, HTML canonical targets, robots/googlebot metadata and X-Robots-Tag
Canonical differencesConflicting targets or targets different from the fetched final page; intentional canonicalization may be valid
Baseline fieldsOnly supplied fields are compared; absent baseline fields remain unknown
Static text changesBounded word-retention and text-length heuristic, for sufficiently large usable text

Canonical checks cover HTML link declarations, not HTTP Link headers or a search engine's selected canonical. A noindex directive may be intentional. Changed titles/headings are review items, not automatic regressions.

An HTTP 200 alone does not prove the mapping is correct. The old URL must reach the intended destination. Conversely, robots restrictions, TLS/DNS errors, bot challenges, unsupported formats and thin JavaScript shells are not called missing pages.

Before/after content needs a baseline

After launch, the old URL often redirects to the same page as the new URL. The Actor does not infer removed content by comparing that page with itself. Supply an earlier snapshot when you need historical field comparisons.

Optional baseline fields for each pair:

FieldLimit
title, description, h1Strings, up to 1,000 characters each; an explicitly empty string is a known empty value
textPlain page text, up to 30,000 characters
noindexExplicit boolean
canonicalUrlPublic HTTP(S) URL or null
observedAtNon-future ISO timestamp with timezone, e.g. 2026-09-28T12:00:00Z

Baseline contents, provenance and dates are supplied by you and are not independently verified. Ordinary live old/new comparisons are labeled live-old-page, not historical evidence.

Text comparison uses distinct Unicode words of at least two characters. A reduction review appears only when fewer than 50% of comparison words remain and destination text length is under 60% of comparison text length. This is not semantic analysis or proof of accidental deletion. Navigation, headers, footers and scripts are removed; main/article text is preferred. JavaScript content is not rendered.

Reusable snapshots: download NEW-SNAPSHOTS. Each usable destination includes a baseline object you can place directly into a later pair. Match the correct page yourself. If extracted text exceeds 30,000 characters, the snapshot labels textOmitted: true and omits text rather than presenting a truncated full-content baseline.

For a pre-migration snapshot, use prelaunch mode with each current URL supplied as both oldUrl and newUrl. This is a normal billable audit, including when no findings are observed.

Scope and resource limits

  • 1–100 URL pairs, maximum 8 MiB input.
  • Only public HTTP(S) pages on standard ports. Credential/signed links, private/reserved DNS/IP targets and account/action URLs are rejected.
  • HTTP GET only; no forms, purchases, login, JavaScript, discovered-link crawl or browser sessions.
  • Each connection pins the validated DNS answer; redirects are validated again.
  • robots.txt is respected for the Actor's named user agent. An unavailable/ambiguous robots policy stops that origin's checks.
  • Up to five followed redirects per URL, 600 total HTTP requests, approximately ten minutes of collection. Unchecked pairs remain explicit.
  • Sequential requests, at least 400 ms between requests to the same origin; robots crawl delays are respected within the bounded budget.
  • Requests have an 8-second DNS/response time budget; responses are limited to 2 MiB and UTF-8/ASCII static HTML. Unsupported encodings/compressed responses remain unknown.
  • No ranking, traffic, backlinks, sitemap, Search Console, actual search-indexing or complete-migration certification.

Reports may be partial when one side is available but another is blocked, or the collection limit is reached. The report lists attempted and unknown pairs. This does not imply every supplied URL was successfully checked.

Pricing

Launch price: $15 per delivered migration report, covering up to 100 supplied URL pairs. The Pricing tab is authoritative.

  • migration-report: once per usable non-demo report, including partial reports and reports with no findings.
  • Fixed fictional demo: no report event.
  • Wholly unknown/unusable collection: no report event; failure details are saved, and the run fails clearly.
  • Invalid input or insufficient report budget: no report event.
  • Startup event: $0.00005 at supported memory sizes, including demos and failures.
  • No separate dataset-row charge or customer platform-usage pass-through.

At least one pair with usable static HTML, an observed missing terminal, a confirmed redirect loop or a missing redirect Location is needed for a paid report. A successful fetch of the old page alone can support a partial billable report even if the new page is unavailable; review the coverage before using it.

The Actor checks the report-event budget before live requests, saves HTML before billing its report row, and skips already-delivered results if the same run is resurrected. A cap is not a minimum charge. Free-plan or remaining-credit restrictions may prevent a $15 real report; the fictional demo remains available with a small budget.

Outputs

The default dataset contains one report: label, phase, isDemo, timestamps, observation status, counts, grouped findings, detailed pairs, coverage, and reportUrl.

Default key-value-store records:

  • migration-<analysisId>.html: printable report.
  • PAIR-RESULTS: full pair observations and unknowns, also saved when all pairs are unusable.
  • NEW-SNAPSHOTS: reusable destination baseline objects.
  • RUN-SUMMARY: delivery, usable/unknown counts and demo/budget state.

API and MCP

import { ApifyClient } from 'apify-client';
const client = new ApifyClient({token: process.env.APIFY_TOKEN});
const run = await client.actor('elfajad/website-migration-qa').call({
mode: 'audit',
phase: 'postlaunch',
urlPairs: [{oldUrl: 'https://old.example.com/about', newUrl: 'https://new.example.com/about'}]
}, {memory: 256, timeout: 900, maxTotalChargeUsd: 15.01});
const {items} = await client.dataset(run.defaultDatasetId).listItems();

Replace placeholder URLs with your actual mapping. The published Actor is also accessible through Apify MCP. No third-party API key is required.

Development and support

Node.js 22+, Apify SDK (Apache-2.0), Cheerio (MIT), ipaddr.js (MIT) and robots-parser (MIT). Deterministic checks, no proprietary model.

npm ci
npm test
npm run sample

Use the Issues tab for problems, with the run ID and non-sensitive URLs/field names. Do not publish credentials, private baseline text or payout information. For migration planning context, see Google's site-move guidance and Screaming Frog's redirect-audit workflow.