agentleFS
Kin9ZeusKin9Zeus/senior-engineer-skills/skills/web-presence-audit/SKILL.md

web-presence-audit

Skill3 starsChanged 2 months agoMITView on GitHub

Audit and build the public surface of a website to professional standards — technical SEO (robots.txt, sitemap, canonicals, indexing, custom 404), on-page metadata (unique titles, meta descriptions, Open Graph and social share images, alt text), structured data including LocalBusiness and FAQ schema, internal linking architecture, and the trust and conversion surface (case studies, FAQ page, response-time commitment, thank-you pages, sticky mobile CTA, cookie notice, legal pages). Use when the user shares a website URL, or says "SEO", "meta tags", "robots.txt", "sitemap", "404 page", "not showing up in Google", "structured data", "schema markup", "Open Graph", "social preview", "alt text", "internal links", "landing page", "trust", "conversion", "case studies", "FAQ page" or "make my site professional"; and as a mandatory pass in any audit of a public-facing project. By Devleck.

We split this skill into the rules it gives an agent

8 rules. About 0 are common, 5 are distinctive, and 3 are very specific to this project.

  • ≈0

    Common · estimate

    Many files like this have a rule of this kind.

  • ≈5

    Distinctive · estimate

    This author's own choices. Worth a look.

  • 3

    Very specific

    Tied to their project's names, files or tools. Probably skip.

  • Common
  • Distinctive
  • Very specific
  1. Distinctive:

    Every gap here costs traffic, conversion or credibility — and unlike most engineering debt, the cost is continuous and silent.

    line 10
  2. Very specific:

    Verify against the live rendered page, not the source.

    line 22
  3. Very specific:

    Run scripts/web-check.sh <url> for the automated first pass.

    line 24
  4. Distinctive:

    Check it on every deploy.

    line 52
  5. Distinctive:

    Test with the platforms' own debuggers.

    line 117
  6. Distinctive:

    Never begin with "image of" or "photo of".

    line 126
  7. Very specific:

    Add matching padding-bottom to the page so it never covers content — especially the last form field or the footer links.

    line 307
  8. Distinctive:

    Do not stack it with a cookie banner and a chat widget — three fixed elements is 40% of a phone screen and reads as hostile.

    line 313

≈ “Common” is an estimate: at least 1 in 5 of the 308,232 skill files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.

Keep what fits and drop the rest. Your version, ready for your agents.
Files
SKILL.md

Web Presence Audit

The public surface is where the product meets people who do not yet trust it. Every gap here costs traffic, conversion or credibility — and unlike most engineering debt, the cost is continuous and silent.

This skill covers four layers. Run them in order; each depends on the one above.

1. CRAWLABLE   Can a machine find, fetch and index this at all?
2. LEGIBLE     Does each page declare what it is, uniquely and correctly?
3. STRUCTURED  Can a machine understand the entities and answer questions with it?
4. TRUSTED     Would a stranger believe this is a real business and act?

Verify against the live rendered page, not the source. Server-side headers, proxies, CDNs and client-side rendering all change what a crawler actually sees. Run scripts/web-check.sh <url> for the automated first pass.


Layer 1 — Crawlable

CheckRequirementSeverity if missing
robots.txtExists at the root, does not accidentally block the site, references the sitemapP1
sitemap.xmlGenerated (never hand-maintained), only canonical indexable URLs, submitted to Search ConsoleP2
Custom 404Returns a real 404 status, offers navigation and search, does not dead-endP2
Custom 500Branded, leaks no stack traceP2
Canonical URLOne per page, self-referencing by defaultP2
HTTPSEnforced, HTTP redirected once, no mixed contentP1
One hostnamewww and apex resolve to one canonical host, 301 not 302P2
Trailing slashConsistent; the other form redirectsP3
No index bloatFilters, sorts, pagination and internal search not indexableP2
Render checkContent present without JavaScript, or server-renderedP1 for a content site
No orphan pagesEvery important page reachable by internal linksP2

The two failures that silently destroy traffic:

A soft 404 — a missing page returning 200 with "not found" text. Crawlers index it, and every mistyped URL becomes a thin duplicate page. Test with curl -o /dev/null -w '%{http_code}' https://site.com/nonexistent-xyz.

A blocking robots.txt shipped from staging. Disallow: / deployed to production removes the site from search entirely, and nobody notices for weeks. Check it on every deploy.

# robots.txt — a sane default
User-agent: *
Allow: /
Disallow: /admin/
Disallow: /api/
Disallow: /*?sort=
Disallow: /search

Sitemap: https://example.com/sitemap.xml

robots.txt controls crawling, not indexing. To keep a page out of the index, use <meta name="robots" content="noindex"> — and do not also block it in robots.txt, or the crawler cannot see the noindex.


Layer 2 — Legible

Every page needs its own:

<title>Ergonomic Standing Desks for Home Offices | Devleck</title>
<meta name="description" content="Height-adjustable desks built for small
      spaces, shipped in 3 days with a 10-year frame warranty. Compare six
      models and find yours.">
<link rel="canonical" href="https://example.com/desks/standing">

<!-- Social share — the difference between a link that gets clicked and one
     that looks broken -->
<meta property="og:type" content="website">
<meta property="og:title" content="Ergonomic Standing Desks for Home Offices">
<meta property="og:description" content="...">
<meta property="og:image" content="https://example.com/og/desks.png">
<meta property="og:image:width" content="1200">
<meta property="og:image:height" content="630">
<meta property="og:url" content="https://example.com/desks/standing">
<meta property="og:site_name" content="Devleck">
<meta property="og:locale" content="en_US">
<meta name="twitter:card" content="summary_large_image">
<meta name="twitter:image:alt" content="A white standing desk in a small home office">

Titles

  • Unique on every page. Duplicated titles are the most common on-page defect and they make your pages compete with each other. A site-wide title set in the layout is a P2 finding on every page it touches.
  • Roughly 50–60 characters before truncation. The distinctive words go first — a title that begins with the brand wastes the position that matters.
  • Describe the page, do not stuff keywords.

Meta descriptions

  • Unique per page, roughly 140–160 characters.
  • They are not a ranking factor; they are ad copy for the search result. Write them to earn the click: state the value and include an implicit call to action.
  • Missing means the engine writes one for you, usually badly.

Social share image (og:image)

  • 1200×630, under ~1MB, an absolute URL (relative URLs silently fail).
  • Legible at thumbnail size — large type, high contrast, no fine detail.
  • Page-specific where it matters. One generic logo across a whole site is a missed opportunity on every share.
  • Test with the platforms' own debuggers; each caches aggressively, so a fix is not visible until you force a re-scrape.

Alt text

  • Every meaningful image gets alt text describing its function in context, not its appearance. A product photo's alt is the product; a chart's alt is the finding it shows.
  • Decorative images get alt="" — empty, not missing. Missing alt makes a screen reader announce the filename.
  • Never begin with "image of" or "photo of".
  • Text inside an image must be repeated in the alt, or the information is lost to search engines and screen readers alike.

Heading structure

  • Exactly one <h1> per page, matching the page's subject.
  • Ordered without skipping levels. Headings are structure, not styling — a <h4> chosen because it looks right is a defect.

Language and locale

  • <html lang="en"> set correctly.
  • hreflang for multi-language sites, reciprocal and self-referencing.

Layer 3 — Structured

Structured data (JSON-LD) is how a machine understands entities rather than strings. It drives rich results, knowledge panels, and increasingly what AI assistants can cite about you.

The baseline set for any business site:

<script type="application/ld+json">
{
  "@context": "https://schema.org",
  "@graph": [
    {
      "@type": "Organization",
      "@id": "https://example.com/#org",
      "name": "Devleck",
      "url": "https://example.com",
      "logo": "https://example.com/logo.png",
      "sameAs": [
        "https://www.linkedin.com/company/devleck",
        "https://github.com/Kin9Zeus"
      ],
      "contactPoint": {
        "@type": "ContactPoint",
        "contactType": "customer support",
        "email": "support@example.com",
        "availableLanguage": ["English", "Spanish"]
      }
    },
    {
      "@type": "WebSite",
      "@id": "https://example.com/#website",
      "url": "https://example.com",
      "name": "Devleck",
      "publisher": { "@id": "https://example.com/#org" }
    }
  ]
}
</script>

LocalBusiness — for any business with a physical location or a service area. This is what drives map results and the local pack; without it a local business is largely invisible in the search that matters most to it.

<script type="application/ld+json">
{
  "@context": "https://schema.org",
  "@type": "LocalBusiness",
  "@id": "https://example.com/#localbusiness",
  "name": "Devleck",
  "image": "https://example.com/storefront.jpg",
  "url": "https://example.com",
  "telephone": "+1-555-0100",
  "priceRange": "$$",
  "address": {
    "@type": "PostalAddress",
    "streetAddress": "123 Main Street",
    "addressLocality": "Austin",
    "addressRegion": "TX",
    "postalCode": "78701",
    "addressCountry": "US"
  },
  "geo": { "@type": "GeoCoordinates", "latitude": 30.2672, "longitude": -97.7431 },
  "openingHoursSpecification": [{
    "@type": "OpeningHoursSpecification",
    "dayOfWeek": ["Monday","Tuesday","Wednesday","Thursday","Friday"],
    "opens": "09:00", "closes": "18:00"
  }],
  "areaServed": { "@type": "City", "name": "Austin" }
}
</script>

NAP consistency — Name, Address, Phone must be byte-identical across the site, the schema, the business listing and every directory. Inconsistency splits the entity and suppresses local ranking.

Per page type: Article / BlogPosting (with author, datePublished, dateModified), Product + Offer, FAQPage, BreadcrumbList, SoftwareApplication, Event, Recipe, JobPosting.

Rules that keep it working:

  • Mark up only what is visible on the page. Schema describing content a user cannot see is a policy violation and gets rich results revoked.
  • Never fabricate reviews or ratings. Invented AggregateRating is fraud, and it is detectable.
  • Validate with the Rich Results Test and the Schema.org validator after every template change. Silent breakage is the norm.

references/structured-data.md has the full templates.


Layer 4 — Trusted

This is the layer engineers skip and businesses lose money to. A technically perfect site that reads as anonymous does not convert.

Internal linking

  • Every important page reachable within three clicks of the homepage. An orphan page is one nobody — human or crawler — will find.
  • Descriptive anchor text. "Read our pricing" beats "click here" for accessibility, for search, and for the reader scanning the page.
  • Contextual links inside body content, not only in the navigation. Contextual links carry topical meaning that a nav link does not.
  • Breadcrumbs on any site deeper than two levels, with BreadcrumbList schema.
  • A related-content block on articles and products.
  • Fix broken internal links. They waste crawl budget and read as neglect.
  • An HTML sitemap page for large sites.

The pages a credible business has

PageWhy it matters
Custom 404A dead end loses the visitor. Offer navigation, search and the top destinations
FAQ pageAnswers objections before they become "I'll think about it". Mark up with FAQPage schema for rich results and AI citation
Case studiesThe single most persuasive asset a B2B or service business has. Structure: the client's situation → what was done → measured outcome → a quote. Vague case studies are worse than none
Thank-you pageA real URL, not a modal. It is the conversion tracking anchor, and it is where you set the next expectation ("we reply within 4 business hours") and offer the next step
About / teamReal names, real photos, real location. Anonymity is the strongest negative trust signal on the internet
ContactMultiple channels, a stated response time, and a real address if there is one
PricingEven a range. "Contact us for pricing" loses visitors who will not start a conversation blind
Privacy policyLegally required almost everywhere. See privacy-compliance
Terms of serviceRequired for anything transactional
Cookie noticeMust gate scripts before consent, not apologise after. See privacy-compliance
Data deletionA self-service path, not "email us". See privacy-compliance
Status pageFor any SaaS. Silence during an outage costs more than the outage
Security / security.txtA disclosure contact at /.well-known/security.txt

The response-time commitment

State it explicitly, wherever a visitor is deciding whether to make contact — the contact page, the form, the thank-you page and the footer:

We reply to every enquiry within one business day. Support: within 4 business hours, Monday–Friday, 09:00–18:00 CET.

Two reasons this matters more than it looks. It removes the "will anyone even answer?" hesitation at the exact moment of decision. And it is a promise, so it must be true and monitored — an unmet stated commitment does more damage than no commitment at all.

Sticky mobile CTA

More than half of traffic is mobile, and mobile users scroll far and rarely scroll back. A persistent bottom bar keeps the action always one tap away.

<div class="cta-bar" role="region" aria-label="Primary action">
  <a href="/get-started" class="cta-bar__button">Get a free quote</a>
</div>
.cta-bar {
  position: fixed; inset-inline: 0; bottom: 0; z-index: 40;
  padding: .75rem 1rem calc(.75rem + env(safe-area-inset-bottom));
  background: var(--surface); border-top: 1px solid var(--border);
}
@media (min-width: 768px) { .cta-bar { display: none; } }   /* mobile only */

Do it correctly, or it costs more than it gains:

  • Add matching padding-bottom to the page so it never covers content — especially the last form field or the footer links.
  • One action only. Two competing buttons in a 60px bar is a decision, not a CTA.
  • Minimum 44×44px touch target; respect env(safe-area-inset-bottom) on notched devices.
  • Keyboard reachable, and not a focus trap.
  • Do not stack it with a cookie banner and a chat widget — three fixed elements is 40% of a phone screen and reads as hostile.

Trust signals throughout

Real customer logos (with permission), specific testimonials with a name, role and company, third-party review scores, certifications and compliance badges, a physical address, years in business, and any guarantee you actually offer.

Specific beats superlative. "Reduced their onboarding from 6 weeks to 4 days" is persuasive; "world-class solutions" is noise.


Reporting

Report per page, not per site — "meta descriptions are missing" is not actionable; a table of which pages, with the suggested text, is.

| Page | Title | Description | Canonical | OG image | H1 | Alt gaps | Schema |
|---|---|---|---|---|---|---|---|
| / | ✓ | ✗ missing | ✓ | ✓ | ✓ | 0/12 | Organization, WebSite |
| /pricing | ⚠ duplicate of / | ✗ missing | ✓ | ✗ | ✓ | 2/5 | none |
| /blog/x | ✓ | ✓ | ✗ points to / | ✓ | ⚠ two h1 | 4/9 | Article |

Then the prioritised findings, with the exact replacement text where you can supply it. A finding that says "write a meta description" is half a finding; one that includes the description is a completed task.

References, templates and scripts

  • references/technical-seo.md — crawling, indexing, canonicals, redirects, migrations
  • references/onpage-and-content.md — titles, descriptions, headings, images, internal linking
  • references/structured-data.md — JSON-LD templates for every common page type
  • references/trust-and-conversion.md — the trust surface, case studies, FAQ, CTA, forms
  • templates/robots.txt · templates/404-page.md · templates/faq-page.md · templates/case-study.md · templates/thank-you-page.md
  • scripts/web-check.sh / scripts/web-check.ps1 — live surface check for any URL

Download now (ZIP)

Does it work?

Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.

No reviews yet

People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.

  • It worked
  • Partly
  • It didn't
What did you use it for? e.g. Reviewing pull requests in a Rails app

Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.

Your trail

Files you open will collect here, so you can find them again.

Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.

Now do this for your own.

Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.