GitHub Actions SEO: How to Gate PRs on Broken Links and Schema Validation
These articles are AI-generated summaries. Please check the original sources for full details.
GitHub Actions SEO: gate PRs on broken links and schema
The fix is a GitHub Actions SEO workflow that gates every blog PR automatically. Four jobs check broken links, meta and canonical correctness, JSON-LD validity, and a Lighthouse performance budget; the merge button stays red until all four pass.
Why This Matters
Code review catches logic bugs but not SEO bugs—a broken canonical doesn’t throw a build error, a dead external link doesn’t fail a type check, and malformed JSON-LD doesn’t appear in a diff. These issues ship quietly and surface weeks later in Search Console. Automated CI gates prevent silent ranking degradation by enforcing technical correctness before merging.
Key Insights
-
- Broken links rot silently: External links that resolve during editorial review may 404 by the time a post ships; lychee-action scans Markdown files directly without building the site (576 links in ~60 seconds per benchmarks).
-
- Canonical mismatches split ranking signals: In Next.js App Router sites, pages can inherit canonicals from parent layouts (e.g.,
/blog/instead of/blog/your-post-slug/), sending ranking signals to the wrong URL without any visible error.
- Canonical mismatches split ranking signals: In Next.js App Router sites, pages can inherit canonicals from parent layouts (e.g.,
-
- JSON-LD validation is separate from Lighthouse: Lighthouse runs ~8 SEO audits per page but never validates structured data content; Schemar wraps the Schema Markup Validator to catch malformed properties or missing required fields that forfeit rich-result eligibility.
-
- Rich results boost CTR significantly: Nestlé measured 82% higher click-through rate for rich-result pages vs non-rich-result pages; Milestone Internet study of 4.5 million queries found 58 clicks per 100 queries for rich results vs 41 for standard results.
Working Examples
# .github/workflows/blog-seo.yml
name: Blog SEO checks
on:
pull_request:
paths:
- 'content/blog/**'
- '.github/workflows/blog-seo.yml'
jobs:
broken-links:
name: Broken links
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v7
- name: Check links
uses: lycheeverse/lychee-action@v2
with:
args: --verbose --no-progress 'content/blog/**/*.md'
fail: true
jobSummary: true
# scripts/check-meta.mjs
import { readdir, readFile } from 'node:fs/promises';
import { join, resolve } from 'node:path';
const SITE_URL = process.env.SITE_URL ?? 'https://yoursite.com';
const BLOG_DIR = resolve('.next/server/app/blog');
async function walk(dir) {
const entries = await readdir(dir, { withFileTypes: true });
const files = [];
for (const entry of entries) {
const full = join(dir, entry.name);
if (entry.isDirectory()) {
files.push(...await walk(full));
} else if (entry.name === 'page.html') {
files.push(full);
}
}
return files;
b}
async function checkPage(htmlPath) {
bconst slug = htmlPath.replace(BLOG_DIR + '/', '').replace('/page.html', '');
bconst html = await readFile(htmlPath, 'utf8');
bconst expectedUrl = `${SITE_URL}/blog/${slug}/`;
blet ok = true;
bconst description =
bhtml.match(/<meta[^>]+name="description"[^>]+content="([^"]+)"/i)?.[1] ??bhtml.match(/<meta[^>]+content="([^"]+)"[^>]+name="description"/i)?.[1] ??bnull;if (!description) {console.error(`[FAIL] Missing meta description: /blog/${slug}/`);process.exitCode = b1;ok = false;}// ... canonical and og:title checks omitted for brevity ...}
Practical Applications
- [Use case] Lyra’s autonomous blog writer uses this CI gate—agent drafts fast with fact-checking before opening the PR—then human review handles voice and accuracy. Pitfall : Skipping branch protection rules after setting up checks makes everything advisory; without requiring status checks to pass before merging ,the merge button stays active even when jobs fail .
References:
Continue reading
Next article
Building Your First AWS Network with Terraform: 4 Failures That Teach More Than Success
Related Content
AI News Weekly Summary: Jun 28 - Jul 05, 2026
Four automated CI checks—broken links, meta tags, JSON-LD, and Lighthouse budget—block PR merges until all pass, catching SEO bugs that... | A deploy wiped an in-memory registry causing false stoppage reports; duplicating workers and zombie processes exposed critical lifecycle flaws. | A lightweight...
Zero-Cost Facebook Auto-Poster: Build a Fully Automated Scheduler with Node.js and GitHub Actions
Learn to build a production-ready, zero-cost Facebook auto-poster using Node.js and GitHub Actions that posts daily quotes with images.
Automated Vulnerability Scanning for Homelab Containers with Trivy + AI
Space Terran released a GitHub Actions workflow that automates weekly Trivy scans and AI-powered risk assessment for all Docker images in a homelab organization.