How to use this: Drop this file in the root of the kevindgraham.github.io repo, then tell Claude Code:
Read
seo-implementation-spec.mdand work through it phase by phase. Start with Phase 0 and report what you find before making changes. Show megit statusandgit diffbefore any commit, and don’t push until I say go.
Report back on:
_config.yml, _layouts/, _includes/.)<title> and <meta name="description">.sitemap.xml exist? robots.txt? A CNAME file?<h1> tags on any page?alt attributes?Do not make changes until this audit is reported.
Create at site root:
User-agent: *
Allow: /
Sitemap: https://kevindgraham.com/sitemap.xml
jekyll-sitemap plugin to _config.yml and let it generate.sitemap.xml manually listing every real page with <loc> and <lastmod>. Exclude 404 pages, thank-you pages, and any test files.Add a self-referencing canonical to every page:
<link rel="canonical" href="https://kevindgraham.com/PAGE-PATH/">
Pick ONE canonical form (with or without www, with or without trailing slash) and make every internal link match it.
Create a branded 404.html in the navy/gold palette that links back to the homepage, blog, and toolkit — not a dead end.
For every page, write unique values. No duplicates across the site.
| Element | Rule |
|---|---|
<title> |
50–60 characters. Front-load the search term, end with \| Kevin D. Graham |
<meta name="description"> |
140–160 characters. Written as a hook, not a summary |
<h1> |
Exactly one per page, and it should not be identical to the title tag |
<html lang="en"> |
Present on every page |
| Heading order | H1 → H2 → H3, no skipped levels |
Add to every page so links look right when shared:
<meta property="og:title" content="...">
<meta property="og:description" content="...">
<meta property="og:image" content="https://kevindgraham.com/images/og-default.jpg">
<meta property="og:url" content="https://kevindgraham.com/PAGE-PATH/">
<meta property="og:type" content="website">
<meta name="twitter:card" content="summary_large_image">
Flag if no OG image exists at 1200×630 — that one needs to be designed, not coded.
alt text to every image (describe the content, not “image of”).width and height attributes to prevent layout shift.loading="lazy" to any image below the fold.{
"@context": "https://schema.org",
"@type": "Person",
"name": "Kevin D. Graham",
"url": "https://kevindgraham.com",
"jobTitle": "Digital Media Educator and Content Creator",
"description": "...",
"sameAs": ["https://instagram.com/strategicdownloads"]
}
Include name, author, description, bookFormat, and the purchase URL.
Include headline, datePublished, dateModified, author, and image.
Only where real Q&A content exists on the page. Don’t fabricate questions to game it.
Validate every block against schema.org’s syntax before committing.
font-display: swap.If a blog post template exists, make sure every new post automatically gets:
If it doesn’t exist, create the template so future posts inherit all of this without manual work.
Before pushing, confirm:
sitemap.xml returns valid XML and lists every live pagerobots.txt points to the sitemap and blocks nothing importantThen show git status and git diff, and wait for approval before pushing to main.
These require a human and an account: