Every Monday, checks the on-page SEO of a page you name and emails its score and what to fix, most important first.
Uses
Gmail
Google PageSpeed Insights
OpenAI
Get a weekly SEO checkup of your key page by email
pageUrl to blank.Set pageUrl to blank.reportRecipient to blank.Set reportRecipient to blank.deviceStrategy to mobile.Set deviceStrategy to mobile.maxFindings to 20.Set maxFindings to 20.pageUrl and save it as auditUrl.Trim pageUrl and save it as auditUrl.reportRecipient and save it as sendTo.Trim reportRecipient and save it as sendTo.deviceStrategy lowercase and save it as device.Make deviceStrategy lowercase and save it as device.auditUrl is a valid web addressIf not auditUrl is a valid web addressYes
No
No steps
sendTo is a valid email addressIf not sendTo is a valid email addressYes
No
No steps
mobile desktop doesn't contain deviceIf mobile desktop doesn't contain deviceYes
No
No steps
auditUrl with PageSpeed Insights. Save it as report.Analyze auditUrl with PageSpeed Insights. Save it as report.report.scores.seo and save it as seoScore.Trim report.scores.seo and save it as seoScore.seoScore is null or seoScore is emptyIf seoScore is null or seoScore is emptyYes
No
No steps
auditedAddress to auditUrl.Set auditedAddress to auditUrl.report.url and save it as finalUrl.Trim report.url and save it as finalUrl.finalUrl isn't empty and finalUrl is not nullIf finalUrl isn't empty and finalUrl is not nullYes
auditedAddress to finalUrl.Change auditedAddress to finalUrl.No
No steps
report.report_url and save it as reportLink.Trim report.report_url and save it as reportLink.reportLink is null or reportLink is emptyIf reportLink is null or reportLink is emptyYes
reportLink to not available for this run.Change reportLink to not available for this run.No
No steps
report.analyzed_at and save it as checkedOn.Trim report.analyzed_at and save it as checkedOn.checkedOn is null or checkedOn is emptyIf checkedOn is null or checkedOn is emptyYes
checkedOn to not reported.Change checkedOn to not reported.No
checkedOn readable as “Monday, November 2, 2026” and save it as checkedOn.Make checkedOn readable as “Monday, November 2, 2026” and save it as checkedOn.findings to an empty list.Set findings to an empty list.findingCount to 0.Set findingCount to 0.audit in report.failed_audits:For each audit in report.failed_audits:audit.category and save it as auditCategory.Trim audit.category and save it as auditCategory.auditCategory is not seoIf auditCategory is not seoYes
No
No steps
findingCount is greater than or equal to maxFindings multiplied by 1If findingCount is greater than or equal to maxFindings multiplied by 1Yes
No
No steps
` with in audit.title and save it as auditTitle.Replace ` with in audit.title and save it as auditTitle.auditTitle is empty or auditTitle is nullIf auditTitle is empty or auditTitle is nullYes
No
No steps
findingLine to - auditTitle.Set findingLine to - auditTitle.audit.display_value and save it as auditDetail.Trim audit.display_value and save it as auditDetail.auditDetail isn't empty and auditDetail is not nullIf auditDetail isn't empty and auditDetail is not nullYes
findingLine to findingLine (auditDetail).Change findingLine to findingLine (auditDetail).No
No steps
\[([^\]]+)\]\(([^)\s]+)\) with $1 ($2) in audit.description and save it as auditWhy.Replace the pattern \[([^\]]+)\]\(([^)\s]+)\) with $1 ($2) in audit.description and save it as auditWhy.` with in auditWhy and save it as auditWhy.Replace ` with in auditWhy and save it as auditWhy.auditWhy isn't empty and auditWhy is not nullIf auditWhy isn't empty and auditWhy is not nullYes
findingLine to findingLineChange findingLine to findingLine
Why it matters: auditWhy.No
No steps
findingLine to the end of findings and save it as findings.Add findingLine to the end of findings and save it as findings.findingCount.Add 1 to findingCount.failedText to None - every on-page check in this audit passed..Set failedText to None - every on-page check in this audit passed..findingCount is greater than 0If findingCount is greater than 0Yes
findings with a new line and save it as failedText.Join findings with a new line and save it as failedText.No
No steps
pageHtml to blank.Set pageHtml to blank.structureText to The page source could not be read from this workflow, so its heading structure was not checked..Set structureText to The page source could not be read from this workflow, so its heading structure was not checked..headingFixes to 0.Set headingFixes to 0.fetchErrorIf a step below fails, save the error as fetchErrorTry
auditUrl and save it as pageFetch.Fetch auditUrl and save it as pageFetch.pageFetch.ok is yesIf pageFetch.ok is yesYes
pageHtml to pageFetch.body.Change pageHtml to pageFetch.body.No
The site answered this workflow with status @pageFetch.status instead of the page (some sites turn away automated visitors), so its heading structure was not c... and save it as structureText.Build the text The site answered this workflow with status @pageFetch.status instead of the page (some sites turn away automated visitors), so its heading structure was not c... and save it as structureText.On error
The page could not be downloaded by this workflow (@fetchError.message), so its heading structure was not checked. and save it as structureText.Build the text The page could not be downloaded by this workflow (@fetchError.message), so its heading structure was not checked. and save it as structureText.pageHtml is greater than or equal to 400If the length of pageHtml is greater than or equal to 400Yes
pageHtml lowercase and save it as htmlLower.Make pageHtml lowercase and save it as htmlLower.h1Count to the length of htmlLower split by <h1 minus 1.Set h1Count to the length of htmlLower split by <h1 minus 1.h2Count to the length of htmlLower split by <h2 minus 1.Set h2Count to the length of htmlLower split by <h2 minus 1.h3Count to the length of htmlLower split by <h3 minus 1.Set h3Count to the length of htmlLower split by <h3 minus 1.h1Count plus h2Count plus h3Count is 0If h1Count plus h2Count plus h3Count is 0Yes
structureText to No H1, H2 or H3 headings were found in the page source. They may be added by JavaScript after the page loads, or the site may have shown this check a different page, so the heading structure could not be judged. Open the page and check its headings yourself..Change structureText to No H1, H2 or H3 headings were found in the page source. They may be added by JavaScript after the page loads, or the site may have shown this check a different page, so the heading structure could not be judged. Open the page and check its headings yourself..No
structureLines to an empty list.Set structureLines to an empty list.h1Count as text, H2 h2Count as text, H3 h3Count as text to the end of structureLines and save it as structureLines.Add - Headings found: H1 h1Count as text, H2 h2Count as text, H3 h3Count as text to the end of structureLines and save it as structureLines.h1Count is 0If h1Count is 0Yes
- There is no H1 on the page. Give it one heading that states what the page is about. to the end of structureLines and save it as structureLines.Add - There is no H1 on the page. Give it one heading that states what the page is about. to the end of structureLines and save it as structureLines.headingFixes.Add 1 to headingFixes.No
No steps
h1Count is greater than 1If h1Count is greater than 1Yes
- The page has more than one H1. Keep one, and demote the rest to H2. to the end of structureLines and save it as structureLines.Add - The page has more than one H1. Keep one, and demote the rest to H2. to the end of structureLines and save it as structureLines.headingFixes.Add 1 to headingFixes.No
No steps
h2Count is 0If h2Count is 0Yes
- There are no H2 subheadings, so the page has no visible structure under its title. Break the content into sections. to the end of structureLines and save it as structureLines.Add - There are no H2 subheadings, so the page has no visible structure under its title. Break the content into sections. to the end of structureLines and save it as structureLines.headingFixes.Add 1 to headingFixes.No
No steps
structureLines with a new line and save it as structureText.Join structureLines with a new line and save it as structureText.No
No steps
auditPrompt to:Set auditPrompt to:You are an SEO specialist writing to the owner of one web page.
Below is everything an automated on-page audit of that page found. Write a short, prioritised list of what to fix, most important first, in plain sentences a non-specialist can act on. Say what to change and where.
Rules you must follow:
- Use ONLY the findings below. Do not add checks that are not listed.
- Do not mention search rankings, traffic, competitors or keywords - none of that was measured here.
- Do not invent any number, page title or wording that does not appear below.
- If the heading structure says it was not che...auditPrompt to auditPromptChange auditPrompt to auditPrompt
Page audited: auditedAddress
On-page SEO score out of 100: seoScore.auditPrompt to auditPromptChange auditPrompt to auditPrompt
Failed on-page checks:
failedText.auditPrompt to auditPromptChange auditPrompt to auditPrompt
Heading structure:
structureText.advice to blank.Set advice to blank.adviceErrorIf a step below fails, save the error as adviceErrorTry
auditPrompt. Save it as answer.Ask OpenAI: auditPrompt. Save it as answer.answer.response_text and save it as answerText.Trim answer.response_text and save it as answerText.answerText isn't empty and answerText is not nullIf answerText isn't empty and answerText is not nullYes
advice to answerText.Change advice to answerText.No
No steps
On error
adviceError as text.Show in the output: Could not write the recommendations for this audit: adviceError as text.advice is emptyIf advice is emptyYes
advice to No written recommendations were produced this run - the checks listed above are the audit..Change advice to No written recommendations were produced this run - the checks listed above are the audit..No
No steps
bodyLines to an empty list.Set bodyLines to an empty list.auditedAddress to the end of bodyLines and save it as bodyLines.Add On-page SEO audit for auditedAddress to the end of bodyLines and save it as bodyLines.checkedOn as a device visitor. to the end of bodyLines and save it as bodyLines.Add Checked on checkedOn as a device visitor. to the end of bodyLines and save it as bodyLines.seoScore out of 100 to the end of bodyLines and save it as bodyLines.failedText to the end of bodyLines and save it as bodyLines.structureText to the end of bodyLines and save it as bodyLines.advice to the end of bodyLines and save it as bodyLines.reportLink to the end of bodyLines and save it as bodyLines.bodyLines with a new line and save it as emailBody.Join bodyLines with a new line and save it as emailBody.fixCount to findingCount plus headingFixes.Set fixCount to findingCount plus headingFixes.fixSummary to fixCount fixes.Set fixSummary to fixCount fixes.fixCount is 0If fixCount is 0Yes
fixSummary to nothing to fix.Change fixSummary to nothing to fix.Else if @fixCount is 1
fixSummary to 1 fix.Change fixSummary to 1 fix.Otherwise
No steps
^https?://(www\.)?|/$ with in auditedAddress and save it as pageLabel.Replace the pattern ^https?://(www\.)?|/$ with in auditedAddress and save it as pageLabel.sendTo.Send an email to sendTo.
Subject: SEO seoScore/100 · fixSummary for pageLabelemailBody