Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
577bbec
Remove clean markdown generation and artifacts.
jottakka Feb 27, 2026
c0be9ee
Remove clean markdown generation and related artifacts.
jottakka Mar 2, 2026
295befb
refactor: replace markdownToHtml+addHTMLFile with addCustomRecord in …
jottakka Mar 2, 2026
b78df10
chore: update lockfile after removing remark/rehype deps
jottakka Mar 2, 2026
492ef4a
fix: restore addHTMLFile for structured search results
jottakka Mar 2, 2026
4df8428
chore: disable llmstxt workflow on PRs (fix in next PR)
jottakka Mar 2, 2026
66cb470
Merge main into cleanup/remove-clean-markdown
jottakka Mar 2, 2026
9fe2c4f
feat: clean MDX in markdown API route, fix copy buttons, re-enable ll…
jottakka Mar 2, 2026
306f8e0
🤖 Regenerate LLMs.txt
github-actions[bot] Mar 2, 2026
6d64099
fix: remove cleanMdxToMarkdown — Cloudflare handles MDX conversion
jottakka Mar 2, 2026
e264848
fix: update stale git SHA in llms.txt
jottakka Mar 2, 2026
d203d34
chore: force llms.txt full regeneration
jottakka Mar 2, 2026
490b4fe
🤖 Regenerate LLMs.txt
github-actions[bot] Mar 2, 2026
fb23a34
refactor: remove /api/markdown route and middleware content negotiation
jottakka Mar 2, 2026
1c81482
fix: restore Algolia search component from main (lost in merge)
jottakka Mar 2, 2026
7ee60c7
refactor: remove dead toolkit markdown generation pipeline
jottakka Mar 2, 2026
cd65017
Merge remote-tracking branch 'origin/main' into cleanup/remove-clean-…
jottakka Mar 2, 2026
ffcf096
fix: remove custom copy button from toolkit pages, use default Nextra…
jottakka Mar 2, 2026
166187e
Merge origin/main into sdserranog/check-markdown-accept
sdserranog Mar 4, 2026
f9581c4
🤖 Regenerate LLMs.txt
github-actions[bot] Mar 4, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
90 changes: 0 additions & 90 deletions .github/workflows/generate-markdown.yml

This file was deleted.

49 changes: 2 additions & 47 deletions .github/workflows/llmstxt.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,22 +2,15 @@ name: Generate LLMs.txt

on:
workflow_dispatch:
pull_request:
Comment thread
jottakka marked this conversation as resolved.
types: [opened, synchronize, reopened]

permissions:
contents: write
pull-requests: write
contents: read

jobs:
llmstxt:
name: Generate LLMSTXT
runs-on: ubuntu-latest

permissions:
contents: write
pull-requests: write

steps:
- name: Use Node.js
uses: actions/setup-node@v4
Expand All @@ -27,7 +20,7 @@ jobs:
- name: Checkout code
uses: actions/checkout@v4
with:
ref: ${{ github.event.pull_request.head.ref || github.ref }}
ref: ${{ github.ref }}
token: ${{ secrets.DOCS_PUBLISHABLE_GH_TOKEN }}

- name: Install dependencies
Expand All @@ -40,41 +33,3 @@ jobs:
run: pnpm llmstxt
env:
OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }}

- name: Check for changes
id: check-changes
run: |
if [ -n "$(git status --porcelain)" ]; then
echo "has_changes=true" >> $GITHUB_OUTPUT
else
echo "has_changes=false" >> $GITHUB_OUTPUT
fi
Comment thread
jottakka marked this conversation as resolved.

- name: Commit changes to PR
if: steps.check-changes.outputs.has_changes == 'true' && github.event_name == 'pull_request'
run: |
git config user.name "github-actions[bot]"
git config user.email "github-actions[bot]@users.noreply.github.com"
git add public/llms.txt
git commit -m "🤖 Regenerate LLMs.txt"
git push

- name: Create Pull Request (for scheduled/manual runs)
if: steps.check-changes.outputs.has_changes == 'true' && github.event_name != 'pull_request'
id: cpr
uses: peter-evans/create-pull-request@v7
with:
token: ${{ secrets.DOCS_PUBLISHABLE_GH_TOKEN }}
commit-message: Regenerate LLMs.txt and related files
branch: auto-update-llms-txt
delete-branch: true
title: "🤖 Regenerate LLMs.txt"
reviewers: >
evantahler
torresmateo

- name: Enable Pull Request Automerge
if: steps.check-changes.outputs.has_changes == 'true' && github.event_name != 'pull_request'
run: gh pr merge --squash --auto ${{ steps.cpr.outputs.pull-request-number }}
env:
GH_TOKEN: ${{ secrets.DOCS_PUBLISHABLE_GH_TOKEN }}
3 changes: 2 additions & 1 deletion CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ pnpm vale:check # Check docs against style rules
```

Run a single test:

```bash
pnpm vitest run tests/broken-link-check.test.ts
```
Expand All @@ -26,7 +27,7 @@ pnpm vitest run tests/broken-link-check.test.ts
- **`app/_lib/`** — Data-fetching utilities (toolkit catalog, slug generation, static params).
- **`app/api/`** — API routes (markdown export, toolkit-data, glossary).
- **`toolkit-docs-generator/`** — Generates MCP toolkit documentation from server metadata JSON files in `toolkit-docs-generator/data/toolkits/`.
- **`scripts/`** — Build/CI scripts (clean markdown export, Vale style fixes, redirect checking, pagefind indexing, i18n sync).
- **`scripts/`** — Build/CI scripts (Vale style fixes, redirect checking, pagefind indexing, i18n sync).
- **`tests/`** — Vitest tests (broken links, internal link validation, sitemap, smoke tests).
- **`lib/`** — Next.js utilities (glossary remark plugin, llmstxt plugin).
- **`next.config.ts`** — Contains ~138 redirect rules.
Expand Down
4 changes: 2 additions & 2 deletions app/_components/copy-page-override.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,14 +10,14 @@ const DROPDOWN_IDENTIFIER = "Markdown for LLMs";

/**
* This component overrides the default nextra-theme-docs "Copy page" button behavior
* to fetch clean markdown from our API instead of copying raw MDX source.
* to fetch markdown from our API instead of copying raw MDX source.
*/
export function CopyPageOverride() {
const pathname = usePathname();

const fetchAndCopyMarkdown = useCallback(async (): Promise<boolean> => {
try {
const markdownUrl = `/api/markdown${pathname}.md`;
const markdownUrl = `/api/markdown${pathname}`;
Comment thread
jottakka marked this conversation as resolved.
Outdated
const response = await fetch(markdownUrl);

if (!response.ok) {
Expand Down
2 changes: 1 addition & 1 deletion app/_components/toolkit-docs/components/page-actions.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ function CopyPageButton() {

setLoading(true);
try {
const response = await fetch(`/api/markdown${pathname}.md`);
const response = await fetch(`/api/markdown${pathname}`);
Comment thread
jottakka marked this conversation as resolved.
Outdated
if (!response.ok) {
throw new Error("Failed to fetch markdown");
}
Expand Down
44 changes: 1 addition & 43 deletions app/api/markdown/[[...slug]]/route.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,6 @@ const MD_EXTENSION_REGEX = /\.md$/;
const TOOLKIT_MARKDOWN_ROOT = join(process.cwd(), "public", "toolkit-markdown");
const APP_ROOT = join(process.cwd(), "app");

// Directory containing pre-generated clean markdown files
const CLEAN_MARKDOWN_DIR = join(process.cwd(), "public", "_markdown");

/**
* Validates that a resolved path is within the allowed directory.
* Prevents path traversal attacks (e.g., ../../../etc/passwd).
Expand Down Expand Up @@ -108,39 +105,6 @@ type ToolkitMarkdownTarget = {
toolkitId: string;
};

/**
* Try to serve clean pre-generated markdown.
* Returns NextResponse if found, null otherwise.
*/
async function tryServeCleanMarkdown(
request: NextRequest,
sanitizedPath: string
): Promise<NextResponse | null> {
const cleanMarkdownPath = join(CLEAN_MARKDOWN_DIR, `${sanitizedPath}.md`);

try {
await access(cleanMarkdownPath);
if (!isPathWithinDirectory(cleanMarkdownPath, CLEAN_MARKDOWN_DIR)) {
return null;
}

const content = await readFile(cleanMarkdownPath, "utf-8");
await trackMarkdownRequest(request, sanitizedPath);

return new NextResponse(content, {
status: 200,
headers: {
"Content-Type": "text/markdown; charset=utf-8",
"Content-Disposition": "inline",
"Cache-Control": "public, max-age=3600",
Vary: "Accept, User-Agent",
},
});
} catch {
return null;
}
}

/**
* Check if a path matches the toolkit documentation pattern.
* Handles both actual toolkit IDs and the [toolkitId] dynamic route pattern.
Expand Down Expand Up @@ -248,13 +212,7 @@ export async function GET(
filePath = join(APP_ROOT, `${sanitizedPath}/page.mdx`);
}
} else {
// Try clean markdown first (preferred)
const cleanResponse = await tryServeCleanMarkdown(request, sanitizedPath);
if (cleanResponse) {
return cleanResponse;
}

// Fallback: raw MDX file
// Serve raw MDX file.
filePath = join(APP_ROOT, `${sanitizedPath}/page.mdx`);
}

Expand Down
2 changes: 1 addition & 1 deletion app/en/get-started/setup/connect-arcade-docs/page.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ description: "Learn how to speed up your development with agents in your IDEs"

# Agentic Development

Every page on the Arcade docs site renders as clean markdown. When an AI agent or coding assistant visits any docs URL, the site automatically returns `Content-Type: text/markdown` instead of HTML if:
Every page on the Arcade docs site can be served as markdown. When an AI agent or coding assistant visits any docs URL, the site automatically returns `Content-Type: text/markdown` instead of HTML if:
Comment thread
jottakka marked this conversation as resolved.
Outdated

- The request `User-Agent` header matches a known AI agent (Claude, ChatGPT, Cursor, etc.)
- The request includes the `Accept: text/markdown` header
Expand Down
19 changes: 11 additions & 8 deletions app/layout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -22,15 +22,16 @@ import {
} from "nextra-theme-docs";

const REGEX_LOCALE = /^\/([a-z]{2}(?:-[A-Z]{2})?)(?:\/|$)/;
const ENABLE_MARKDOWN_ALTERNATE = false;

function getMarkdownAlternatePath(pathname: string): string {
// Handle root paths
if (pathname === "/" || pathname === "") {
return "/index.md";
return "/";
}
// Remove trailing slash if present, then add .md extension
// Remove trailing slash if present.
const cleanPath = pathname.endsWith("/") ? pathname.slice(0, -1) : pathname;
return `${cleanPath}.md`;
return cleanPath;
}

export async function generateMetadata() {
Expand Down Expand Up @@ -77,11 +78,13 @@ export async function generateMetadata() {
appleWebApp: {
title: "Arcade Documentation",
},
alternates: {
types: {
"text/markdown": getMarkdownAlternatePath(pathname),
},
},
alternates: ENABLE_MARKDOWN_ALTERNATE
? {
types: {
"text/markdown": getMarkdownAlternatePath(pathname),
},
}
: undefined,
Comment thread
jottakka marked this conversation as resolved.
Outdated
other: {
"apple-mobile-web-app-title": "Arcade Documentation",
"twitter:url": "https://docs.arcade.dev",
Expand Down
8 changes: 4 additions & 4 deletions middleware.ts
Original file line number Diff line number Diff line change
Expand Up @@ -101,15 +101,15 @@ function getLocaleFromPathname(pathname: string, request: NextRequest): string {

function buildMarkdownPath(pathname: string, locale: string): string {
Comment thread
jottakka marked this conversation as resolved.
Outdated
if (pathname === "/" || pathname === "") {
return `/${locale}/home.md`;
return `/${locale}/home`;
}
if (pathnameIsMissingLocale(pathname)) {
return `/${locale}${pathname}.md`;
return `/${locale}${pathname}`;
}
if (SUPPORTED_LOCALES.some((loc) => pathname === `/${loc}`)) {
return `${pathname}/home.md`;
return `${pathname}/home`;
}
return `${pathname}.md`;
return pathname;
}

function isToolkitDetailPath(pathname: string): boolean {
Expand Down
3 changes: 1 addition & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,7 @@
"format": "pnpm exec ultracite fix",
"prepare": "husky install",
"toolkit-markdown": "pnpm dlx tsx toolkit-docs-generator/scripts/generate-toolkit-markdown.ts",
"postbuild": "if [ \"$SKIP_POSTBUILD\" != \"true\" ]; then pnpm run generate:markdown && pnpm run custompagefind; fi",
"generate:markdown": "pnpm dlx tsx scripts/generate-clean-markdown.ts",
"postbuild": "if [ \"$SKIP_POSTBUILD\" != \"true\" ]; then pnpm run custompagefind; fi",
Comment thread
cursor[bot] marked this conversation as resolved.
Outdated
"translate": "pnpm dlx tsx scripts/i18n-sync/index.ts && pnpm format",
"llmstxt": "pnpm dlx tsx scripts/generate-llmstxt.ts",
"custompagefind": "pnpm dlx tsx scripts/pagefind.ts",
Expand Down
Loading