Skip to content

v2.3.0 — Fix agentic readability blockers (is-agentic 64/100) - #101

Open
prabal-banerjee wants to merge 3 commits into
mainfrom
v2.3.0-agentic-readability
Open

v2.3.0 — Fix agentic readability blockers (is-agentic 64/100)#101
prabal-banerjee wants to merge 3 commits into
mainfrom
v2.3.0-agentic-readability

Conversation

@prabal-banerjee

Copy link
Copy Markdown
Contributor

Scanned the production deployment against is-agentic.com, which returned 64/100 — Essential 51.4/80, Recommended 11/20. This fixes the failing checks.

No human-facing content or layout was altered, with one exception called out below.

The main problem: nothing was server-rendered

NexusContainer returned a full-page <Skeleton> until a useEffect read localStorage, and Web3Provider wraps the entire app — so every page served ~0 characters of content in raw HTML. The canonical URLs and TechArticle/BreadcrumbList JSON-LD already generated in src/app/docs/[[...slug]]/page.tsx never reached the HTML either. One gate was failing four separate checks, and hurting SEO for the same reason.

Removing it is safe: the packaged NexusProvider builds its client inside useEffect(..., [stableConfig]) with destroy() cleanup, so it never touches browser APIs during render and correctly rebuilds the client when the stored network differs from the mainnet default.

Measured against a local next start:

Page Text in raw HTML <h1>
/ 35 → 1584 0 → 1
/docs/da/get-started 54 → 2541 0 → 1
/docs/nexus 40 → 966 0 → 1

Two further bugs, independent of that

All Avail DA markdown negotiation was broken. src/middleware.ts rewrote daDA, but content is canonicalized lowercase under content/docs/da/. In production, /docs/da/get-started with Accept: text/markdown returned 404 while the nexus equivalent returned 200. The .md suffix failed the same way, and uppercase /api/markdown/DA/* 404'd too. Both casings now resolve. robots.txt has been advertising this capability the whole time.

Vary: accept was emitted as a second header line, which CDNs and scanners commonly miss — the exact cache-mismatch the scan flags. Now a single merged value with Accept first.

Everything else

  • Agent-friendly 404s — markdown body naming the discovery indexes instead of an opaque {"error":"Page not found"}, keeping the 404 status.
  • Homepage structured data — canonical URL plus an Organization/WebSite/SoftwareApplication @graph. contactPoint and sameAs are built only from links and addresses already present in the repo; nothing invented. Docs pages get the full Organization node in place of the 3-field stub.
  • sitemap.xml now includes the homepage and the new pages — it previously listed docs pages only, so / was absent entirely.
  • llms.txt gains an Agent Endpoints section.

Needs a review decision

/about, /contact, /privacy (all 404 before) were added at the maintainer's request to satisfy the trust-anchor check. Content is written from behaviour verified in this repo — PostHog config, localStorage keys, the wallet flow, the feedback route.

Two things to look at:

  1. The privacy page should get a legal read. It is a legal document, and there is no canonical policy upstream to defer to (availproject.org/privacypolicy 404s).
  2. It discloses that feedback is public. /api/feedback files issues to availproject/docs-fumadocs, which redirects to the public availproject/docs — so submitted comments, contact details and screenshots are publicly visible. Documented here; you may prefer to change the behaviour instead.

Three footer links (About these docs, Privacy, Contact) were added so the pages aren't orphaned. That is the only human-visible change beyond the pages themselves, and is easy to drop.

Testing

The markdown-API and middleware suites were asserting the uppercase-DA behaviour that was breaking production, which is why the bug survived; they now encode the real content layout, plus regression tests for the casing and the .md suffix.

  • 100 vitest + 1 jest pass
  • pnpm build green
  • Biome error count unchanged from main (121 both)
  • Verified end-to-end against next start: DA negotiation 404 → 200, agent 404 returns markdown with 404 status, homepage JSON-LD graph parses with 3 contactPoint entries

Note: @avail-project/widgets has its own console.log("NEXUS PROVIDER CONFIG", ...) that now appears in server logs, since the provider actually renders on the server. Harmless; passing debug: false would silence it.

🤖 Generated with Claude Code

Scanned docs.availproject.org against is-agentic.com and fixed the
failing checks. No human-facing content or layout was altered; the three
new pages were added at the maintainer's request.

Server-rendered content (Essential — was failing)
Every page served ~0 chars of content in raw HTML. NexusContainer
returned a full-page <Skeleton> until a useEffect read localStorage, and
Web3Provider wraps the whole app, so the server emitted a skeleton for
the entire body. Existing canonical URLs and TechArticle/BreadcrumbList
JSON-LD never reached the HTML either.

NexusProvider builds its client inside useEffect([config]) with destroy()
cleanup, so it is SSR-safe and rebuilds correctly when the stored network
differs from the default. Dropping the gate is therefore safe.

  /                     35 ->  1584 chars
  /docs/da/get-started  54 ->  2541 chars
  /docs/nexus           40 ->   966 chars

Markdown content negotiation (Essential — was failing)
- middleware rewrote /docs/da/* to /api/markdown/DA/*, but content is
  canonicalized lowercase, so every Avail DA page 404'd on both the
  Accept: text/markdown and .md paths. Uppercase /api/markdown/DA/* 404'd
  as well. Both casings now resolve.
- Vary was emitted as a second header line, which CDNs and scanners
  commonly miss. Now one merged value, with Accept first.

Agent-friendly 404s (Essential — was partial)
404s return a markdown body naming the discovery indexes instead of an
opaque JSON error, keeping the 404 status.

Structured data and metadata (Recommended — were failing)
- Homepage: canonical URL plus an Organization/WebSite/SoftwareApplication
  @graph, with contactPoint and sameAs built only from links already in
  the repo.
- Docs pages: the 3-field Organization stub replaced with the full node.

Discoverability
- /about, /contact, /privacy added (previously 404). Privacy documents
  only verified behaviour, and discloses that feedback is filed to a
  public GitHub repo.
- sitemap.xml now includes the homepage and these pages; it previously
  listed docs pages only.
- llms.txt gains an Agent Endpoints section.

Tests updated: the markdown API and middleware suites asserted the
uppercase-DA behaviour that was breaking production. 100 vitest + 1 jest
pass; Biome error count unchanged from main (121).

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@vercel

vercel Bot commented Sep 4, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated
docs-fumadocs Ready Ready Preview Sep 4, 2026 4:33pm UTC

Request Review

Pulled the machine-readable report (is-agentic.com/api/v1/report) for the
production deployment, which gives per-check detail the HTML page omits.
Two things it revealed:

1. The markdown-negotiation check runs against the scanned URL — the site
   root — not a docs page. The middleware matcher covered /docs/* only, so
   `Accept: text/markdown` on / returned HTML and the check failed
   regardless of the DA casing fix. / now negotiates to the docs index.

2. The check reads only the first Vary header. On Vercel's edge Next's
   RSC-only Vary is emitted first, so the merged value was invisible —
   reported as "Vary header missing Accept". Local `next start` happened to
   order these the other way, which is why it looked correct there. Declared
   the merged Vary in vercel.json so the platform value wins.

Redirect rules deliberately do not run for "/" — the matcher covers it
solely for negotiation, and running them would change behaviour for a path
middleware previously never executed on.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Measured on the preview: header rules in vercel.json are not applied to
Next-served routes. HTML responses for both / and /docs/* came back with
only Next's own `vary: rsc, next-router-state-tree, ...`, so the rules
were dead config. The equivalent in next.config.mjs headers() was also
tested and appends rather than replaces, leaving Next's RSC-only Vary
first, so it is not kept either.

Accept still reaches the client as a second Vary line via AGENT_HEADERS,
which is valid HTTP — RFC 9110 treats repeated field lines as equivalent
to one comma-joined value. Whether the scanner credits it depends on
whether it combines duplicate headers or reads only the first.

The homepage negotiation fix from the previous commit is unaffected and
verified working on the preview: / with Accept: text/markdown now returns
text/markdown, and browsers still get HTML.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant