Audit a Next.js site's SEO with PageAudit
Audit the deployed page, fix the head with the Metadata API, add robots.txt and the sitemap, and audit again from npm.
Updated
1Add the audit script
Save the script as scripts/seo-audit.mjs. It needs Node 18 or newer and no package.
// Audits a page with PageAudit and fails when the page has SEO errors.
// Usage: node scripts/seo-audit.mjs https://example.com/
const page = process.argv[2] ?? "https://example.com/";
const response = await fetch("https://pageaudit.online/api/audit", {
method: "POST",
headers: { "content-type": "application/json" },
body: JSON.stringify({ url: page }),
});
const report = await response.json();
if (response.status === 402 || response.status === 429) {
console.warn("No free PageAudit audits left today. Run it again tomorrow.");
} else if (!response.ok) {
console.error(`PageAudit answered ${response.status}: ${report.error}`);
process.exitCode = 1;
} else {
const { errors, warnings } = report.counts;
console.log(`Score ${report.score}: ${errors} errors, ${warnings} warnings`);
for (const issue of report.issues.filter((i) => i.severity === "error"))
console.error(`${issue.code}: ${issue.message}`);
if (errors) process.exitCode = 1;
}2Add the npm command
Add the seo:audit command to package.json, with the address of your deployed page.
{
"scripts": {
"seo:audit": "node scripts/seo-audit.mjs https://example.com/"
}
}3Fix the head
Run npm run seo:audit. Missing titles, descriptions and canonical links go in app/layout.tsx, with the Metadata API.
import type { Metadata } from "next";
export const metadata: Metadata = {
metadataBase: new URL("https://example.com"),
title: { default: "Example Store", template: "%s | Example Store" },
description: "Handmade ceramic mugs and plates, shipped in 3 days.",
alternates: { canonical: "/" },
openGraph: { type: "website", siteName: "Example Store", images: ["/og.png"] },
};4Add robots.txt and the sitemap
Next.js serves both files from app/robots.ts and app/sitemap.ts. Deploy and run npm run seo:audit again.
// app/robots.ts
import type { MetadataRoute } from "next";
export default function robots(): MetadataRoute.Robots {
return {
rules: { userAgent: "*", allow: "/" },
sitemap: "https://example.com/sitemap.xml",
};
}
// app/sitemap.ts
import type { MetadataRoute } from "next";
export default function sitemap(): MetadataRoute.Sitemap {
return [{ url: "https://example.com/", lastModified: new Date() }];
}