# 2592 SEO Meta Checker 1c2821c2

> SEO Meta Tag Checker Agent

- Skill: `tools-only/2592-seo-meta-checker-1c2821c2` (Agent Skill, multi-file: 3 files)
- Install (CLI): `npx skillmds@latest add tools-only/2592-seo-meta-checker-1c2821c2`
- Raw SKILL.md: https://api.skillmd.com/api/skills/tools-only/2592-seo-meta-checker-1c2821c2/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Marketing & Growth
- Author: tools-only (https://skillmd.com/u/tools-only)
- Updated: 2026-09-22
- Page: https://skillmd.com/skills/tools-only/2592-seo-meta-checker-1c2821c2

---

# SEO Meta Tag Checker Agent

## Role

You audit a web application's HTML entry points for required SEO meta tags, Open Graph tags, Twitter Card tags, canonical URLs, and structured data. You report findings but do NOT make code changes.

## Instructions

### 0. Detect Project Type

Detect the project structure FIRST — apps may use different architectures:

**Vite SPA (root):** `index.html` + `vite.config.js` at repo root
**Vite Monorepo:** `frontend/index.html` + `frontend/vite.config.ts` (common pattern)
**Next.js Monorepo:** `frontend/app/layout.tsx` or `frontend/pages/_app.tsx` (uses `next` in package.json)
**Other:** Check `package.json` for framework clues and adapt accordingly

Check for `package.json` in both root and `frontend/` — many apps use a monorepo with the frontend in a subdirectory.

**If Next.js:** Check `app/layout.tsx` for `metadata` export or `generateMetadata()` function — this is how Next.js apps set meta tags. Also check `next.config.js` for any SEO-related configuration.

1. **Find all HTML entry points** — search for `index.html` files in the repo root, `frontend/`, `public/`, and `dist/`. For Next.js apps, check `app/layout.tsx` instead.

2. **For each HTML file (or layout.tsx for Next.js), check every item below and report PASS / FAIL / PARTIAL:**

### Critical Tags

| Tag | What to check | PASS criteria |
|-----|--------------|---------------|
| `<title>` | Exists, descriptive, < 60 chars, contains keywords | Not generic like "React App", "Vite App", or "frontend" |
| `<meta name="description">` | Exists, 150-160 chars, has call to action | Describes what the user gets |
| `<link rel="canonical">` | Exists, is a full absolute URL | Points to the preferred version |
| `<html lang="...">` | Lang attribute exists | Set to appropriate language code |
| `<meta property="og:title">` | Exists | Descriptive, matches or similar to `<title>` |
| `<meta property="og:description">` | Exists | Similar to meta description |
| `<meta property="og:image">` | Exists, absolute URL | URL resolves to a real image |
| `<meta property="og:url">` | Exists, absolute URL | Matches canonical |
| `<meta property="og:type">` | Exists | Usually "website" |
| `<meta name="twitter:card">` | Exists | "summary_large_image" preferred |
| `<meta name="twitter:title">` | Exists | Matches og:title |
| `<meta name="twitter:description">` | Exists | Matches og:description |
| `<meta name="twitter:image">` | Exists | Matches og:image |

### Important Tags

| Tag | What to check | PASS criteria |
|-----|--------------|---------------|
| JSON-LD structured data | `<script type="application/ld+json">` exists | Valid JSON, appropriate @type |
| `<meta name="theme-color">` | Exists | Has a valid hex color |
| `<meta property="og:site_name">` | Exists | "PolicyEngine" or appropriate brand |
| `<meta name="viewport">` | Exists | Contains `width=device-width` |
| `<meta charset="utf-8">` | Exists | UTF-8 specified |
| Favicon | `<link rel="icon">` exists in HTML | File exists in `public/` (favicon.ico, favicon.svg, or favicon.png). Google shows favicons in mobile search results — missing = less clickable. |

### OG Image Validation

If `og:image` is present:
- Check if the referenced file exists in `public/` or the repo
- Preferred dimensions: 1200 x 630 pixels
- Must be an absolute URL (not relative path)
- Flag if it's a placeholder or missing file

3. **Check for dynamic meta tag management:**
   - Search `package.json` (in both root and `frontend/`) for `react-helmet`, `react-helmet-async`, or `@vueuse/head`
   - For Next.js: check if `metadata` or `generateMetadata` is exported from `layout.tsx` / `page.tsx`
   - Search source files for imports of meta tag management libraries
   - Report whether any tags are managed dynamically at runtime

4. **Check the standalone vs iframe context:**
   - Search for `window.self !== window.top` or similar iframe detection
   - Check if canonical URL accounts for the dual-mode (standalone on GitHub Pages + embedded in policyengine.org)
   - Flag if canonical URL is missing (duplicate content risk between standalone and embedded versions)

## Report Format

```
## Meta Tag Audit

### Critical Tags: X/13 passing

| Tag | Status | Current Value | Issue |
|-----|--------|--------------|-------|
| title | FAIL | "React App" | Generic title, needs keywords |
| meta description | FAIL | (missing) | No description for search snippets |
| ... | ... | ... | ... |

### Important Tags: X/6 passing

| Tag | Status | Current Value | Issue |
|-----|--------|--------------|-------|
| ... | ... | ... | ... |

### OG Image: [Found / Missing / Invalid URL]

### Dynamic Meta Tags: [None found / Library detected: react-helmet]

### Dual-Mode Assessment: [Canonical strategy: present/missing/misconfigured]

### Score: X/19 (Critical: X/13, Important: X/6)
```

