SEO Release Diff – Staging vs Production
Pricing
from $5.00 / 1,000 page pair compareds
SEO Release Diff – Staging vs Production
Catch SEO changes before a site release: compare titles, canonicals, noindex and H1 with exact before/after evidence. See the real Next.js 14 vs 15 example: 4 changes in 1 page pair ($0.006 event ceiling). Try your production and staging URLs.
Pricing
from $5.00 / 1,000 page pair compareds
Rating
0.0
(0)
Developer
Kais
Maintained by CommunityActor stats
0
Bookmarked
2
Total users
1
Monthly active users
8 days ago
Last modified
Categories
Share
SEO Release Diff — Staging vs Production
Compare old and new public pages before a redesign, theme change or migration. Get field-level before/after evidence and a machine-readable CI flag in one run, without exporting and joining two audits.
Live Output Example — Next.js 14 vs 15
A framework upgrade can change the canonical path, page title and heading before your release team notices. Compare the current and candidate pages in one run to see exactly what needs review.
Real public-page capture, 13 October 2026 (UTC). This example runs the Actor's actual HTTP fetching and comparison code against the official Next.js 14 and 15 upgrade guides, with robots.txt checks enabled. Both pages returned HTTP 200. It is a comparison of two documentation pages, not a claim about a customer migration or every Next.js website.
- Reference: Next.js 14 upgrade guide
- Candidate: Next.js 15 upgrade guide
| Measured field | Next.js 14 reference | Next.js 15 candidate |
|---|---|---|
| title | Upgrading: Version 14 | Next.js | Upgrading: Version 15 | Next.js |
| description | Upgrade your Next.js Application from Version 13 to 14. | Upgrade your Next.js Application from Version 14 to 15. |
| canonical | //{origin}/docs/app/building-your-application/upgrading/version-14 | //{origin}/docs/app/guides/upgrading/version-15 |
| h1 | Version 14 | How to upgrade to version 15 |
Actual result: CHANGED, changeCount: 4, ciPassed: true. The Actor reported CANONICAL_CHANGED as a warning. Neither page added noindex, lost a title/description/H1/canonical, or increased malformed JSON-LD. The canonical values in the table use the Actor's default {origin} normalization; the path change remains visible. With failOnAnyChange:true, these same changes make ciPassed:false.
For a concrete cost example, this is 1 page pair / 2 pages, with a maximum event charge of $0.006 at 256 MB. Ten completed pairs have an event-price ceiling of $0.051. Those figures are the listed run charges, not estimated SEO revenue or guaranteed savings.
Try this comparison in SEO Release Diff: open the Actor input, paste the example below, and click Start. Use your own production/staging URLs for your release check.
{"pairs":[{"label":"Next.js 14 vs 15 upgrade guides","referenceUrl":"https://nextjs.org/docs/14/app/building-your-application/upgrading/version-14","candidateUrl":"https://nextjs.org/docs/15/app/guides/upgrading/version-15"}],"maxPairs":1,"normalizeOrigins":true,"failOnAnyChange":false,"respectRobotsTxt":true}
This checks server-returned HTML metadata. Review whether the reported changes are intentional before releasing your own site.
Quick start
{"pairs":[{"label":"Demo: identical page","referenceUrl":"https://example.com","candidateUrl":"https://example.com"}],"maxPairs":1,"normalizeOrigins":true,"failOnAnyChange":false,"respectRobotsTxt":true}
- Open this Actor on Apify Store or Console and sign in to your Apify account. Paste the JSON above into the input editor.
- Keep the default 256 MB memory. Set the run's maximum charge to $0.01 for this one-pair demo. Its event-price ceiling is $0.006, not $0.01; available Apify credits depend on your account.
- Start the run. Open the run's dataset to see the comparison, and the default key-value store's SUMMARY record to check
allPairsCompletedandciPassed.
The demo compares the same public page with itself. It should return PASS if the page and its robots.txt can be inspected; an access or fetch failure returns ERROR. For a real release check, use your current public page as referenceUrl and the corresponding public staging page as candidateUrl. Repeat that object for each page pair and raise maxPairs to the number you want inspected. No target-site login, target API key, proxy subscription or AI service is required.
What changes are checked?
- Title, meta descriptions and H1 text.
- Canonical URLs, meta robots/googlebot and the X-Robots-Tag header, including newly added noindex/none.
- HTML language and hreflang language/target inventory.
- Detected JSON-LD types and the number of malformed JSON-LD blocks.
Each result contains reference and candidate snapshots, changes with exact before/after values, and findings with reproducible codes. Whitespace in title/H1 text is normalized. Canonical and hreflang origins from the compared pages are treated as equivalent by default; paths and query strings remain significant. Set normalizeOrigins:false for literal origin comparison. Final redirect URLs remain in the snapshots but changing host alone does not fail the comparison.
Example: catching an added noindex
Synthetic example, generated offline from this Actor's current comparison code. These are invented HTML fixtures, not a customer run or a public website result. The reference HTML contains index,follow; the candidate HTML contains noindex,follow. Both pages keep the same title, H1, description and canonical path.
Dataset excerpt (snapshots, URLs and timestamps omitted):
{"status": "REGRESSION","ciPassed": false,"changeCount": 2,"changes": [{"field": "robots","before": ["follow","index"],"after": ["follow","noindex"]},{"field": "hasNoindex","before": false,"after": true}],"findings": [{"code": "NOINDEX_ADDED","severity": "error","field": "robots","message": "Candidate adds noindex/none. This may be intentional on staging; remove before production if indexing is intended."}]}
The corresponding SUMMARY excerpt is:
{"counts": {"PASS": 0,"CHANGED": 0,"REGRESSION": 1,"ERROR": 0},"requestedPairs": 1,"completedThisSession": 1,"previouslyCompleted": 0,"allPairsCompleted": true,"ciPassed": false}
allPairsCompleted:true means the requested comparisons finished; it does not mean they passed. Here, ciPassed:false reports the added noindex. Staging noindex may be intentional: confirm the intended production setting before release. This checks the HTML directives, not Google's actual indexing.
Results and CI
PASS: the measured fields match. CHANGED: at least one field changed, with no detected high-priority regression. REGRESSION: candidate added noindex, removed a reference title/description/H1/canonical, or increased malformed JSON-LD blocks. ERROR: a target could not be inspected. Intentional staging noindex is still reported: decide whether it will be removed before deployment.
ciPassed is false for REGRESSION and ERROR. With failOnAnyChange:true, CHANGED also returns false. Your CI should also require SUMMARY.allPairsCompleted:true. The SUMMARY record is in the default key-value store; results export as JSON, CSV or Excel in Apify Console.
For CI, also confirm the dataset contains a result for each unique page pair you requested, within maxPairs. Block the release check if the run hits its cost limit, is interrupted, or is missing any expected pair; do not rely on the SUMMARY record or on the platform run status alone.
A PASS is limited to these checks. It is not approval to deploy, an SEO score or a ranking prediction. A changed title is not automatically a regression.
Pricing
Price: $5 per 1,000 completed page-pair comparisons ($0.005 per pair), plus $0.001 for the Actor start at the default 256 MB memory. Apify charges one start event up to 1 GB, then scales the number of start events with memory. Platform usage is included in this Actor's event pricing; there is no additional default dataset-item event. A pair means two inspected pages; an identical URL is fetched once. A completed comparison is charged even if it detects a regression. ERROR rows have no custom comparison fee. Duplicate URL pairs within one run are processed once; a later run is new work.
At the default 256 MB memory, one completed pair costs at most $0.006, and ten completed pairs cost at most $0.051 in event charges. The current default run cap of $0.05 is below the ten-pair ceiling. For ten pairs, set a maximum charge of at least $0.051 (for example, $0.06); this cap limits spending and is not a flat fee. A lower cap may stop the run before all requested pairs finish. Always require SUMMARY.allPairsCompleted:true together with SUMMARY.ciPassed:true before treating the measured checks as passed. Platform-displayed pricing is authoritative. No external paid API or proxy is used. Developer margins depend on actual platform resource costs; they are not guaranteed by this price.
Bounds and limitations
Up to 50 unique pairs; default maxPairs is 10. Each response is limited to 2 MiB, each request has a 12-second timeout, redirect depth is capped and processing stops near nine minutes. Incomplete runs must not pass your release check; verify completion in SUMMARY and the dataset. Requests are sequential with a short delay. There is no automatic proxy escalation.
Reads server-returned HTML only. JavaScript-injected tags may be absent. Private networks, localhost, login pages and credential-bearing URLs are excluded; every network connection uses a validated public IP, including redirects. Robots.txt is checked by default; an unavailable robots file (other than 404) or a disallowed path produces ERROR. Use only pages you are authorized to inspect. Turning robots checks off is for sites you control.
JSON-LD inspection checks parsing and type inventory, not full schema vocabulary, required rich-result fields or Google's rich-result eligibility. Hreflang targets and reciprocal links are not fetched. This version does not measure browser appearance, Core Web Vitals, full content parity, broken links or actual search indexing.
Practical uses
- Compare a Shopify theme preview that is publicly accessible with production.
- Check a headless website rebuild for lost canonical, H1 or JSON-LD types.
- Add a small URL-pair release check to GitHub Actions, n8n or Make using the Apify API.
- Compare a previous static deployment with a candidate deployment.
For support, include the run ID and public reproduction URLs; never include credentials or customer personal data.