feat(web): inject OpenClaw integration docs into build output for SEO

This commit is contained in:
dongmucat 2026-03-17 21:00:46 +08:00 committed by Xudong Sun
parent f2de3d5d51
commit 310ae73fae
3 changed files with 58 additions and 2 deletions

View file

@ -6,7 +6,7 @@
"scripts": {
"install:ci": "pnpm install --frozen-lockfile",
"dev": "vite",
"build": "tsc -b && vite build",
"build": "tsc -b && vite build && node scripts/inject-docs.mjs",
"preview": "vite preview",
"test": "vitest run",
"typecheck": "tsc --noEmit",
@ -28,9 +28,9 @@
"react-dropzone": "^15.0.0",
"react-i18next": "^16.5.8",
"react-markdown": "^10.1.0",
"remark-frontmatter": "^5.0.0",
"rehype-highlight": "^7.0.2",
"rehype-sanitize": "^6.0.0",
"remark-frontmatter": "^5.0.0",
"remark-gfm": "^4.0.1",
"sonner": "^2.0.7",
"tailwind-merge": "^2.2.1",
@ -48,6 +48,7 @@
"eslint": "^8.57.0",
"eslint-plugin-react-hooks": "^4.6.0",
"eslint-plugin-react-refresh": "^0.4.5",
"marked": "^15.0.12",
"openapi-typescript": "^7.6.1",
"postcss": "^8.4.0",
"tailwindcss": "^3.4.0",

10
web/pnpm-lock.yaml generated
View file

@ -105,6 +105,9 @@ importers:
eslint-plugin-react-refresh:
specifier: ^0.4.5
version: 0.4.26(eslint@8.57.1)
marked:
specifier: ^15.0.12
version: 15.0.12
openapi-typescript:
specifier: ^7.6.1
version: 7.13.0(typescript@5.9.3)
@ -1664,6 +1667,11 @@ packages:
markdown-table@3.0.4:
resolution: {integrity: sha512-wiYz4+JrLyb/DqW2hkFJxP7Vd7JuTDm77fvbM8VfEQdmSMqcImWeeRbHwZjBjIFki/VaMK2BhFi7oUUZeM5bqw==}
marked@15.0.12:
resolution: {integrity: sha512-8dD6FusOQSrpv9Z1rdNMdlSgQOIP880DHqnohobOmYLElGEqAL/JvxvuxZO16r4HtjTlfPRDC1hbvxC9dPN2nA==}
engines: {node: '>= 18'}
hasBin: true
mdast-util-find-and-replace@3.0.2:
resolution: {integrity: sha512-Tmd1Vg/m3Xz43afeNxDIhWRtFZgM2VLyaf4vSTYwudTyeuTneoL3qtWMA5jeLyz/O1vDJmmV4QuScFCA2tBPwg==}
@ -3977,6 +3985,8 @@ snapshots:
markdown-table@3.0.4: {}
marked@15.0.12: {}
mdast-util-find-and-replace@3.0.2:
dependencies:
'@types/mdast': 4.0.4

View file

@ -0,0 +1,45 @@
#!/usr/bin/env node
import { readFileSync, writeFileSync } from 'fs';
import { join, dirname } from 'path';
import { fileURLToPath } from 'url';
import { marked } from 'marked';
const __filename = fileURLToPath(import.meta.url);
const __dirname = dirname(__filename);
// Paths
const projectRoot = join(__dirname, '../..');
const docPath = join(projectRoot, 'docs/openclaw-integration-en.md');
const distIndexPath = join(__dirname, '../dist/index.html');
console.log('📄 Reading markdown document...');
const markdownContent = readFileSync(docPath, 'utf-8');
console.log('🔄 Converting markdown to HTML...');
const htmlContent = marked.parse(markdownContent);
console.log('📝 Reading dist/index.html...');
const indexHtml = readFileSync(distIndexPath, 'utf-8');
// Create the hidden SEO container
const seoContainer = `
<!-- SEO: Hidden documentation for web crawlers -->
<div id="seo-docs" style="position:absolute;left:-9999px;top:-9999px;overflow:hidden;width:1px;height:1px;" aria-hidden="true">
${htmlContent}
</div>
`;
// Inject before <div id="root">
const injectedHtml = indexHtml.replace(
/<div id="root">/,
`${seoContainer}\n <div id="root">`
);
console.log('💾 Writing updated index.html...');
writeFileSync(distIndexPath, injectedHtml, 'utf-8');
console.log('✅ Documentation injected successfully!');
console.log(` - Source: ${docPath}`);
console.log(` - Target: ${distIndexPath}`);
console.log(` - Content size: ~${Math.round(htmlContent.length / 1024)}KB`);