Skip to content

Add docs metadata helpers and deployment recipes#57

Merged
KayleeWilliams merged 3 commits into
mainfrom
KayleeWilliams/p3-issues
May 16, 2026
Merged

Add docs metadata helpers and deployment recipes#57
KayleeWilliams merged 3 commits into
mainfrom
KayleeWilliams/p3-issues

Conversation

@KayleeWilliams
Copy link
Copy Markdown
Collaborator

Summary

  • add framework-neutral JSON-LD helpers with overrides and safe script stringification
  • add a Next App Router createGenerateMetadata helper with metadata and OpenGraph override support
  • dogfood the metadata helpers in the Next example and document deployment recipes for generated artifacts

Validation

  • commit hooks ran bun test and Ultracite on both commits
  • bun --filter leadtype build
  • bun --filter leadtype test
  • bun --filter leadtype check-types
  • ./node_modules/.bin/tsgo --noEmit in apps/next-example
  • ./node_modules/.bin/next build --webpack in apps/next-example
  • bun x ultracite check

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 16, 2026

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: 23a1e88e-0d8b-4efc-9c8a-309b94e975e4

📥 Commits

Reviewing files that changed from the base of the PR and between a43a8fe and 254e939.

📒 Files selected for processing (3)
  • docs/reference/llm.mdx
  • packages/leadtype/src/next/index.ts
  • packages/leadtype/src/next/next.test.ts
📜 Recent review details
🧰 Additional context used
📓 Path-based instructions (4)
**/*.{ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

**/*.{ts,tsx}: Use explicit types for function parameters and return values when they enhance clarity
Prefer unknown over any when the type is genuinely unknown
Use const assertions (as const) for immutable values and literal types
Leverage TypeScript's type narrowing instead of type assertions

Files:

  • packages/leadtype/src/next/next.test.ts
  • packages/leadtype/src/next/index.ts
**/*.{js,ts,jsx,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

**/*.{js,ts,jsx,tsx}: Use meaningful variable names instead of magic numbers - extract constants with descriptive names
Use arrow functions for callbacks and short functions
Prefer for...of loops over .forEach() and indexed for loops
Use optional chaining (?.) and nullish coalescing (??) for safer property access
Prefer template literals over string concatenation
Use destructuring for object and array assignments
Use const by default, let only when reassignment is needed, never var
Always await promises in async functions - don't forget to use the return value
Use async/await syntax instead of promise chains for better readability
Handle errors appropriately in async code with try-catch blocks
Don't use async functions as Promise executors
Remove console.log, debugger, and alert statements from production code
Throw Error objects with descriptive messages, not strings or other values
Use try-catch blocks meaningfully - don't catch errors just to rethrow them
Prefer early returns over nested conditionals for error cases
Extract complex conditions into well-named boolean variables
Use early returns to reduce nesting
Prefer simple conditionals over nested ternary operators
Don't use eval() or assign directly to document.cookie
Avoid spread syntax in accumulators within loops
Use top-level regex literals instead of creating them in loops
Prefer specific imports over namespace imports
Use descriptive names for functions, variables, and types for meaningful naming
Add comments for complex logic, but prefer self-documenting code

Files:

  • packages/leadtype/src/next/next.test.ts
  • packages/leadtype/src/next/index.ts
**/*.{test,spec}.{js,ts,jsx,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

**/*.{test,spec}.{js,ts,jsx,tsx}: Write assertions inside it() or test() blocks
Avoid done callbacks in async tests - use async/await instead
Don't use .only or .skip in committed code
Keep test suites reasonably flat - avoid excessive describe nesting

Files:

  • packages/leadtype/src/next/next.test.ts
**/index.{js,ts,jsx,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

Avoid barrel files (index files that re-export everything)

Files:

  • packages/leadtype/src/next/index.ts
🔇 Additional comments (11)
docs/reference/llm.mdx (1)

243-255: LGTM!

Also applies to: 315-320, 323-340, 366-378, 386-388

packages/leadtype/src/next/index.ts (4)

23-124: LGTM!


146-189: LGTM!


191-263: LGTM!


351-442: LGTM!

packages/leadtype/src/next/next.test.ts (6)

204-216: LGTM!


218-243: LGTM!


245-253: LGTM!


255-300: LGTM!


302-321: LGTM!


323-346: LGTM!


📝 Walkthrough

Summary by CodeRabbit

  • New Features

    • JSON-LD generation for docs pages with customization and safe stringification.
    • Next.js App Router metadata support for docs pages (route-aware metadata + static params).
  • Documentation

    • New "Deploy generated artifacts" guide with framework-specific deployment recipes.
    • Updated framework docs and agent-optimization guides with JSON-LD/metadata examples and cross-references.
    • Added docs config starting point for the new guide.
  • Tests

    • Expanded tests covering JSON-LD generation, stringification, and metadata behavior.

Walkthrough

Adds typed JSON-LD generation (createDocsJsonLd, stringifyJsonLd) with override/transform support, a Next.js App Router metadata factory (createGenerateMetadata), example page wiring that emits JSON-LD, tests, and deployment/framework documentation.

Changes

Metadata and JSON-LD integration

Layer / File(s) Summary
JSON-LD override type system and infrastructure
packages/leadtype/src/llm/readability.ts
JsonLdType and JSON-LD override/transform types; createDocsJsonLd and stringifyJsonLd; CreateDocsHeadConfig extended to accept jsonLd options and createDocsHead updated to conditionally include JSON-LD.
JSON-LD helper tests
packages/leadtype/src/llm/llm.test.ts
Tests createDocsJsonLd override behavior, unknown-path null returns, stringifyJsonLd escaping, and createDocsHead JSON-LD integration (breadcrumb removal support).
Next.js metadata generation with overrides
packages/leadtype/src/next/index.ts
Adds Next metadata types and createGenerateMetadata factory that resolves URL path from route params, looks up manifest pages, builds defaults, and applies ordered overrides (including OpenGraph cascading and optional transform).
Next.js metadata generation tests
packages/leadtype/src/next/next.test.ts
Tests manifest version validation, known/unknown slug behavior, function/value overrides, alternates/robots/siteName merging, and OpenGraph cascade/precedence.
Example Next.js page with metadata and JSON-LD
apps/next-example/app/docs/[[...slug]]/page.tsx
Wires manifest-driven generateStaticParams/generateMetadata; computes JSON-LD via createDocsJsonLd with publisher override from manifest product name and renders escaped inline JSON-LD script when present.
Framework-specific integration and deployment guides
docs/build/deploy-generated-artifacts.mdx, docs/build/framework-matrix.mdx, docs/build/optimize-docs-for-agents.mdx, docs/build/build-a-docs-site.mdx, docs/build/generate-static-artifacts.mdx, docs/docs.config.ts, docs/reference/llm.mdx
New deployment guide and framework recipes; docs updated to document createGenerateMetadata, createDocsJsonLd, and stringifyJsonLd usage and to add cross-references to the new deployment guidance.

Sequence Diagram(s)

sequenceDiagram
  participant Route as Next Route Handler
  participant Generator as createGenerateMetadata
  participant Manifest as Page Manifest
  participant JsonLd as createDocsJsonLd
  participant Head as Page Head / Response

  Route->>Generator: params + route context
  Generator->>Manifest: resolve urlPath from basePath + slug
  Manifest-->>Generator: page entry or not found
  alt page found
    Generator->>Generator: build defaults (title/description, alternates, openGraph)
    Generator->>Generator: apply overrides (title/description -> cascade to openGraph)
    Generator->>Head: return NextDocsMetadata (title, alternates, openGraph, etc.)
    Route->>JsonLd: provide page.urlPath + overrides
    JsonLd-->>Head: JsonLdValue (or null)
    Head->>Route: page with optional inline JSON-LD script
  else page not found
    Generator-->>Head: empty {} metadata
  end
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related PRs

  • inthhq/leadtype#51: Both PRs modify the Next adapter surface—specifically packages/leadtype/src/next/index.ts—so they are closely related.

Poem

🐰 I nibbled the manifest and found a trail of gold,
Json‑LD and metadata, tidy and bold.
Next pages now whisper their schema with pride,
Overrides and transforms hopping by my side —
Deploy the artifacts, watch docs unfold!

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 25.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately summarizes the main change: adding docs metadata helpers and deployment recipes, which aligns with the PR's core objectives of adding JSON-LD helpers, createGenerateMetadata, and deployment documentation.
Description check ✅ Passed The description is directly related to the changeset, detailing the addition of JSON-LD helpers, Next.js metadata support, dogfooding in the example app, and deployment documentation—all reflected in the file changes.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch KayleeWilliams/p3-issues

Warning

There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure.

🔧 ESLint

If the error stems from missing dependencies, add them to the package.json file. For unrecoverable errors (e.g., due to private dependencies), disable the tool in the CodeRabbit configuration.

ESLint skipped: no ESLint configuration detected in root package.json. To enable, add eslint to devDependencies.


Comment @coderabbitai help to get the list of available commands and usage tips.

@KayleeWilliams KayleeWilliams marked this pull request as ready for review May 16, 2026 02:10
Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@docs/build/deploy-generated-artifacts.mdx`:
- Line 201: The import for manifestJson uses a relative public path
("../../public/docs/agent-readability.json") which resolves incorrectly; update
the import statement that declares manifestJson to reference the project-root
public asset (use an absolute public path like "/docs/agent-readability.json")
so Astro will load the manifest from the public folder correctly.

In `@packages/leadtype/src/llm/readability.ts`:
- Around line 721-723: The page lookup in createDocsJsonLd uses a strict
equality on entry.urlPath === config.urlPath which misses variants with trailing
slashes or query/hash fragments; normalize both sides before comparing (e.g.,
strip trailing slash and remove query/hash) so config.manifest.pages.find
compares normalizedEntryUrl === normalizedConfigUrl; update the lookup around
config.manifest.pages and config.urlPath (and any variable named entry.urlPath)
to use the normalized values so the JSON-LD generation isn't skipped for
equivalent URLs.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: 166bbf04-4b26-4874-b6aa-0db339b39373

📥 Commits

Reviewing files that changed from the base of the PR and between aca9e8f and a43a8fe.

📒 Files selected for processing (12)
  • apps/next-example/app/docs/[[...slug]]/page.tsx
  • docs/build/build-a-docs-site.mdx
  • docs/build/deploy-generated-artifacts.mdx
  • docs/build/framework-matrix.mdx
  • docs/build/generate-static-artifacts.mdx
  • docs/build/optimize-docs-for-agents.mdx
  • docs/docs.config.ts
  • docs/reference/llm.mdx
  • packages/leadtype/src/llm/llm.test.ts
  • packages/leadtype/src/llm/readability.ts
  • packages/leadtype/src/next/index.ts
  • packages/leadtype/src/next/next.test.ts
📜 Review details
🧰 Additional context used
📓 Path-based instructions (6)
**/*.{ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

**/*.{ts,tsx}: Use explicit types for function parameters and return values when they enhance clarity
Prefer unknown over any when the type is genuinely unknown
Use const assertions (as const) for immutable values and literal types
Leverage TypeScript's type narrowing instead of type assertions

Files:

  • docs/docs.config.ts
  • packages/leadtype/src/next/next.test.ts
  • apps/next-example/app/docs/[[...slug]]/page.tsx
  • packages/leadtype/src/next/index.ts
  • packages/leadtype/src/llm/readability.ts
  • packages/leadtype/src/llm/llm.test.ts
**/*.{js,ts,jsx,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

**/*.{js,ts,jsx,tsx}: Use meaningful variable names instead of magic numbers - extract constants with descriptive names
Use arrow functions for callbacks and short functions
Prefer for...of loops over .forEach() and indexed for loops
Use optional chaining (?.) and nullish coalescing (??) for safer property access
Prefer template literals over string concatenation
Use destructuring for object and array assignments
Use const by default, let only when reassignment is needed, never var
Always await promises in async functions - don't forget to use the return value
Use async/await syntax instead of promise chains for better readability
Handle errors appropriately in async code with try-catch blocks
Don't use async functions as Promise executors
Remove console.log, debugger, and alert statements from production code
Throw Error objects with descriptive messages, not strings or other values
Use try-catch blocks meaningfully - don't catch errors just to rethrow them
Prefer early returns over nested conditionals for error cases
Extract complex conditions into well-named boolean variables
Use early returns to reduce nesting
Prefer simple conditionals over nested ternary operators
Don't use eval() or assign directly to document.cookie
Avoid spread syntax in accumulators within loops
Use top-level regex literals instead of creating them in loops
Prefer specific imports over namespace imports
Use descriptive names for functions, variables, and types for meaningful naming
Add comments for complex logic, but prefer self-documenting code

Files:

  • docs/docs.config.ts
  • packages/leadtype/src/next/next.test.ts
  • apps/next-example/app/docs/[[...slug]]/page.tsx
  • packages/leadtype/src/next/index.ts
  • packages/leadtype/src/llm/readability.ts
  • packages/leadtype/src/llm/llm.test.ts
**/*.{test,spec}.{js,ts,jsx,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

**/*.{test,spec}.{js,ts,jsx,tsx}: Write assertions inside it() or test() blocks
Avoid done callbacks in async tests - use async/await instead
Don't use .only or .skip in committed code
Keep test suites reasonably flat - avoid excessive describe nesting

Files:

  • packages/leadtype/src/next/next.test.ts
  • packages/leadtype/src/llm/llm.test.ts
**/*.{jsx,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

**/*.{jsx,tsx}: Use function components over class components in React
Call hooks at the top level only, never conditionally
Specify all dependencies in hook dependency arrays correctly
Use the key prop for elements in iterables (prefer unique IDs over array indices)
Nest children between opening and closing tags instead of passing as props
Don't define components inside other components
Avoid dangerouslySetInnerHTML unless absolutely necessary
Use proper image components (e.g., Next.js <Image>) over <img> tags
Use Next.js <Image> component for images
Use next/head or App Router metadata API for head elements in Next.js
Use Server Components for async data fetching instead of async Client Components in Next.js
Use ref as a prop instead of React.forwardRef in React 19+

Files:

  • apps/next-example/app/docs/[[...slug]]/page.tsx
**/*.{jsx,tsx,html}

📄 CodeRabbit inference engine (AGENTS.md)

**/*.{jsx,tsx,html}: Use semantic HTML and ARIA attributes for accessibility: provide meaningful alt text for images, use proper heading hierarchy, add labels for form inputs, include keyboard event handlers alongside mouse events, use semantic elements instead of divs with roles
Add rel="noopener" when using target="_blank" on links

Files:

  • apps/next-example/app/docs/[[...slug]]/page.tsx
**/index.{js,ts,jsx,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

Avoid barrel files (index files that re-export everything)

Files:

  • packages/leadtype/src/next/index.ts
🪛 LanguageTool
docs/reference/llm.mdx

[style] ~319-~319: Three successive sentences begin with the same word. Consider rewording the sentence or use a thesaurus to find a synonym.
Context: ... type="application/ld+json">contents. UsecreateDocsHead` when your framework ac...

(ENGLISH_WORD_REPEAT_BEGINNING_RULE)

🔇 Additional comments (11)
docs/reference/llm.mdx (1)

243-243: LGTM!

Also applies to: 255-255, 315-315, 317-317, 319-319, 323-327, 329-338, 340-340, 366-366, 368-378, 386-387

docs/build/framework-matrix.mdx (1)

36-37: LGTM!

Also applies to: 55-64

docs/build/optimize-docs-for-agents.mdx (1)

162-163: LGTM!

Also applies to: 166-180, 183-184

docs/build/build-a-docs-site.mdx (1)

59-59: LGTM!

docs/build/generate-static-artifacts.mdx (1)

14-15: LGTM!

docs/docs.config.ts (1)

21-21: LGTM!

packages/leadtype/src/llm/readability.ts (1)

56-57: LGTM!

Also applies to: 225-269, 276-277, 648-715, 724-745, 1101-1112

packages/leadtype/src/llm/llm.test.ts (1)

18-19: LGTM!

Also applies to: 32-33, 661-669, 679-721, 1130-1149

packages/leadtype/src/next/index.ts (1)

6-6: LGTM!

Also applies to: 10-10, 21-123, 144-254, 333-432

packages/leadtype/src/next/next.test.ts (1)

8-8: LGTM!

Also applies to: 202-333

apps/next-example/app/docs/[[...slug]]/page.tsx (1)

1-10: LGTM!

Also applies to: 16-21, 33-48

normalizeAgentReadabilityManifest,
stringifyJsonLd,
} from "leadtype/llm/readability";
import manifestJson from "../../public/docs/agent-readability.json";
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Fix Astro manifest import path in the snippet.

Line 201 points to ../../public/..., which resolves to src/public/... from src/pages/docs/[...slug].astro. For a standard Astro app, this should point to project-root public.

Suggested doc fix
-import manifestJson from "../../public/docs/agent-readability.json";
+import manifestJson from "../../../public/docs/agent-readability.json";
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
import manifestJson from "../../public/docs/agent-readability.json";
import manifestJson from "../../../public/docs/agent-readability.json";
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@docs/build/deploy-generated-artifacts.mdx` at line 201, The import for
manifestJson uses a relative public path
("../../public/docs/agent-readability.json") which resolves incorrectly; update
the import statement that declares manifestJson to reference the project-root
public asset (use an absolute public path like "/docs/agent-readability.json")
so Astro will load the manifest from the public folder correctly.

Comment on lines +721 to +723
const page = config.manifest.pages.find(
(entry) => entry.urlPath === config.urlPath
);
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Normalize urlPath before page lookup in createDocsJsonLd.

The lookup is strict (entry.urlPath === config.urlPath), so valid variants like trailing slash or query/hash forms can return null and silently skip JSON-LD generation.

Suggested fix
 export function createDocsJsonLd(
   config: CreateDocsJsonLdConfig
 ): JsonLdValue | null {
   assertManifestVersion(config.manifest);
+  const normalizedUrlPath =
+    normalizeUrlPath(config.urlPath).replace(TRAILING_SLASH_PATTERN, "") || "/";
   const page = config.manifest.pages.find(
-    (entry) => entry.urlPath === config.urlPath
+    (entry) => entry.urlPath === normalizedUrlPath
   );
   if (!page) {
     return null;
   }
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/leadtype/src/llm/readability.ts` around lines 721 - 723, The page
lookup in createDocsJsonLd uses a strict equality on entry.urlPath ===
config.urlPath which misses variants with trailing slashes or query/hash
fragments; normalize both sides before comparing (e.g., strip trailing slash and
remove query/hash) so config.manifest.pages.find compares normalizedEntryUrl ===
normalizedConfigUrl; update the lookup around config.manifest.pages and
config.urlPath (and any variable named entry.urlPath) to use the normalized
values so the JSON-LD generation isn't skipped for equivalent URLs.

Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: a43a8fe2b3

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines +351 to +353
const page = config.manifest.pages.find(
(entry) => entry.urlPath === urlPath
);
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Validate manifest version before generating metadata

When createGenerateMetadata is called with a stale or future agent-readability.json, this new path reads config.manifest.pages without the manifest-version assertion used by the other runtime helpers such as createDocsJsonLd/createDocsHead. In that scenario the helper silently emits canonical and OpenGraph metadata from an incompatible manifest instead of failing loudly, so add the same version check before looking up pages.

Useful? React with 👍 / 👎.

Copy link
Copy Markdown

@pullfrog pullfrog Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No new issues found.

TL;DR — Adds framework-neutral JSON-LD helpers (createDocsJsonLd / stringifyJsonLd) with override and transform hooks, a Next App Router createGenerateMetadata helper that cascades title/description into OpenGraph, and host-specific deployment recipes that are wired into the docs nav and dogfooded in the Next example.

Key changes

  • JSON-LD helpers with overridescreateDocsJsonLd returns a Schema.org TechArticle object enriched with name, mainEntityOfPage, conditional inLanguage, and an isPartOf WebSite. stringifyJsonLd escapes <, >, &, U+2028, and U+2029 for safe <script type="application/ld+json"> contents.
  • Next App Router createGenerateMetadata — Produces a generateMetadata function with default title, description, OpenGraph, and text/markdown canonical alternate. Title and description cascade into OpenGraph defaults unless an explicit OpenGraph override wins. Includes escape-hatch metadata and transform config.
  • Deployment recipes — New docs/build/deploy-generated-artifacts.mdx covering Next on Vercel, Nuxt, SvelteKit, Astro, Cloudflare Workers and Pages, and plain Vite hosting, plus the output-contract table. Cross-linked from framework-matrix, build-a-docs-site, and generate-static-artifacts.
  • createDocsHead integration — Now accepts a jsonLd config that passes through to createDocsJsonLd and omits the JSON-LD meta entry when no page matches.
  • Next example dogfoodapps/next-example/app/docs/[[...slug]]/page.tsx imports the agent-readability manifest, wires generateMetadata, and renders route-scoped JSON-LD with stringifyJsonLd.

Summary | 12 files | 2 commits | base: mainKayleeWilliams/p3-issues


Framework-neutral JSON-LD helpers

Before: renderJsonLd and renderJsonLdScript produced a fixed TechArticle object with no override surface, and a missing-page caller had to guard manually.
After: createDocsJsonLd({ urlPath, manifest, overrides, transform }) returns JsonLdValue | null, with a function-or-object overrides shape; defaults gain name, mainEntityOfPage, isPartOf, and inLanguage when the page has a locale.

The breadcrumb: false sentinel removes the generated breadcrumb cleanly; any other field is replaced when overridden. stringifyJsonLd is exported separately so framework-typed metadata APIs and <script> consumers share the same escape path.

packages/leadtype/src/llm/readability.ts · packages/leadtype/src/llm/llm.test.ts · docs/reference/llm.mdx


Next App Router metadata helper

Before: App Router pages had to wire up canonical, OpenGraph, and text/markdown alternate metadata by hand against the manifest.
After: createGenerateMetadata({ manifest }) returns a typed generateMetadata that resolves the manifest entry from the route slug and emits title, description, alternates, and OpenGraph defaults, with cascade rules from title/description into OpenGraph.

How does the cascade behave? A `title` override updates both `metadata.title` and `metadata.openGraph.title`, and likewise for `description`. An explicit `openGraph` override (object or callback) wins on whichever fields it sets, but unset fields keep the cascaded values. The catch-all `metadata` override merges last, and `transform` runs after every other layer.

packages/leadtype/src/next/index.ts · packages/leadtype/src/next/next.test.ts · apps/next-example/app/docs/[[...slug]]/page.tsx


Deployment recipes for generated artifacts

Before: framework-matrix covered command shapes but not host-specific paths for serving llms.txt, markdown mirrors, search JSON, manifest, sitemap, and robots.
After: A dedicated guide spells out static vs. runtime responsibilities per host and gives copy-paste page snippets for Next, Nuxt, SvelteKit, Astro, Cloudflare, and plain Vite.

The output-contract table at the top doubles as a checklist for what leadtype generate writes and which paths the runtime must serve.

docs/build/deploy-generated-artifacts.mdx · docs/build/framework-matrix.mdx · docs/build/build-a-docs-site.mdx · docs/docs.config.ts

Pullfrog  | View workflow run | Using Claude Opus𝕏

Copy link
Copy Markdown

@pullfrog pullfrog Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No new issues. Reviewed the following changes:

  • Added a SUPPORTED_MANIFEST_VERSION guard to createGenerateMetadata, mirroring the existing assertManifestVersion pattern in readability.ts so stale manifests fail loudly with a regenerate-the-manifest message.
  • Covered the unsupported-version path with a next.test.ts case that asserts the thrown message.
  • Tweaked the createDocsJsonLd / stringifyJsonLd / createDocsHead lead-in paragraph in docs/reference/llm.mdx to vary sentence openings.

Pullfrog  | View workflow run | Using Claude Opus𝕏

@KayleeWilliams KayleeWilliams merged commit f178a7b into main May 16, 2026
3 checks passed
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