SEO Landing
Give your AI coding agent the capabilities of a senior Technical SEO engineer.
An agent skill for building high-performance, technically optimized SEO landing pages. Turn an AI coding agent into a technical SEO specialist.
Build and improve landing pages with:
- π 100/100 Google PageSpeed target
- β‘ Core Web Vitals optimization
- π Technical SEO
- π§© Full Schema.org structured data
- πΌοΈ AVIF image optimization
- π¨ Critical CSS
- π§Ή Zero third-party requests on first load
- π± Mobile-first performance
- π€ Semantic HTML
π·πΊ ΠΠΏΠΈΡΠ°Π½ΠΈΠ΅ ΡΠΊΠΈΠ»Π° Π½Π° ΡΡΡΡΠΊΠΎΠΌ ΡΠ·ΡΠΊΠ΅
Works with AI coding agents
Designed for agentic coding workflows and compatible with Agent Skillsβstyle environments.
What it does?
The skill guides an AI coding agent through the complete landing-page workflow:
- Analyze the existing page
- Fix technical SEO issues
- Optimize HTML structure
- Improve Core Web Vitals
- Optimize images and fonts
- Add structured data
- Remove unnecessary dependencies
- Validate the final implementation
Why?
AI can generate a beautiful landing page in seconds. The problem is that generated pages often contain:
- unnecessary JavaScript
- oversized images
- poor semantic structure
- missing structured data
- weak metadata
- performance bottlenecks
- technical SEO mistakes
SEO Landing Skill gives the agent a repeatable technical SEO workflow instead of relying on generic prompting.
An agent skill that builds and updates landing pages toward 100/100 lab PageSpeed and Core Web Vitals-friendly performance, and gets the technical SEO right. Static HTML, critical CSS, AVIF images, full schema.org markup, zero third-party requests on first load (deferred widgets, when used, are consent-gated and documented in the dependency manifest). These are optimization targets, not guaranteed outcomes β results depend on content, hosting, devices, and real traffic; Core Web Vitals status itself is determined by Google from field (RUM) data, not by lab tools.
BEFORE
Landing page
β
LCP: 4.2s
Performance: 61
Missing schema
Large PNG
Render-blocking CSS
β SEO LANDING SKILL β
AFTER
Landing page
β
LCP: 1.1s
Performance: 100
Schema.org β
AVIF β
Critical CSS β
Semantic HTML β
Format β Agent Skills (open standard originally developed by Anthropic): works in VS Code Copilot, Claude Code, OpenAI Codex, Google Antigravity, Cursor, Gemini CLI, OpenClaw, Hermes, and other compatible agents.
What's inside
seo-landing/
βββ SKILL.md # Main workflow: mode routing β brief β generation β stop point β validation β report
βββ references/
β βββ tech-spec.md # Technical spec (13 requirement sections + executable validation contract)
β βββ server-config.md # Server config: caching, Brotli/gzip, security headers (Nginx/Apache)
β βββ video-facade.md # Reference implementation of the "facade" pattern for YouTube
β βββ map-facade.md # Reference implementation of the "facade" pattern for map embeds
βββ benchmark/ # Lab benchmark disclosure: fixture, raw Lighthouse reports, methodology
βββ tests/
βββ fixtures/broken-landing/ # Negative fixture: every validator gate must fail on it
Key requirements enforced by the skill
- Performance: LCP < 2.5s, INP < 100ms, CLS < 0.1; critical CSS inlined, the rest loaded async; the LCP image loads eagerly with
fetchpriority="high"(a responsiveimagesrcset/imagesizespreload only when measurement shows a benefit) - Images: AVIF β WebP β JPEG via
<picture>,srcset/sizes,width/height,loading="lazy"for below-the-fold images only (never on the LCP image), breakpoints 320β1920 - SEO: title/description/canonical/robots, Open Graph, Twitter Card, JSON-LD (
WebSite,Organization,BreadcrumbList,FAQPage,VideoObjectβ emitted only when fact-backed and reported per the chosen video mode, never as a guaranteed search feature) - Accessibility: WCAG 2.1 AA, contrast β₯ 4.5:1, keyboard navigation,
prefers-reduced-motion - Security:
X-Content-Type-Options,X-Frame-Options,Permissions-Policy,Referrer-Policy, per-page CSP, staged HSTS, HTTPS enforcement,rel="noopener noreferrer" - Fonts: system fonts only β no external fonts, no Google Fonts
- JS budget β€ 15 KB for the first load, one file with
defer; deferred third-party widgets (when used) are consent-gated, excluded from the budget, and disclosed in the dependency manifest - Forbidden: external JS/CSS libraries, SVG images, synchronous scripts, iframes on first load
- Video & maps: "facade" pattern by default β the cover is a local responsive image (eager when it is the LCP/above the fold, lazy below the fold), the iframe loads only on click. Click-only video trades Google video discovery for pre-activation privacy/performance; an opt-in SEO-discoverable mode (self-hosted
<video>or a documented direct embed) exists when video search matters (tech-spec Β§9). Maps remain facade-only. - Common blocks without JS: FAQ via
<details>, slider viascroll-snap, modal via<dialog> - Stop point: before validation and the final report, the skill always asks the user to confirm the HTML version
Real-world result (lab measurements β not field Core Web Vitals)
One reproducible lab benchmark: Lighthouse CLI 13.4.1, mobile emulation, simulated throttling. Original β an Angular SPA (102 requests, 1 run); the same page rebuilt as static HTML with this skill (17β18 requests, median of 5 runs). Full disclosure β fixture, exact flags, raw JSON reports, timestamps, and aggregation method β is in benchmark/README.md.
| Metric | Original | Rebuilt | Gain |
|---|---|---|---|
| Performance | 75 | 100 | +25 |
| Accessibility | 75 | 100 | +25 |
| Best Practices | 73 | 100 | +27 |
| LCP | 3.3 s | 1.6 s | β52% |
| Total Blocking Time | 490 ms | 13 ms | β97% |
| TTI | 9.4 s | 1.6 s | β83% |
| Data transferred | 769 KiB | 110 KiB | β86% |
| Requests | 102 | 17 | β83% |
These are lab numbers for one before/after pair. They are not field Core Web Vitals (Google determines CWV status from CrUX/RUM field data at the 75th percentile, and Lighthouse cannot measure INP without real interaction), and they are not a guarantee that another page, host, device, or audience will reach the same results β the skill's targets are optimization goals, not promised outcomes.
Installation
The skill is hosted at github.com/aleksandr-alhoff/seo-landing. Clone the repository β the repo root is the skill folder itself β then run the commands below from the directory that contains seo-landing/:
git clone https://github.com/aleksandr-alhoff/seo-landing.git
Global (available in all projects)
Every recipe below is self-contained: it creates its destination directory first, then copies the skill into it. Each one must exit with status 0 and leave the layout <skills-dir>/seo-landing/SKILL.md in place.
Note: cp -R from a git clone also copies the clone's .git directory into the installation β harmless, but unnecessary. To keep installations lean, replace cp -R seo-landing <dir>/ with rsync -a --exclude=.git seo-landing <dir>/seo-landing/ (the same sync used for updates below).
# VS Code Copilot
mkdir -p ~/.copilot/skills
cp -R seo-landing ~/.copilot/skills/
# Claude Code
mkdir -p ~/.claude/skills
cp -R seo-landing ~/.claude/skills/
# OpenAI Codex CLI / ChatGPT desktop
mkdir -p ~/.agents/skills
cp -R seo-landing ~/.agents/skills/
# Cursor
mkdir -p ~/.cursor/skills
cp -R seo-landing ~/.cursor/skills/
# Gemini CLI
mkdir -p ~/.gemini/skills
cp -R seo-landing ~/.gemini/skills/
# Google Antigravity
mkdir -p ~/.gemini/config/skills
cp -R seo-landing ~/.gemini/config/skills/
# OpenCode
mkdir -p ~/.config/opencode/skills
cp -R seo-landing ~/.config/opencode/skills/
# OpenClaw (via CLI β installs into the shared ~/.openclaw/skills)
openclaw skills install git:aleksandr-alhoff/seo-landing --global
# or from a local clone: openclaw skills install ./seo-landing --global
# or manually:
mkdir -p ~/.openclaw/skills
cp -R seo-landing ~/.openclaw/skills/
# Hermes
mkdir -p ~/.hermes/skills
cp -R seo-landing ~/.hermes/skills/
OpenClaw also picks up skills from ~/.agents/skills (the Codex path above), and Hermes can scan it too if you add ~/.agents/skills to skills.external_dirs in ~/.hermes/config.yaml.
Gemini CLI can also install straight from a Git repository:
gemini skills install https://github.com/aleksandr-alhoff/seo-landing.git
Per project (workspace only)
# Shared .agents/skills β picked up by VS Code Copilot, Codex, Cursor, Antigravity, Gemini CLI, OpenCode, OpenClaw, Hermes
mkdir -p .agents/skills
cp -R seo-landing .agents/skills/
# Claude Code
mkdir -p .claude/skills
cp -R seo-landing .claude/skills/
# VS Code Copilot (GitHub-style location)
mkdir -p .github/skills
cp -R seo-landing .github/skills/
# OpenClaw (workspace skills β highest precedence)
# via CLI: openclaw skills install ./seo-landing
mkdir -p skills
cp -R seo-landing skills/
# Hermes (project-local; then trust the repo once: hermes skills trust)
mkdir -p .hermes/skills
cp -R seo-landing .hermes/skills/
Updating, verifying, and uninstalling installed copies
Two facts drive everything below:
git pullchanges only the clone. An installed copy made withcp -Ris independent β pulling the source clone does NOT update any installation.cp -Rcopies, it does not synchronize. GNUcphas no destination-sync/removal behavior: a file deleted upstream stays in the installed copy forever, producing a mixed release of old and new instructions.
So an update is an explicit, bounded, idempotent sync into the resolved skill destination β never a blind re-copy.
Destinations (one per client and scope)
| Client / scope | Installed skill destination ($DEST) |
|---|---|
| VS Code Copilot β global | ~/.copilot/skills/seo-landing |
| Claude Code β global | ~/.claude/skills/seo-landing |
| OpenAI Codex CLI / ChatGPT desktop β global | ~/.agents/skills/seo-landing |
| Cursor β global | ~/.cursor/skills/seo-landing |
| Gemini CLI β global | ~/.gemini/skills/seo-landing |
| Google Antigravity β global | ~/.gemini/config/skills/seo-landing |
| OpenCode β global | ~/.config/opencode/skills/seo-landing |
| OpenClaw β global | ~/.openclaw/skills/seo-landing |
| Hermes β global | ~/.hermes/skills/seo-landing |
| Shared per-project (Copilot, Codex, Cursor, Antigravity, Gemini CLI, OpenCode, OpenClaw, Hermes) | .agents/skills/seo-landing |
| Claude Code β per project | .claude/skills/seo-landing |
| VS Code Copilot β per project (GitHub-style) | .github/skills/seo-landing |
| OpenClaw β workspace (highest precedence) | skills/seo-landing |
| Hermes β per project | .hermes/skills/seo-landing |
Update (idempotent sync, removes upstream-deleted files)
Run from the directory that contains the updated seo-landing/ clone, with $DEST set to the destination from the table above:
DEST=~/.copilot/skills/seo-landing # β substitute the right destination
# 1. Recovery first: back up the current installation (the sync is destructive).
cp -R "$DEST" "$DEST.backup-$(date +%Y%m%d)"
# 2. Bounded idempotent sync: copy new/changed files AND delete files inside
# $DEST that no longer exist upstream. --delete only ever touches $DEST.
rsync -a --delete --exclude=.git seo-landing/ "$DEST/"
# 3. Verify: zero differences (exit status 0) and the installed SKILL.md
# matches the source revision byte-for-byte.
diff -qr -x .git seo-landing "$DEST" && cmp "$DEST/SKILL.md" seo-landing/SKILL.md
Notes:
rsync -a --deleteis available out of the box on macOS (openrsync) and on typical Linux systems;--exclude=.gitkeeps the clone's history out of the installation.- The backup in step 1 is the recovery path: if the new version misbehaves, restore it with
rm -rf "$DEST" && cp -R "$DEST.backup-<date>" "$DEST". (macOS openrsync does not support--backup, so the explicit copy is the verified mechanism.) - The sync is safe to re-run at any time β running it twice in a row changes nothing the second time.
- Tested upgrade path: an installation containing a file that the new revision removed loses that file after the sync, and the installed
SKILL.mdbecomes byte-identical to the source revision.
Verify an existing installation at any time
diff -qr -x .git seo-landing "$DEST"
Exit status 0 (no output) means the installation matches the clone exactly. Any printed difference is a stale, modified, or extra file β re-run the update sync to resolve it. To check which specification version is installed, read the Version line at the top of $DEST/references/tech-spec.md (the single source of truth for versions).
Reload / restart after an update
Agents read skills when a session starts. After updating, start a new chat session (or restart the agent CLI) before relying on the new version. Clients that gate skills behind trust/approval (e.g. Hermes: hermes skills trust) may require re-trusting the updated copy.
Uninstall
rm -rf "$DEST" # the destination from the table above
If the copy was installed through a client CLI (openclaw skills install, gemini skills install), prefer that client's own uninstall command when it provides one; otherwise removing the destination directory is sufficient. Also remove any backups ($DEST.backup-*) you no longer need.
Symlinked installations β optional/experimental
Symlinking the clone into a skills directory (so git pull updates it in place) is possible in principle, but official symlink support, trust handling, and reload behavior differ per client and are NOT verified here β treat this as experimental. The rsync sync above is the supported, client-independent update path.
Once installed, the skill is picked up automatically by its description β just ask your agent to "build a landing page from a brief with focus on SEO and PageSpeed".
Usage
- Give the agent a brief: domain, language (BCP-47 tag, base direction for RTL languages, and Open Graph locale β three separate inputs), topic and keywords, business type, CTA and contacts.
- The skill creates a separate project folder (
<workspace>/<project-slug>/) withindex.htmland every local asset it references (all image variants, favicon), plus β conditionally βstyles.css(deferred CSS only),script.js(when JS is used),robots.txt,sitemap.xml,ASSETS.md, andSERVER-SETUP.md. Missing source images are requested from the user, never invented. - At the stop point, confirm the HTML version β the skill then runs validation (local asset/link existence, W3C, JSON-LD, Lighthouse as automated evidence, plus required manual accessibility checks) and produces a report: LCP, PageSpeed scores, and the schema.org types used.
About the author
Aleksandr Alhov β 14+ years of experience in SEO, content marketing, and GEO/AEO. Runs an SEO boutique for product teams working across EN, LATAM, MENA, and CIS markets: building in-house SEO departments turnkey, launching profitable corporate media, discovering growth hypotheses in the SEO channel, and providing hands-on SEO consulting.
Co-founder of:
Made for the t.me/sdelay_tam channel β a cozy SEO channel for product teams. SEO questions: t.me/alhov.
License
MIT β free to use, modify, and distribute, including commercially. Just keep the copyright notice. Specification: see references/tech-spec.md β the current version and change record are declared there.
No comments yet
Be the first to share your take.