A site content audit: the inventory, the decisions, and what to do with each page
How to build the URL inventory, the eight columns that turn it into decisions, the keep, improve, merge, redirect or remove rule for every page, and the order to work in.
Published by AI Knows Us · Updated 13 October 2026
A site content audit is an inventory of every URL you publish, with enough data beside each one to decide its fate: keep it, improve it, merge it into a stronger page, redirect it, or remove it. That is the whole exercise. It needs four inputs, a crawl of the site, your Search Console performance and indexing data, your analytics, and your own view of which pages make money, joined into one sheet where every row ends in a decision. An audit that produces a report instead of a decision column has not finished.
This page covers the content audit: the inventory, the decisions and the execution. For status codes, render blocking and markup checks, see the technical SEO checklist, and SEO audit tools explains what each kind of tool checks.
Step one: build the inventory
Start from the sitemap, because that is the list you are asserting is canonical, then add everything a crawler finds that the sitemap missed.
curl -s https://example.com/sitemap.xml \
| grep -o '<loc>[^<]*</loc>' \
| sed 's#</*loc>##g' \
| sort -u > sitemap-urls.txt
wc -l sitemap-urls.txt
For a nested index, fetch each child sitemap the same way. Then export Search Console's Pages report for the last sixteen months and join the two lists. A short script beats a spreadsheet once you are past a few hundred URLs:
// join.js, run: node join.js sitemap-urls.txt gsc-pages.csv > inventory.csv
const fs = require('fs');
const [urlFile, gscFile] = process.argv.slice(2);
const urls = fs.readFileSync(urlFile, 'utf8').split(/\r?\n/).filter(Boolean);
const gsc = new Map();
for (const line of fs.readFileSync(gscFile, 'utf8').split(/\r?\n/).slice(1)) {
if (!line) continue;
const [url, clicks, impressions] = line.split(',');
gsc.set(url.replace(/^"|"$/g, ''), {
clicks: Number(clicks) || 0,
impressions: Number(impressions) || 0
});
}
console.log('url,clicks,impressions,ctr');
for (const url of urls) {
const row = gsc.get(url) || { clicks: 0, impressions: 0 };
const ctr = row.impressions ? (row.clicks / row.impressions) : 0;
console.log([url, row.clicks, row.impressions, ctr.toFixed(4)].join(','));
}
Any URL in the sitemap with zero impressions over sixteen months is either new, not indexed, or serving no demand. All three are findings.
Step two: the eight columns
| Column | Source | What it decides |
|---|---|---|
| URL | Sitemap and crawl | The row itself |
| Page type | Your own labelling | Which standard the page is held to |
| Clicks, 16 months | Search Console | Whether it earns traffic today |
| Impressions, 16 months | Search Console | Whether demand exists even without clicks |
| Index status | Search Console Page indexing | Whether Google kept it at all |
| Internal links in | Crawl | Whether the site itself treats it as important |
| Last updated | CMS export | Whether the facts on it are current |
| Commercial value | You, on a three point scale | Everything, when two rows otherwise tie |
Eight columns is deliberate. Add a ninth and the sheet becomes a research project; drop to four and you will argue about every borderline row.
Step three: the decision rule
| Pattern | Action |
|---|---|
| Impressions and clicks both healthy | Keep. Refresh facts and move on. |
| High impressions, low clicks | Improve the title and description first, then the content. This is the fastest work on the sheet. |
| Two or more pages serving the same question | Merge into the strongest URL, 301 the others. |
| No impressions, no internal links, no commercial value | Remove and return 410, or redirect if a close parent exists. |
| No impressions but real commercial value | Rewrite against the query it should serve, then relink to it. |
| Indexed, dated facts, still ranking | Update in place. Keep the URL. |
| Not indexed and should be | Technical row, not a content row. Send it to the technical list. |
Step four: executing each action properly
- Improve. Rewrite the opening paragraph so it answers the query in the first two sentences, fix the title, add the sections the ranking pages cover and you do not. Meta descriptions covers the snippet half of this.
- Merge. Move the unique content across, then 301 the old URL to the survivor. A merge without a redirect throws away the links the old page had earned.
- Redirect. One hop, to the closest genuine equivalent. A redirect to the home page is a soft 404 in practice and Google treats it as one.
- Remove. 410 for content that is gone for good. It is a clearer instruction than 404 and gets the URL out of the index faster.
- Relink. Every page you keep or improve needs links from the pages that already rank. This is the step most audits skip and the one that moves positions.
The order to work in
- High impressions and low clicks. Existing demand, cheapest fix.
- Merges. They remove internal competition and consolidate signals in one move.
- Commercially valuable pages with no visibility. Rewrite and relink.
- Removals. Do them in batches with the date recorded, so the traffic line can be read afterwards.
- Everything else, in commercial value order.
Record the date of every batch in the sheet. Two months later the only question anyone asks is whether the audit worked, and a dated change log is the only way to answer it. Internal linking is worth running as its own pass once the merges are done.
Guard rails worth keeping
- Remove in batches, never all at once, so you can attribute any movement to a specific change.
- Keep a URL whenever it has earned external links, even when it has no traffic. Redirect it instead of deleting it.
- Check the canonical before calling two pages duplicates. Sometimes the second URL is a variant Google has already consolidated, and there is nothing to do.
- Re-audit annually on a normal site, and after any migration or large publishing push.
Questions buyers ask about A site content audit
How long does a content audit take?
For a few hundred URLs, a focused week to build the sheet and make the decisions, then the execution spread over a quarter. The inventory is quick; the rewriting is the work.
Does deleting pages help SEO?
Removing pages that serve no query and attract no links tidies crawling and removes internal competition. The gain comes from the merges and the relinking rather than the deletion count, so treat removal as housekeeping and the merges as the win.
Why sixteen months of Search Console data?
It is the full range the interface exports, and it covers a complete year plus a seasonal overlap, so you can tell a dead page from a seasonal one.
What about pages with traffic from other channels?
Keep them. The audit is a search decision, and a page earning email or social traffic has a job even with no impressions. Note the channel in the commercial value column.
Should thin pages be noindexed or deleted?
Delete or merge anything with no purpose. Reserve noindex for pages people need and search engines do not, such as internal search results, filtered views and thank you pages.
A column for how each page is quoted
Your audit sheet decides whether each page is kept, improved, merged, redirected or removed. The sheet has no column for what an assistant does with the page when a buyer asks the question it was written for. A page can rank and still be passed over, and a thin page can be quoted again and again.
Add one column, "named by assistant, yes or no", filled from five minutes of testing per priority page. AI Knows Us fills that column for a whole inventory of questions, so that the keep or merge decision uses both views of the page.