SheetMagicSheetMagic

On-Page SEO Audit in Google Sheets for 100 URLs

Run an on-page SEO audit in Google Sheets. Paste 120 URLs, add five formulas, and flag every bad title, description, and H1 in about 10 minutes.

Phil Nguyen · 15 min read

A new client hands you a 120-page site and asks what is wrong with it. You need every page title, every meta description, and every H1, with the character counts, before you can say anything useful. Exporting a crawl and pivoting it into something a client can read costs you most of an afternoon.

There is a shorter path. Paste the URL list into column A of a Google Sheet, add five formulas, and let the sheet fill itself while you write the summary.

Here is the formula the whole audit is built on.

Formula

=GETMETATITLE(A2)

Fetches the page at the URL in A2 and returns its title tag. One call, one integration credit, one cell.

What comes back

A (URL)B (=GETMETATITLE result)
https://fennwoodflooring.com/Fennwood Flooring - Hardwood, Vinyl and Tile in Columbus OH
https://fennwoodflooring.com/services/hardwood-refinishingHardwood Floor Refinishing Services
https://fennwoodflooring.com/services/vinyl-plankVinyl Plank
https://fennwoodflooring.com/aboutFennwood Flooring | Family Owned Since 1994 | Serving Central Ohio and the Surrounding Counties

You can already see two problems in four rows. Row 3 is a bare service name with no location. Row 4 runs far past what Google will show. Now do that for all 120 pages.

Do it for the whole column

Paste your URL list into A2 and down. Put three formulas across row 2, then select them and drag to the last row.

Formula

=GETMETADESCRIPTION(A2)

Returns the meta description. Put this in E2.

Formula

=GETH1(A2)

Returns the H1 heading. Put this in H2. If the page has more than one H1, they come back joined by line breaks in the same cell.

Three formulas, 120 rows, 360 cells that fill themselves. Each cell is one page fetch and one integration credit, so a 120-page audit of all three fields costs about 360 credits. Solo's 10,000 credits a month covers about 27 audits that size.

Two things to know before you drag.

First, these formulas run right in the cell and give you the answer straight away. They are not background jobs, so there is no placeholder to wait on and nothing lands in a separate tab.

Second, they are not frozen. The Keep Formula setting does not apply to the page-scraping formulas, so a recalculation can fetch the pages again. Results are cached for 30 minutes per formula and URL, so a quick re-run costs nothing. Once the columns look right, select B through I, copy, then Edit, Paste special, Values only. Now the audit is data and it will never re-bill.

Tip

Sort column A before you drag. Grouping by section (blog, services, locations) makes the flags far easier to read later, and the formulas do not care about order.

Flag what is broken

Raw titles are not an audit. What the client wants is a column that says what to fix. That part is free, because it is plain Google Sheets.

Formula

=LEN(B2)

Character count of the title in B2. Put it in C2. Costs nothing, no credits, no tokens.

Formula

=IF(C2=0,"Missing",IF(C2>60,"Too long",IF(C2<30,"Too short","OK")))

Turns the count into a verdict. Put it in D2 and drag it down with the rest.

What comes back

B (Title)C (=LEN)D (Flag)
Fennwood Flooring - Hardwood, Vinyl and Tile in Columbus OH58OK
Hardwood Floor Refinishing Services35OK
Vinyl Plank11Too short
Fennwood Flooring | Family Owned Since 1994 | Serving Central Ohio and the Surrounding Counties94Too long

The same two formulas work on the description in F and G, with 155 and 70 as the cut-offs instead of 60 and 30. Pick your own numbers. The point is that the sheet applies them the same way to every row, which is the part a human audit gets wrong around page 40.

The H1 needs a different test. Google is fine with a page having no H1, but your client's template probably should not skip one, and two H1s on a page usually means a stray heading in a banner.

Formula

=IF(H2="No elements found.","Missing",IF(ISNUMBER(SEARCH(CHAR(10),H2)),"More than one","OK"))

GETH1 returns the exact text 'No elements found.' when a page has no H1, and joins multiple H1s with line breaks. This reads both cases. Put it in I2.

What comes back

A (URL)H (=GETH1 result)I (Flag)
/services/hardwood-refinishingHardwood Floor RefinishingOK
/services/vinyl-plankVinyl Plank FlooringOK
/aboutNo elements found.Missing
/locations/dublin-ohDublin OH Flooring
Get a Free Estimate
More than one

Filter column D or I to "Too long" and you have the fix list. That is the deliverable the client actually reads.

Four fields in one call

When you only need a quick look at a handful of pages, there is a cheaper way to get all of it at once.

Formula

=PAGEDATA(A2, A3, A4, A5)

Fetches each page once and returns the title, meta description, H1, and status for all of them as one table. One credit per URL, not one per field.

What comes back

URLTitleMeta DescriptionH1Status
https://fennwoodflooring.com/Fennwood Flooring - Hardwood, Vinyl and Tile in Columbus OHHardwood, vinyl and tile installation across Central Ohio since 1994.Flooring That LastsSuccess
https://fennwoodflooring.com/services/vinyl-plankVinyl PlankVinyl Plank FlooringSuccess
https://fennwoodflooring.com/aboutFennwood Flooring | Family Owned Since 1994 | Serving Central Ohio and the Surrounding CountiesMeet the Fennwood family and our install crews.No H1Success
https://fennwoodflooring.com/blog/vinyl-vs-laminateVinyl vs Laminate: Which Holds Up Better?A side by side comparison for busy households.Vinyl vs LaminateSuccess

That is one page fetch per URL instead of three, so it is a third of the credits for the same four fields. It comes with a catch: PAGEDATA takes each URL as its own argument and does not accept a range. =PAGEDATA(A2:A121) will not audit 120 pages, so use it for a batch you can list by hand and use the drag-down columns for the full site.

The result spills across five columns and down one row per URL, plus a header row. Leave that space empty or Sheets shows a #REF! error.

Rewrite the flagged titles

Now the part that used to be the actual afternoon. Every flagged row needs new copy, and there are usually 30 of them.

Formula

=IF(D2="OK","",AITEXT("Rewrite this page title for SEO in under 60 characters. Keep the brand name Fennwood Flooring. Reply with the title only: " & B2))

Only fires on rows you flagged, so you never pay to rewrite a title that was already fine. Put it in J2.

What comes back

B (Title)D (Flag)J (=AITEXT result)
Fennwood Flooring - Hardwood, Vinyl and Tile in Columbus OHOK
Vinyl PlankToo shortVinyl Plank Flooring Installation | Fennwood Flooring
Fennwood Flooring | Family Owned Since 1994 | Serving Central Ohio and the Surrounding CountiesToo longFamily Owned Flooring in Central Ohio | Fennwood
Flooring BlogToo shortFlooring Care and Buying Guides | Fennwood Flooring

The IF wrapper matters more than it looks. Without it you run 120 AI calls to rewrite 30 titles. With it you run 30.

More prompts for this kind of work are in the AI for SEO guide. The same pattern writes the missing descriptions into column K. Feed it the title rather than the old description, because the pages that need a description usually do not have one to improve.

Formula

=IF(G2="OK","",AITEXT("Write a meta description under 155 characters for a page titled: " & B2 & ". Plain language, one clear reason to click. Reply with the description only."))

Put it in K2. Spends AI tokens, not integration credits.

Note

Every AI formula runs on every plan, including Free, which comes with 20,000 one-time tokens to try it. Solo's 3.25M tokens a month is roughly 7,500 to 15,000 short pieces of copy like these titles and descriptions.

See what you are up against

A title can pass every character check and still lose. Before you hand the rewrites over, look at what currently ranks for the page's main keyword.

Formula

=GSEARCH("hardwood floor refinishing columbus oh", "us")

Pulls the live Google organic results for one query. 10 results per call, 3 integration credits.

This one behaves differently from everything above. The cell shows ⏳ Scraping... while the job runs, then the results land in a new tab called Google Search Results, and the cell you typed in ends up reading ✅ 10 results → Google Search Results.

What comes back (first columns of the results tab)

SourcePositionTitleURLSnippet
Sheet1!M21Hardwood Floor Refinishing in Columbus, OH | Buckeye Floorshttps://buckeyefloors.com/refinishingDustless refinishing for Columbus homes, finished in 3 days.
Sheet1!M22Columbus Hardwood Refinishing Costs 2026https://ohiofloorguide.com/costsWhat homeowners paid last year, by square foot.
Sheet1!M23Refinish or Replace? A Columbus Guidehttps://fennwoodflooring.com/blog/refinish-or-replaceWhen refinishing is worth it and when it is not.

More columns follow, including the displayed URL, highlighted snippet words, and sitelinks. The Source column names the cell that asked for each row, so a whole column of GSEARCH formulas collects into one tab and you can still tell the queries apart. Rows arrive in the order the jobs finish, not the order you typed them, so sort by Source before you read it.

Three lookups at 3 credits each is 9 credits. Run it for your 10 priority pages, not all 120.

Turn it into a client summary

The fix list is for you. The client wants one number per problem. Build that on a second tab with native Sheets formulas, which cost nothing to run.

Formula

=COUNTIF(Audit!D:D, "Too long")

Counts one flag across the whole audit. Repeat it for each flag value and each flag column to build the scoreboard.

What comes back

CheckToo longToo shortMissingOK
Title1124085
Meta description693174
H14112

That table is the first slide of the onboarding deck, and it took one formula copied across a grid. It is the same reporting loop the rest of the agency workflows are built on. Next month you paste a fresh URL list into the audit tab and the same counts update.

For the handful of pages that look thin, one more formula tells you whether the page has any structure at all.

Formula

=GETHEADINGS(A2)

Returns every heading on the page as a table of level and text. Run it on a single URL in an empty area, not down a column, because it spills.

A service page with an H1 and nothing else is the one your client will ask about first. Now you can point at it. For anything the named formulas do not cover, such as a canonical tag or a schema block, pull it with a CSS selector.

Compared to Screaming Frog

Screaming Frog is the tool most SEO teams reach for here, and it is very good at this. Being fair about it is more useful than pretending otherwise.

SheetMagic in SheetsScreaming Frog SEO Spider
What it isFormulas inside a Google SheetA desktop app for Windows, macOS and Linux
Best forA known URL list, client-facing output, rewriting as you flagCrawling a whole site and finding what you did not know to look for
CoverageThe fields you write a formula forOver 300 SEO issues, per its site
Price shapeMonthly plan with a usage allowanceFree up to a 500 URL crawl, then a licence at £199 or $279 per year
OutputAlready a shareable sheetA crawl you export
Fixes the copyYes, AITEXT column next to the flagNo, it reports

Screaming Frog's own pages describe it as "the industry leading website crawler" and say it finds broken links, redirects, duplicate content, and structural problems, with JavaScript rendering and Search Console integrations on the paid licence. Nothing in this post replaces that. If you need to know every 404 and every redirect chain on a site you have never seen, crawl it.

What the sheet gives you is the other half of the job. The crawler tells you the title is 94 characters. It does not write you a better one. Here the flag and the rewrite sit in adjacent columns, the client can open the link without installing anything, and next month you paste a fresh URL list into the same file.

Use both. Crawl with the Frog, audit and fix in the sheet.

Copy this template

Eleven columns. Column A is your URL list. Row 2 holds the formulas, and you drag row 2 down to your last URL.

ColumnHeaderFormula in row 2
AURLyour list, pasted
BTitle=GETMETATITLE(A2)
CTitle length=LEN(B2)
DTitle flag=IF(C2=0,"Missing",IF(C2>60,"Too long",IF(C2<30,"Too short","OK")))
EDescription=GETMETADESCRIPTION(A2)
FDescription length=LEN(E2)
GDescription flag=IF(F2=0,"Missing",IF(F2>155,"Too long",IF(F2<70,"Too short","OK")))
HH1=GETH1(A2)
IH1 flag=IF(H2="No elements found.","Missing",IF(ISNUMBER(SEARCH(CHAR(10),H2)),"More than one","OK"))
JSuggested title=IF(D2="OK","",AITEXT(...))
KSuggested description=IF(G2="OK","",AITEXT(...))

Download the template CSV. Import it into a blank sheet (File, Import, Upload) and the formulas are ready to drag down.

What to watch for

  • PAGEDATA needs separate arguments. =PAGEDATA(A2, A3, A4) works. A range like =PAGEDATA(A2:A121) does not, because the whole range arrives as one value. For a long list, use the drag-down columns instead.
  • Nothing here is frozen automatically. Keep Formula does not apply to the page-scraping formulas, so paste your results as values once the audit looks right. Otherwise a recalculation can fetch every page again.
  • Some pages cost more than one credit. A page that needs JavaScript rendering costs 2, and a heavily bot-protected page can settle as high as 9. You are charged what the fetch actually cost, not a flat rate.
  • Spilling results need room. PAGEDATA and GETHEADINGS spread across columns and down rows. If anything is in the way, Sheets shows #REF! instead of the table.

Note

A 120-page audit across title, description and H1 is about 360 integration credits. The free allowance is 100 one-time credits, enough to run one column over roughly 33 pages and see the whole thing work. Solo's 10,000 credits a month covers about 27 audits that size.

Run this on your own site first, before a client's. You will find a "Too long" row you have been looking at for two years. When you want the rest of the page, not just its metadata, extract the full content into a cell and ask AITEXT about it, or read the deeper guide to bulk meta extraction.

Every formula in this article runs on the free allowance. Install from the Google Workspace Marketplace, no card, no expiry.

Install free for Google Sheets

About the author

Phil NguyenPhil builds SheetMagic, the Google Sheets add-on that brings AI and web scraping into the spreadsheet, used by 6,300+ people. He writes these guides from the formulas he runs on his own sheets.