Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
be46594
fix
udhaykumarbala Sep 23, 2025
9bb7b89
Merge branch '0gfoundation:main' into main
udhaykumarbala Sep 23, 2025
d85755a
Merge branch '0gfoundation:main' into main
udhaykumarbala Sep 24, 2025
29f28f5
Merge branch '0gfoundation:main' into main
udhaykumarbala Sep 30, 2025
e78db5f
Merge branch '0gfoundation:main' into main
udhaykumarbala Oct 7, 2025
b2be9ad
Merge branch '0gfoundation:main' into main
udhaykumarbala Oct 9, 2025
03cb5bc
Merge branch '0gfoundation:main' into main
udhaykumarbala Oct 11, 2025
c29d60a
Merge branch '0gfoundation:main' into main
udhaykumarbala Oct 13, 2025
0cbea16
Merge branch '0gfoundation:main' into main
udhaykumarbala Oct 16, 2025
b956125
Merge branch '0gfoundation:main' into main
udhaykumarbala Oct 16, 2025
84c5399
Merge branch '0gfoundation:main' into main
udhaykumarbala Oct 21, 2025
dc5c9ea
Merge branch '0gfoundation:main' into main
udhaykumarbala Oct 21, 2025
5939e4c
Merge branch '0gfoundation:main' into main
udhaykumarbala Oct 27, 2025
f45fe29
Merge branch '0gfoundation:main' into main
udhaykumarbala Nov 10, 2025
94ac4ad
Merge branch '0gfoundation:main' into main
udhaykumarbala Nov 19, 2025
29e60e8
Merge branch '0gfoundation:main' into main
udhaykumarbala Nov 28, 2025
b1671f5
Merge branch '0gfoundation:main' into main
udhaykumarbala Dec 4, 2025
1d39ded
Merge branch '0gfoundation:main' into main
udhaykumarbala Dec 8, 2025
2c5cfc7
Merge branch '0gfoundation:main' into main
udhaykumarbala Dec 8, 2025
3398bf9
Merge branch '0gfoundation:main' into main
udhaykumarbala Dec 16, 2025
0ee810e
Merge branch '0gfoundation:main' into main
udhaykumarbala Dec 16, 2025
b4f7df9
Merge branch '0gfoundation:main' into main
udhaykumarbala Dec 18, 2025
3730ccb
Merge branch '0gfoundation:main' into main
udhaykumarbala Jan 10, 2026
b30984a
token price update
udhaykumarbala Jan 10, 2026
bd3006f
Revert "token price update"
udhaykumarbala Jan 10, 2026
56672ad
Merge branch '0gfoundation:main' into main
udhaykumarbala Feb 5, 2026
c3108e6
Merge branch '0gfoundation:main' into main
udhaykumarbala Feb 5, 2026
9d41244
Merge branch '0gfoundation:main' into main
udhaykumarbala Feb 18, 2026
fd97a75
feat: add LLM-friendly documentation endpoints
udhaykumarbala Feb 18, 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
17 changes: 17 additions & 0 deletions docusaurus.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,23 @@ const config: Config = {
],
// Add security headers plugin
require.resolve('./src/plugins/security-headers-plugin'),
// Enable LLM-compatible markdown endpoints (e.g., /page.md returns raw markdown)
// See: https://github.com/0gfoundation/0g-doc/issues/242
require.resolve('./src/plugins/markdown-endpoint-plugin'),
// Generate llms.txt and llms-full.txt for AI tools (industry standard)
// See: https://llmstxt.org/
[
'docusaurus-plugin-llms',
{
generateLLMsTxt: true,
generateLLMsFullTxt: true,
docsDir: 'docs',
title: '0G Documentation',
description: '0G is a decentralized AI operating system (deAIOS) providing modular infrastructure for AI applications including decentralized storage, data availability, and GPU compute marketplace.',
llmsTxtFilename: 'llms.txt',
llmsFullTxtFilename: 'llms-full.txt',
},
],
],

headTags: [
Expand Down
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
"@mdx-js/react": "^3.0.0",
"clsx": "^2.0.0",
"crypto-js": "^4.2.0",
"docusaurus-plugin-llms": "^0.3.0",
"gsap": "^3.12.5",
"hast-util-is-element": "1.1.0",
"lottie-web": "^5.12.2",
Expand Down Expand Up @@ -53,4 +54,4 @@
"engines": {
"node": ">=20.11.0"
}
}
}
38 changes: 38 additions & 0 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

124 changes: 124 additions & 0 deletions src/plugins/markdown-endpoint-plugin.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,124 @@
/**
* Markdown Endpoint Plugin for Docusaurus
*
* Enables LLM-compatible endpoints by serving raw markdown files at .md URLs.
* For example: docs.0g.ai/concepts/compute.md returns raw markdown content.
*
* This allows AI tools and LLMs to programmatically ingest documentation
* without needing to parse HTML.
*
* @see https://github.com/0gfoundation/0g-doc/issues/242
*/

const fs = require('fs');
const path = require('path');

module.exports = function markdownEndpointPlugin(context, options) {
return {
name: 'markdown-endpoint-plugin',

async postBuild({ siteConfig, routesPaths, outDir }) {
const docsDir = path.join(context.siteDir, 'docs');

console.log('\n[markdown-endpoint] Starting markdown file copy...\n');

let copiedCount = 0;
let skippedCount = 0;
let errorCount = 0;

/**
* Recursively copy markdown files from source to destination
* @param {string} srcDir - Source directory
* @param {string} destDir - Destination directory
* @param {string} relativePath - Current relative path for logging
*/
function copyMarkdownFiles(srcDir, destDir, relativePath = '') {
if (!fs.existsSync(srcDir)) {
console.warn(`[markdown-endpoint] Source directory not found: ${srcDir}`);
return;
}

if (!fs.existsSync(destDir)) {
fs.mkdirSync(destDir, { recursive: true });
}

const items = fs.readdirSync(srcDir);

for (const item of items) {
const srcPath = path.join(srcDir, item);
const destPath = path.join(destDir, item);
const currentRelativePath = relativePath ? path.join(relativePath, item) : item;
const stat = fs.statSync(srcPath);

if (stat.isDirectory()) {
// Skip hidden directories and node_modules
if (item.startsWith('.') || item === 'node_modules') {
continue;
}
copyMarkdownFiles(srcPath, destPath, currentRelativePath);
} else if (item.endsWith('.md') || item.endsWith('.mdx')) {
try {
if (fs.existsSync(destPath)) {
const srcStat = fs.statSync(srcPath);
const destStat = fs.statSync(destPath);

if (srcStat.mtime > destStat.mtime) {
fs.copyFileSync(srcPath, destPath);
copiedCount++;
} else {
skippedCount++;
}
} else {
fs.copyFileSync(srcPath, destPath);
copiedCount++;
}
} catch (error) {
console.error(`[markdown-endpoint] Error copying ${currentRelativePath}:`, error.message);
errorCount++;
}
}
}
}

copyMarkdownFiles(docsDir, outDir);

console.log('[markdown-endpoint] Summary:');
console.log(` Copied: ${copiedCount} files`);
console.log(` Skipped: ${skippedCount} files (up-to-date)`);
console.log(` Errors: ${errorCount} files`);
console.log('[markdown-endpoint] Markdown files ready for LLM access!\n');
},

// Serve raw markdown in development
configureWebpack(config, isServer, utils) {
return {
devServer: {
setupMiddlewares: (middlewares, devServer) => {
devServer.app.get('*.md', (req, res, next) => {
const docsDir = path.join(context.siteDir, 'docs');
const requestedPath = req.path.replace(/^\//, '');
const filePath = path.join(docsDir, requestedPath);

if (fs.existsSync(filePath)) {
res.setHeader('Content-Type', 'text/markdown; charset=utf-8');
res.setHeader('Access-Control-Allow-Origin', '*');
res.sendFile(filePath);
} else {
// Try .mdx if .md not found
const mdxPath = filePath.replace('.md', '.mdx');
if (fs.existsSync(mdxPath)) {
res.setHeader('Content-Type', 'text/markdown; charset=utf-8');
res.setHeader('Access-Control-Allow-Origin', '*');
res.sendFile(mdxPath);
} else {
next();
}
}
});
return middlewares;
},
},
};
},
};
};
45 changes: 45 additions & 0 deletions vercel.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
{
"$schema": "https://openapi.vercel.sh/vercel.json",
"headers": [
{
"source": "/llms.txt",
"headers": [
{ "key": "Content-Type", "value": "text/plain; charset=utf-8" },
{ "key": "Access-Control-Allow-Origin", "value": "*" },
{ "key": "Access-Control-Allow-Methods", "value": "GET, OPTIONS" },
{ "key": "Cache-Control", "value": "public, max-age=3600" },
{ "key": "X-Content-Type-Options", "value": "nosniff" }
]
},
{
"source": "/llms-full.txt",
"headers": [
{ "key": "Content-Type", "value": "text/plain; charset=utf-8" },
{ "key": "Access-Control-Allow-Origin", "value": "*" },
{ "key": "Access-Control-Allow-Methods", "value": "GET, OPTIONS" },
{ "key": "Cache-Control", "value": "public, max-age=3600" },
{ "key": "X-Content-Type-Options", "value": "nosniff" }
]
},
{
"source": "/(.*).md",
"headers": [
{ "key": "Content-Type", "value": "text/markdown; charset=utf-8" },
{ "key": "Access-Control-Allow-Origin", "value": "*" },
{ "key": "Access-Control-Allow-Methods", "value": "GET, OPTIONS" },
{ "key": "Cache-Control", "value": "public, max-age=3600" },
{ "key": "X-Content-Type-Options", "value": "nosniff" }
]
},
{
"source": "/(.*).mdx",
"headers": [
{ "key": "Content-Type", "value": "text/markdown; charset=utf-8" },
{ "key": "Access-Control-Allow-Origin", "value": "*" },
{ "key": "Access-Control-Allow-Methods", "value": "GET, OPTIONS" },
{ "key": "Cache-Control", "value": "public, max-age=3600" },
{ "key": "X-Content-Type-Options", "value": "nosniff" }
]
}
]
}