Skip to content
metafix

Technical SEO for Next.js App Router

SEO fixes that arrive as pull requests.

Metafix crawls your live site, finds technical SEO issues, maps each one to the file that causes it, and opens a pull request with the fix. You review the diff. Nothing reaches your default branch without you.

Free, no sign-in. Reads your sitemap and up to 50 pages.

Pull requests are in private beta.

audit: live · pull requests: private beta

seo: fix 8 issues in 3 files #42

Openmetafix[bot]metafix/seo-fixes-2026-10-04intomain Checks passed
app/pricing/page.tsx
unchanged: import type { Metadata } from "next";
unchanged: import { Plans } from "@/components/plans";
unchanged:
removed: export const metadata: Metadata = {};
added: export const metadata: Metadata = {
added: title: "Pricing",
added: description: "Plans for teams of any size.",
added: alternates: { canonical: "/pricing" },
added: openGraph: {
added: type: "website",
added: url: "/pricing",
added: title: "Pricing",
added: description: "Plans for teams of any size.",
added: images: ["/og/pricing.png"],
added: },
added: };
unchanged:
unchanged: export default function PricingPage() {
unchanged: return <Plans />;
unchanged: }
  • app/layout.tsx+2 -0
  • components/hero.tsx+2 -2

Flagged, not guessed (2)

  • app/blog/[slug]/page.tsx — metadata comes from getPostMeta(), can't parse, left untouched
  • /old-pricing — 404, no redirect target known
Sample PR · illustrative

From crawl to verified fix

Illustrative output. Steps 2 to 5 are in private beta.

  1. Crawl and audit

    Reads your sitemap and every page it lists, respects robots.txt, and runs deterministic rules. No model decides what is broken.

    87 pages · 56 issues

  2. Map to code

    Resolves each URL to the App Router file that renders it, through route groups, dynamic segments and layouts.

    /pricing → app/pricing/page.tsx

  3. Fix

    A model writes only the text: descriptions, alt text, JSON-LD values. It is schema-validated, and the code change is made on the AST.

    + description: "Plans for teams of any size."

  4. Open the pull request

    A new branch and a pull request listing every change. Never your default branch.

    metafix/seo-fixes-2026-10-04 → #42

  5. Verify

    After you merge and deploy, Metafix re-crawls and marks each issue resolved, then re-runs on a schedule to catch regressions.

    re-crawl: 8 of 8 resolved

Six kinds of fix. One reviewable diff.

Missing or duplicated titles and descriptions get a written value in the page's metadata export.

title-missing · title-duplicate · meta-description-missing · meta-description-duplicate

app/pricing/page.tsx
removed: export const metadata: Metadata = {};
added: export const metadata: Metadata = {
added: title: "Pricing",
added: description: "Plans for teams of any size.",
added: };

When we don't fix itMetadata that comes from a CMS or a helper we can't parse is flagged in the PR description, never guessed.

Ground rules

The commitments the pull-request pipeline is built around.

  1. 01

    Never pushes to your default branch.

    Branch and pull request only. Always.

    branch + PR only
  2. 02

    The audit is deterministic.

    No model decides what is broken. Every rule is a pure function with fixture tests.

    pure functions
  3. 03

    The model only writes text.

    Meta descriptions, alt text and JSON-LD values, schema-validated before they can reach a PR.

    zod
  4. 04

    Unsupported patterns are flagged, not guessed.

    Metadata from a CMS or a helper we can't parse is listed in the PR description and left untouched.

    flagged items
  5. 05

    Code is edited through the AST.

    No regex, no string replacement. Minimal diffs that keep your formatting.

    ts-morph

Run your first audit.

Paste a production URL. You'll get a report in about a minute.

Free, no sign-in. Reads your sitemap and up to 50 pages.

Want the pull requests when they open up?