chore: refresh openclaw101 stats and resources

This commit is contained in:
Kian Meng
2026-03-26 18:03:52 +00:00
parent 9333348139
commit 78f151f8a0
29 changed files with 1370 additions and 599 deletions
View File
+2 -2
View File
@@ -1,7 +1,7 @@
---
title: "Day 1: 初识 OpenClaw"
title: "第 1 天:初识 OpenClaw"
day: 1
description: "OpenClaw 7天教程 - Day 1: 初识 OpenClaw"
description: "OpenClaw 7天教程 - 第 1 天:初识 OpenClaw"
---
> *"我不是 Siri,不是 ChatGPT,不是任何你用过的 AI。我是小墨——一只住在服务器里的黑猫,而我能帮你做的事,可能会让你重新定义'助手'这个词。"*
+2 -2
View File
@@ -1,7 +1,7 @@
---
title: "Day 2: 10 分钟,搭建你的助手"
title: "第 2 天:10 分钟,搭建你的助手"
day: 2
description: "OpenClaw 7天教程 - Day 2: 10 分钟,搭建你的助手"
description: "OpenClaw 7天教程 - 第 2 天:10 分钟,搭建你的助手"
---
> *"别被'部署'这个词吓到。如果你能泡一碗方便面,你就能搭一个 AI 助手。时间差不多,都是 10 分钟的事。"*
+2 -2
View File
@@ -1,7 +1,7 @@
---
title: "Day 3: 给助手一个灵魂"
title: "第 3 天:给助手一个灵魂"
day: 3
description: "OpenClaw 7天教程 - Day 3: 给助手一个灵魂"
description: "OpenClaw 7天教程 - 第 3 天:给助手一个灵魂"
---
> *"没有灵魂的 AI 助手,就是个高级复读机。它能回答问题,但它不认识你,不了解你,不是'你的'。今天,我们改变这件事。"*
+2 -2
View File
@@ -1,7 +1,7 @@
---
title: "Day 4: 接入你的数字生活"
title: "第 4 天:接入你的数字生活"
day: 4
description: "OpenClaw 7天教程 - Day 4: 接入你的数字生活"
description: "OpenClaw 7天教程 - 第 4 天:接入你的数字生活"
---
> *"一个只会聊天的 AI 助手,和一个能帮你读邮件、管日历、上网搜信息的 AI 助手,中间差的不是智商,是一双手。今天我们给它接上手。"*
+2 -2
View File
@@ -1,7 +1,7 @@
---
title: "Day 5: 解锁技能树"
title: "第 5 天:解锁技能树"
day: 5
description: "OpenClaw 7天教程 - Day 5: 解锁技能树"
description: "OpenClaw 7天教程 - 第 5 天:解锁技能树"
---
> *"如果说 Day 4 是给助手接上了手,那今天就是给它发了一整箱工具。螺丝刀、扳手、电钻……用哪个取哪个,用完放回去。这就是 Skills 系统。"*
+2 -2
View File
@@ -1,7 +1,7 @@
---
title: "Day 6: 让助手主动工作"
title: "第 6 天:让助手主动工作"
day: 6
description: "OpenClaw 7天教程 - Day 6: 让助手主动工作"
description: "OpenClaw 7天教程 - 第 6 天:让助手主动工作"
---
> *"一个你要主动去问的助手,只是一个工具。一个主动来找你的助手,才是真正的助手。今天之后,你再也不需要'记得检查邮件'了——因为有人帮你记着。"*
+2 -2
View File
@@ -1,7 +1,7 @@
---
title: "Day 7: 进阶玩法 & 未来展望"
title: "第 7 天:进阶玩法 & 未来展望"
day: 7
description: "OpenClaw 7天教程 - Day 7: 进阶玩法 & 未来展望"
description: "OpenClaw 7天教程 - 第 7 天:进阶玩法 & 未来展望"
---
> *"七天前你还在想'AI 助手是什么'。现在你有了一个 24 小时在线、了解你、能办事、会主动工作的私人助手。但我要告诉你——这才刚开始。"*
+1 -1
View File
@@ -4,7 +4,7 @@
"private": true,
"scripts": {
"dev": "next dev",
"build": "next build",
"build": "next build && node scripts/postbuild-seo.mjs",
"start": "next start"
},
"dependencies": {
-1
View File
@@ -1,7 +1,6 @@
User-agent: *
Allow: /
# AI Search Engines - Welcome!
User-agent: GPTBot
Allow: /
+91 -81
View File
@@ -1,154 +1,164 @@
<?xml version="1.0" encoding="UTF-8"?>
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9"
xmlns:xhtml="http://www.w3.org/1999/xhtml">
<!-- Home -->
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9" xmlns:xhtml="http://www.w3.org/1999/xhtml">
<url>
<loc>https://openclaw101.dev/</loc>
<xhtml:link rel="alternate" hreflang="en" href="https://openclaw101.dev/"/>
<xhtml:link rel="alternate" hreflang="zh" href="https://openclaw101.dev/zh"/>
<lastmod>2026-02-04</lastmod>
<xhtml:link rel="alternate" hreflang="zh-CN" href="https://openclaw101.dev/zh"/>
<xhtml:link rel="alternate" hreflang="x-default" href="https://openclaw101.dev/"/>
<lastmod>2026-03-15T14:09:18.271Z</lastmod>
<changefreq>weekly</changefreq>
<priority>1.0</priority>
</url>
<url>
<loc>https://openclaw101.dev/zh</loc>
<xhtml:link rel="alternate" hreflang="en" href="https://openclaw101.dev/"/>
<xhtml:link rel="alternate" hreflang="zh" href="https://openclaw101.dev/zh"/>
<lastmod>2026-02-04</lastmod>
<xhtml:link rel="alternate" hreflang="zh-CN" href="https://openclaw101.dev/zh"/>
<xhtml:link rel="alternate" hreflang="x-default" href="https://openclaw101.dev/"/>
<lastmod>2026-03-15T14:09:18.271Z</lastmod>
<changefreq>weekly</changefreq>
<priority>1.0</priority>
</url>
<!-- Resources -->
<url>
<loc>https://openclaw101.dev/resources</loc>
<xhtml:link rel="alternate" hreflang="en" href="https://openclaw101.dev/resources"/>
<xhtml:link rel="alternate" hreflang="zh" href="https://openclaw101.dev/zh/resources"/>
<lastmod>2026-02-04</lastmod>
<xhtml:link rel="alternate" hreflang="zh-CN" href="https://openclaw101.dev/zh/resources"/>
<xhtml:link rel="alternate" hreflang="x-default" href="https://openclaw101.dev/resources"/>
<lastmod>2026-03-26T18:02:53.846Z</lastmod>
<changefreq>weekly</changefreq>
<priority>0.8</priority>
</url>
<url>
<loc>https://openclaw101.dev/zh/resources</loc>
<xhtml:link rel="alternate" hreflang="en" href="https://openclaw101.dev/resources"/>
<xhtml:link rel="alternate" hreflang="zh" href="https://openclaw101.dev/zh/resources"/>
<lastmod>2026-02-04</lastmod>
<xhtml:link rel="alternate" hreflang="zh-CN" href="https://openclaw101.dev/zh/resources"/>
<xhtml:link rel="alternate" hreflang="x-default" href="https://openclaw101.dev/resources"/>
<lastmod>2026-03-26T18:02:53.846Z</lastmod>
<changefreq>weekly</changefreq>
<priority>0.8</priority>
</url>
<!-- 7-Day Tutorial - English -->
<url>
<loc>https://openclaw101.dev/day/1</loc>
<xhtml:link rel="alternate" hreflang="en" href="https://openclaw101.dev/day/1"/>
<xhtml:link rel="alternate" hreflang="zh" href="https://openclaw101.dev/zh/day/1"/>
<lastmod>2026-02-04</lastmod>
<xhtml:link rel="alternate" hreflang="zh-CN" href="https://openclaw101.dev/zh/day/1"/>
<xhtml:link rel="alternate" hreflang="x-default" href="https://openclaw101.dev/day/1"/>
<lastmod>2026-03-15T14:09:18.271Z</lastmod>
<changefreq>monthly</changefreq>
<priority>0.9</priority>
</url>
<url>
<loc>https://openclaw101.dev/zh/day/1</loc>
<xhtml:link rel="alternate" hreflang="en" href="https://openclaw101.dev/day/1"/>
<xhtml:link rel="alternate" hreflang="zh-CN" href="https://openclaw101.dev/zh/day/1"/>
<xhtml:link rel="alternate" hreflang="x-default" href="https://openclaw101.dev/day/1"/>
<lastmod>2026-03-15T14:09:18.271Z</lastmod>
<changefreq>monthly</changefreq>
<priority>0.9</priority>
</url>
<url>
<loc>https://openclaw101.dev/day/2</loc>
<xhtml:link rel="alternate" hreflang="en" href="https://openclaw101.dev/day/2"/>
<xhtml:link rel="alternate" hreflang="zh" href="https://openclaw101.dev/zh/day/2"/>
<lastmod>2026-02-04</lastmod>
<changefreq>monthly</changefreq>
<priority>0.9</priority>
</url>
<url>
<loc>https://openclaw101.dev/day/3</loc>
<xhtml:link rel="alternate" hreflang="en" href="https://openclaw101.dev/day/3"/>
<xhtml:link rel="alternate" hreflang="zh" href="https://openclaw101.dev/zh/day/3"/>
<lastmod>2026-02-04</lastmod>
<changefreq>monthly</changefreq>
<priority>0.9</priority>
</url>
<url>
<loc>https://openclaw101.dev/day/4</loc>
<xhtml:link rel="alternate" hreflang="en" href="https://openclaw101.dev/day/4"/>
<xhtml:link rel="alternate" hreflang="zh" href="https://openclaw101.dev/zh/day/4"/>
<lastmod>2026-02-04</lastmod>
<changefreq>monthly</changefreq>
<priority>0.9</priority>
</url>
<url>
<loc>https://openclaw101.dev/day/5</loc>
<xhtml:link rel="alternate" hreflang="en" href="https://openclaw101.dev/day/5"/>
<xhtml:link rel="alternate" hreflang="zh" href="https://openclaw101.dev/zh/day/5"/>
<lastmod>2026-02-04</lastmod>
<changefreq>monthly</changefreq>
<priority>0.9</priority>
</url>
<url>
<loc>https://openclaw101.dev/day/6</loc>
<xhtml:link rel="alternate" hreflang="en" href="https://openclaw101.dev/day/6"/>
<xhtml:link rel="alternate" hreflang="zh" href="https://openclaw101.dev/zh/day/6"/>
<lastmod>2026-02-04</lastmod>
<changefreq>monthly</changefreq>
<priority>0.9</priority>
</url>
<url>
<loc>https://openclaw101.dev/day/7</loc>
<xhtml:link rel="alternate" hreflang="en" href="https://openclaw101.dev/day/7"/>
<xhtml:link rel="alternate" hreflang="zh" href="https://openclaw101.dev/zh/day/7"/>
<lastmod>2026-02-04</lastmod>
<changefreq>monthly</changefreq>
<priority>0.9</priority>
</url>
<!-- 7-Day Tutorial - Chinese -->
<url>
<loc>https://openclaw101.dev/zh/day/1</loc>
<xhtml:link rel="alternate" hreflang="en" href="https://openclaw101.dev/day/1"/>
<xhtml:link rel="alternate" hreflang="zh" href="https://openclaw101.dev/zh/day/1"/>
<lastmod>2026-02-04</lastmod>
<xhtml:link rel="alternate" hreflang="zh-CN" href="https://openclaw101.dev/zh/day/2"/>
<xhtml:link rel="alternate" hreflang="x-default" href="https://openclaw101.dev/day/2"/>
<lastmod>2026-03-15T14:09:18.271Z</lastmod>
<changefreq>monthly</changefreq>
<priority>0.9</priority>
</url>
<url>
<loc>https://openclaw101.dev/zh/day/2</loc>
<xhtml:link rel="alternate" hreflang="en" href="https://openclaw101.dev/day/2"/>
<xhtml:link rel="alternate" hreflang="zh" href="https://openclaw101.dev/zh/day/2"/>
<lastmod>2026-02-04</lastmod>
<xhtml:link rel="alternate" hreflang="zh-CN" href="https://openclaw101.dev/zh/day/2"/>
<xhtml:link rel="alternate" hreflang="x-default" href="https://openclaw101.dev/day/2"/>
<lastmod>2026-03-15T14:09:18.271Z</lastmod>
<changefreq>monthly</changefreq>
<priority>0.9</priority>
</url>
<url>
<loc>https://openclaw101.dev/day/3</loc>
<xhtml:link rel="alternate" hreflang="en" href="https://openclaw101.dev/day/3"/>
<xhtml:link rel="alternate" hreflang="zh-CN" href="https://openclaw101.dev/zh/day/3"/>
<xhtml:link rel="alternate" hreflang="x-default" href="https://openclaw101.dev/day/3"/>
<lastmod>2026-03-15T14:09:18.271Z</lastmod>
<changefreq>monthly</changefreq>
<priority>0.9</priority>
</url>
<url>
<loc>https://openclaw101.dev/zh/day/3</loc>
<xhtml:link rel="alternate" hreflang="en" href="https://openclaw101.dev/day/3"/>
<xhtml:link rel="alternate" hreflang="zh" href="https://openclaw101.dev/zh/day/3"/>
<lastmod>2026-02-04</lastmod>
<xhtml:link rel="alternate" hreflang="zh-CN" href="https://openclaw101.dev/zh/day/3"/>
<xhtml:link rel="alternate" hreflang="x-default" href="https://openclaw101.dev/day/3"/>
<lastmod>2026-03-15T14:09:18.271Z</lastmod>
<changefreq>monthly</changefreq>
<priority>0.9</priority>
</url>
<url>
<loc>https://openclaw101.dev/day/4</loc>
<xhtml:link rel="alternate" hreflang="en" href="https://openclaw101.dev/day/4"/>
<xhtml:link rel="alternate" hreflang="zh-CN" href="https://openclaw101.dev/zh/day/4"/>
<xhtml:link rel="alternate" hreflang="x-default" href="https://openclaw101.dev/day/4"/>
<lastmod>2026-03-15T14:09:18.271Z</lastmod>
<changefreq>monthly</changefreq>
<priority>0.9</priority>
</url>
<url>
<loc>https://openclaw101.dev/zh/day/4</loc>
<xhtml:link rel="alternate" hreflang="en" href="https://openclaw101.dev/day/4"/>
<xhtml:link rel="alternate" hreflang="zh" href="https://openclaw101.dev/zh/day/4"/>
<lastmod>2026-02-04</lastmod>
<xhtml:link rel="alternate" hreflang="zh-CN" href="https://openclaw101.dev/zh/day/4"/>
<xhtml:link rel="alternate" hreflang="x-default" href="https://openclaw101.dev/day/4"/>
<lastmod>2026-03-15T14:09:18.271Z</lastmod>
<changefreq>monthly</changefreq>
<priority>0.9</priority>
</url>
<url>
<loc>https://openclaw101.dev/day/5</loc>
<xhtml:link rel="alternate" hreflang="en" href="https://openclaw101.dev/day/5"/>
<xhtml:link rel="alternate" hreflang="zh-CN" href="https://openclaw101.dev/zh/day/5"/>
<xhtml:link rel="alternate" hreflang="x-default" href="https://openclaw101.dev/day/5"/>
<lastmod>2026-03-15T14:09:18.271Z</lastmod>
<changefreq>monthly</changefreq>
<priority>0.9</priority>
</url>
<url>
<loc>https://openclaw101.dev/zh/day/5</loc>
<xhtml:link rel="alternate" hreflang="en" href="https://openclaw101.dev/day/5"/>
<xhtml:link rel="alternate" hreflang="zh" href="https://openclaw101.dev/zh/day/5"/>
<lastmod>2026-02-04</lastmod>
<xhtml:link rel="alternate" hreflang="zh-CN" href="https://openclaw101.dev/zh/day/5"/>
<xhtml:link rel="alternate" hreflang="x-default" href="https://openclaw101.dev/day/5"/>
<lastmod>2026-03-15T14:09:18.271Z</lastmod>
<changefreq>monthly</changefreq>
<priority>0.9</priority>
</url>
<url>
<loc>https://openclaw101.dev/day/6</loc>
<xhtml:link rel="alternate" hreflang="en" href="https://openclaw101.dev/day/6"/>
<xhtml:link rel="alternate" hreflang="zh-CN" href="https://openclaw101.dev/zh/day/6"/>
<xhtml:link rel="alternate" hreflang="x-default" href="https://openclaw101.dev/day/6"/>
<lastmod>2026-03-15T14:09:18.271Z</lastmod>
<changefreq>monthly</changefreq>
<priority>0.9</priority>
</url>
<url>
<loc>https://openclaw101.dev/zh/day/6</loc>
<xhtml:link rel="alternate" hreflang="en" href="https://openclaw101.dev/day/6"/>
<xhtml:link rel="alternate" hreflang="zh" href="https://openclaw101.dev/zh/day/6"/>
<lastmod>2026-02-04</lastmod>
<xhtml:link rel="alternate" hreflang="zh-CN" href="https://openclaw101.dev/zh/day/6"/>
<xhtml:link rel="alternate" hreflang="x-default" href="https://openclaw101.dev/day/6"/>
<lastmod>2026-03-15T14:09:18.271Z</lastmod>
<changefreq>monthly</changefreq>
<priority>0.9</priority>
</url>
<url>
<loc>https://openclaw101.dev/day/7</loc>
<xhtml:link rel="alternate" hreflang="en" href="https://openclaw101.dev/day/7"/>
<xhtml:link rel="alternate" hreflang="zh-CN" href="https://openclaw101.dev/zh/day/7"/>
<xhtml:link rel="alternate" hreflang="x-default" href="https://openclaw101.dev/day/7"/>
<lastmod>2026-03-15T14:09:18.271Z</lastmod>
<changefreq>monthly</changefreq>
<priority>0.9</priority>
</url>
<url>
<loc>https://openclaw101.dev/zh/day/7</loc>
<xhtml:link rel="alternate" hreflang="en" href="https://openclaw101.dev/day/7"/>
<xhtml:link rel="alternate" hreflang="zh" href="https://openclaw101.dev/zh/day/7"/>
<lastmod>2026-02-04</lastmod>
<xhtml:link rel="alternate" hreflang="zh-CN" href="https://openclaw101.dev/zh/day/7"/>
<xhtml:link rel="alternate" hreflang="x-default" href="https://openclaw101.dev/day/7"/>
<lastmod>2026-03-15T14:09:18.271Z</lastmod>
<changefreq>monthly</changefreq>
<priority>0.9</priority>
</url>
+224
View File
@@ -0,0 +1,224 @@
import fs from 'fs';
import path from 'path';
import { fileURLToPath } from 'url';
const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);
const projectRoot = path.resolve(__dirname, '..');
const publicDir = path.join(projectRoot, 'public');
const outDir = path.join(projectRoot, 'out');
const siteUrl = 'https://openclaw101.dev';
const aiBots = [
'GPTBot',
'ChatGPT-User',
'Google-Extended',
'Perplexity-User',
'PerplexityBot',
'Claude-Web',
'anthropic-ai',
'Applebot-Extended',
'cohere-ai',
'Bytespider',
];
function resolveProjectFile(relativePath) {
return path.join(projectRoot, relativePath);
}
function fileExists(relativePath) {
return fs.existsSync(resolveProjectFile(relativePath));
}
function getLatestModified(relativePaths) {
const timestamps = relativePaths
.filter(fileExists)
.map((relativePath) => fs.statSync(resolveProjectFile(relativePath)).mtimeMs);
return new Date(Math.max(...timestamps));
}
function toAbsoluteUrl(pathname) {
return new URL(pathname, siteUrl).toString();
}
function formatLastModified(date) {
return date.toISOString();
}
function createSitemapUrlEntry({ loc, en, zh, lastmod, changefreq, priority }) {
return ` <url>\n <loc>${toAbsoluteUrl(loc)}</loc>\n <xhtml:link rel="alternate" hreflang="en" href="${toAbsoluteUrl(en)}"/>\n <xhtml:link rel="alternate" hreflang="zh-CN" href="${toAbsoluteUrl(zh)}"/>\n <xhtml:link rel="alternate" hreflang="x-default" href="${toAbsoluteUrl(en)}"/>\n <lastmod>${formatLastModified(lastmod)}</lastmod>\n <changefreq>${changefreq}</changefreq>\n <priority>${priority.toFixed(1)}</priority>\n </url>`;
}
function buildSitemapXml() {
const homeModified = getLatestModified([
'src/app/page.tsx',
'src/app/zh/page.tsx',
'src/components/HomePage.tsx',
'src/lib/seo.ts',
]);
const resourcesModified = getLatestModified([
'src/app/resources/page.tsx',
'src/app/zh/resources/page.tsx',
'src/components/ResourcesPage.tsx',
'src/data/resources.ts',
'src/lib/seo.ts',
]);
const urls = [
createSitemapUrlEntry({
loc: '/',
en: '/',
zh: '/zh',
lastmod: homeModified,
changefreq: 'weekly',
priority: 1.0,
}),
createSitemapUrlEntry({
loc: '/zh',
en: '/',
zh: '/zh',
lastmod: homeModified,
changefreq: 'weekly',
priority: 1.0,
}),
createSitemapUrlEntry({
loc: '/resources',
en: '/resources',
zh: '/zh/resources',
lastmod: resourcesModified,
changefreq: 'weekly',
priority: 0.8,
}),
createSitemapUrlEntry({
loc: '/zh/resources',
en: '/resources',
zh: '/zh/resources',
lastmod: resourcesModified,
changefreq: 'weekly',
priority: 0.8,
}),
];
for (let day = 1; day <= 7; day += 1) {
const dayModified = getLatestModified([
`content/days-en/day${day}.md`,
`content/days/day${day}.md`,
'src/app/day/[day]/page.tsx',
'src/app/zh/day/[day]/page.tsx',
'src/components/DayContent.tsx',
'src/lib/days.ts',
'src/lib/seo.ts',
]);
urls.push(
createSitemapUrlEntry({
loc: `/day/${day}`,
en: `/day/${day}`,
zh: `/zh/day/${day}`,
lastmod: dayModified,
changefreq: 'monthly',
priority: 0.9,
}),
);
urls.push(
createSitemapUrlEntry({
loc: `/zh/day/${day}`,
en: `/day/${day}`,
zh: `/zh/day/${day}`,
lastmod: dayModified,
changefreq: 'monthly',
priority: 0.9,
}),
);
}
return `<?xml version="1.0" encoding="UTF-8"?>\n<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9" xmlns:xhtml="http://www.w3.org/1999/xhtml">\n${urls.join('\n')}\n</urlset>\n`;
}
function buildRobotsTxt() {
const lines = ['User-agent: *', 'Allow: /', ''];
for (const bot of aiBots) {
lines.push(`User-agent: ${bot}`);
lines.push('Allow: /');
lines.push('');
}
lines.push(`Sitemap: ${siteUrl}/sitemap.xml`);
lines.push('');
return lines.join('\n');
}
function writeFileCopies(relativePath, content) {
const destinations = [path.join(publicDir, relativePath)];
if (fs.existsSync(outDir)) {
destinations.push(path.join(outDir, relativePath));
}
for (const destination of destinations) {
fs.mkdirSync(path.dirname(destination), { recursive: true });
fs.writeFileSync(destination, content);
}
}
function collectHtmlFiles(directory) {
if (!fs.existsSync(directory)) {
return [];
}
const entries = fs.readdirSync(directory, { withFileTypes: true });
const files = [];
for (const entry of entries) {
const fullPath = path.join(directory, entry.name);
if (entry.isDirectory()) {
files.push(...collectHtmlFiles(fullPath));
continue;
}
if (entry.isFile() && fullPath.endsWith('.html')) {
files.push(fullPath);
}
}
return files;
}
function patchZhHtmlLang() {
if (!fs.existsSync(outDir)) {
return;
}
const htmlFiles = collectHtmlFiles(outDir);
for (const filePath of htmlFiles) {
const relativePath = path.relative(outDir, filePath).replaceAll(path.sep, '/');
const isZhPage = relativePath === 'zh.html' || relativePath.startsWith('zh/');
if (!isZhPage) {
continue;
}
const original = fs.readFileSync(filePath, 'utf8');
const updated = original.replace(
/<html([^>]*)lang="[^"]*"([^>]*)>/,
'<html$1lang="zh-CN"$2>',
);
if (updated !== original) {
fs.writeFileSync(filePath, updated);
}
}
}
writeFileCopies('sitemap.xml', buildSitemapXml());
writeFileCopies('robots.txt', buildRobotsTxt());
patchZhHtmlLang();
console.log('SEO postbuild complete: generated robots.txt, sitemap.xml, and patched zh html lang.');
+68 -69
View File
@@ -1,85 +1,84 @@
import { Metadata } from 'next';
import type { Metadata } from 'next';
import { notFound } from 'next/navigation';
import fs from 'fs';
import path from 'path';
import matter from 'gray-matter';
import DayContent from '@/components/DayContent';
import { getDayContent, getDayStaticParams } from '@/lib/days';
import {
SITE_NAME,
SITE_URL,
absoluteUrl,
buildPageMetadata,
getStructuredDataLanguage,
} from '@/lib/seo';
interface Props {
params: Promise<{ day: string }>;
}
const DAYS = [1, 2, 3, 4, 5, 6, 7];
export async function generateStaticParams() {
return DAYS.map((day) => ({ day: day.toString() }));
}
function getDay(day: string): { content: string; frontmatter: any } | null {
const dayNum = parseInt(day);
if (!DAYS.includes(dayNum)) return null;
const filePath = path.join(process.cwd(), 'content', 'days-en', `day${dayNum}.md`);
if (!fs.existsSync(filePath)) return null;
const fileContent = fs.readFileSync(filePath, 'utf8');
const { data, content } = matter(fileContent);
return { content, frontmatter: data };
}
export async function generateMetadata({ params }: Props): Promise<Metadata> {
const { day } = await params;
const data = getDay(day);
if (!data) return { title: 'Not Found' };
const dayNum = parseInt(day);
const titles: Record<number, { en: string; zh: string }> = {
1: { en: 'Meet OpenClaw', zh: '初识 OpenClaw' },
2: { en: 'Build Your Assistant in 10 Minutes', zh: '10 分钟,搭建你的助手' },
3: { en: 'Give Your Assistant a Soul', zh: '给助手一个灵魂' },
4: { en: 'Connect Your Digital Life', zh: '接入你的数字生活' },
5: { en: 'Unlock the Skill Tree', zh: '解锁技能树' },
6: { en: 'Make Your Assistant Work Proactively', zh: '让助手主动工作' },
7: { en: 'Advanced Techniques & Future Outlook', zh: '进阶玩法 & 未来展望' },
params: {
day: string;
};
const title = `Day ${dayNum}: ${titles[dayNum]?.en || ''} | OpenClaw 101`;
return {
title,
}
export function generateStaticParams() {
return getDayStaticParams();
}
export function generateMetadata({ params }: Props): Metadata {
const data = getDayContent('en', params.day);
if (!data) {
return {
title: 'Not Found',
};
}
return buildPageMetadata({
title: data.frontmatter.title,
description: data.frontmatter.description,
alternates: {
canonical: `https://openclaw101.dev/day/${day}`,
languages: {
'en': `https://openclaw101.dev/day/${day}`,
'zh': `https://openclaw101.dev/zh/day/${day}`,
},
},
openGraph: {
title,
description: data.frontmatter.description,
type: 'article',
url: `https://openclaw101.dev/day/${day}`,
},
};
locale: 'en',
enPath: `/day/${params.day}`,
zhPath: `/zh/day/${params.day}`,
type: 'article',
});
}
export default async function DayPage({ params }: Props) {
const { day } = await params;
const data = getDay(day);
export default function DayPage({ params }: Props) {
const data = getDayContent('en', params.day);
if (!data) {
notFound();
}
const dayNum = parseInt(day);
const prevDay = dayNum > 1 ? dayNum - 1 : null;
const nextDay = dayNum < 7 ? dayNum + 1 : null;
const dayNumber = Number(params.day);
const prevDay = dayNumber > 1 ? dayNumber - 1 : null;
const nextDay = dayNumber < 7 ? dayNumber + 1 : null;
const url = absoluteUrl(`/day/${params.day}`);
const jsonLd = {
'@context': 'https://schema.org',
'@type': 'Article',
'@id': `${url}#article`,
headline: data.frontmatter.title,
description: data.frontmatter.description,
url,
inLanguage: getStructuredDataLanguage('en'),
isPartOf: {
'@type': 'WebSite',
name: SITE_NAME,
url: SITE_URL,
},
author: {
'@type': 'Organization',
name: SITE_NAME,
url: SITE_URL,
},
dateModified: data.lastModified,
};
return (
<main className="min-h-screen bg-gradient-to-b from-gray-900 to-gray-950">
<DayContent
day={dayNum}
<script
type="application/ld+json"
dangerouslySetInnerHTML={{ __html: JSON.stringify(jsonLd) }}
/>
<DayContent
day={dayNumber}
content={data.content}
frontmatter={data.frontmatter}
prevDay={prevDay}
+28 -150
View File
@@ -1,21 +1,24 @@
import type { Metadata } from 'next';
import Script from 'next/script';
import './globals.css';
import {
DEFAULT_OG_IMAGE,
SITE_KEYWORDS,
SITE_NAME,
SITE_URL,
} from '@/lib/seo';
export const metadata: Metadata = {
metadataBase: new URL('https://openclaw101.dev'),
const googleVerification = process.env.NEXT_PUBLIC_GOOGLE_SITE_VERIFICATION;
const CURRENT_SKILLS_COUNT = '5400+';
const siteMetadata: Metadata = {
metadataBase: new URL(SITE_URL),
title: {
default: 'OpenClaw 101 - Master Your AI Assistant in 7 Days | Free Tutorial',
template: '%s | OpenClaw 101',
default: SITE_NAME,
template: `%s | ${SITE_NAME}`,
},
description: 'Free 7-day tutorial to master OpenClaw (Clawdbot/Moltbot). Learn to build your own AI personal assistant with installation guides, 5490+ community skills, automation, and 400+ curated resources.',
keywords: [
'OpenClaw', 'OpenClaw tutorial', 'OpenClaw guide', 'OpenClaw 教程',
'Clawdbot', 'Moltbot', 'AI assistant', 'AI Agent', 'personal AI',
'Telegram bot', 'self-hosted AI', 'open source AI', 'AI automation',
'OpenClaw skills', 'OpenClaw installation', 'OpenClaw setup',
'7 day AI tutorial', 'AI助理', 'AI私人助手', '开源AI'
],
description: `Free 7-day tutorial to master OpenClaw (Clawdbot/Moltbot). Learn to build your own AI personal assistant with installation guides, ${CURRENT_SKILLS_COUNT} community skills, curated resources, automation tips, and step-by-step workflows.`,
keywords: SITE_KEYWORDS,
icons: {
icon: '/favicon.svg',
},
@@ -31,142 +34,31 @@ export const metadata: Metadata = {
},
},
openGraph: {
title: 'OpenClaw 101 - Master Your AI Assistant in 7 Days',
description: 'Free 7-day tutorial to build your own AI personal assistant with OpenClaw. 400+ curated resources, skills ecosystem, and step-by-step guides.',
url: 'https://openclaw101.dev',
siteName: 'OpenClaw 101',
siteName: SITE_NAME,
type: 'website',
url: SITE_URL,
images: [
{
url: 'https://openclaw101.dev/og-image.png',
url: DEFAULT_OG_IMAGE,
width: 1200,
height: 630,
alt: 'OpenClaw 101 - AI Assistant Tutorial',
alt: SITE_NAME,
},
],
locale: 'en_US',
type: 'website',
},
twitter: {
card: 'summary_large_image',
title: 'OpenClaw 101 - Master Your AI Assistant in 7 Days',
description: 'Free 7-day tutorial to build your own AI personal assistant with OpenClaw.',
images: ['https://openclaw101.dev/og-image.png'],
},
verification: {
google: 'G-86ESEQC7V8',
},
alternates: {
canonical: 'https://openclaw101.dev',
languages: {
'en': 'https://openclaw101.dev',
'zh': 'https://openclaw101.dev/zh',
},
images: [DEFAULT_OG_IMAGE],
},
};
// Schema.org structured data
const jsonLd = {
'@context': 'https://schema.org',
'@graph': [
{
'@type': 'WebSite',
'@id': 'https://openclaw101.dev/#website',
url: 'https://openclaw101.dev',
name: 'OpenClaw 101',
description: 'The definitive guide to mastering OpenClaw AI assistant',
inLanguage: ['en', 'zh'],
},
{
'@type': 'Course',
'@id': 'https://openclaw101.dev/#course',
name: 'OpenClaw 7-Day Tutorial',
description: 'Learn to build and customize your own AI personal assistant with OpenClaw in 7 days',
provider: {
'@type': 'Organization',
name: 'OpenClaw 101',
url: 'https://openclaw101.dev',
},
hasCourseInstance: {
'@type': 'CourseInstance',
courseMode: 'online',
courseWorkload: 'P7D',
},
numberOfLessons: 7,
teaches: ['AI Assistant Setup', 'OpenClaw Configuration', 'Skills Development', 'Automation'],
isAccessibleForFree: true,
availableLanguage: ['en', 'zh'],
},
{
'@type': 'FAQPage',
'@id': 'https://openclaw101.dev/#faq',
mainEntity: [
{
'@type': 'Question',
name: 'What is OpenClaw?',
acceptedAnswer: {
'@type': 'Answer',
text: 'OpenClaw is an open-source AI agent framework that lets you build a self-hosted personal AI assistant. It connects to services like Telegram, Gmail, Google Calendar, and web browsers, and can execute code, automate tasks, and manage your digital life 24/7. It was formerly known as Clawdbot and Moltbot.',
},
},
{
'@type': 'Question',
name: 'Is OpenClaw free?',
acceptedAnswer: {
'@type': 'Answer',
text: 'Yes, OpenClaw is fully open-source and free to use. You only pay for the AI model API costs (e.g., Claude ~$3-15/month) and server hosting (~$5-20/month).',
},
},
{
'@type': 'Question',
name: 'How do I install OpenClaw?',
acceptedAnswer: {
'@type': 'Answer',
text: 'You need a Linux server (Ubuntu 22.04+ recommended), Node.js 20+, and an API key for your chosen AI model. Clone the repository, run the setup wizard, configure your Telegram bot token, and start the gateway. The Day 2 tutorial at openclaw101.dev/day/2 covers this step by step.',
},
},
{
'@type': 'Question',
name: 'What AI models does OpenClaw support?',
acceptedAnswer: {
'@type': 'Answer',
text: 'OpenClaw supports Anthropic Claude (recommended), OpenAI GPT-4, Google Gemini, xAI Grok, and any model available through OpenRouter.',
},
},
{
'@type': 'Question',
name: 'What can an OpenClaw assistant do?',
acceptedAnswer: {
'@type': 'Answer',
text: 'An OpenClaw assistant can manage email, schedule calendar events, browse the web with a real browser, write and execute code, analyze SEO data, create content, monitor websites, automate workflows, and more through its extensible skills system with 5490+ community plugins.',
},
},
{
'@type': 'Question',
name: 'What is the difference between OpenClaw and ChatGPT?',
acceptedAnswer: {
'@type': 'Answer',
text: 'ChatGPT is a conversational AI in the cloud. OpenClaw is a framework for building your own AI agent on your server, with persistent memory, real tool access (email, browser, code execution), proactive automation (heartbeats, cron jobs), and full customization. ChatGPT is a chat app; OpenClaw is a personal AI employee.',
},
},
],
},
{
'@type': 'ItemList',
'@id': 'https://openclaw101.dev/#tutorial-list',
name: 'OpenClaw 7-Day Learning Path',
numberOfItems: 7,
itemListElement: [
{ '@type': 'ListItem', position: 1, name: 'Day 1: Meet OpenClaw', url: 'https://openclaw101.dev/day/1' },
{ '@type': 'ListItem', position: 2, name: 'Day 2: Installation', url: 'https://openclaw101.dev/day/2' },
{ '@type': 'ListItem', position: 3, name: 'Day 3: Give Your Assistant a Soul', url: 'https://openclaw101.dev/day/3' },
{ '@type': 'ListItem', position: 4, name: 'Day 4: Connect Your Digital Life', url: 'https://openclaw101.dev/day/4' },
{ '@type': 'ListItem', position: 5, name: 'Day 5: Skills Ecosystem', url: 'https://openclaw101.dev/day/5' },
{ '@type': 'ListItem', position: 6, name: 'Day 6: Automation & Heartbeat', url: 'https://openclaw101.dev/day/6' },
{ '@type': 'ListItem', position: 7, name: 'Day 7: Advanced Techniques', url: 'https://openclaw101.dev/day/7' },
],
},
],
};
if (googleVerification) {
siteMetadata.verification = {
google: googleVerification,
};
}
export const metadata = siteMetadata;
export default function RootLayout({
children,
@@ -176,7 +68,6 @@ export default function RootLayout({
return (
<html lang="en">
<head>
{/* Google AdSense */}
<meta name="google-adsense-account" content="ca-pub-1081201777589554" />
<Script
src="https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js?client=ca-pub-1081201777589554"
@@ -184,18 +75,6 @@ export default function RootLayout({
crossOrigin="anonymous"
/>
{/* Schema.org structured data */}
<script
type="application/ld+json"
dangerouslySetInnerHTML={{ __html: JSON.stringify(jsonLd) }}
/>
{/* hreflang tags for i18n */}
<link rel="alternate" hrefLang="en" href="https://openclaw101.dev" />
<link rel="alternate" hrefLang="zh" href="https://openclaw101.dev/zh" />
<link rel="alternate" hrefLang="x-default" href="https://openclaw101.dev" />
{/* Google tag (gtag.js) */}
<Script
src="https://www.googletagmanager.com/gtag/js?id=G-86ESEQC7V8"
strategy="afterInteractive"
@@ -207,7 +86,6 @@ gtag('js', new Date());
gtag('config', 'G-86ESEQC7V8');`}
</Script>
{/* Privacy-friendly analytics by Plausible */}
<Script
src="https://plausible.shipsolo.io/js/pa-JFzm3YyWo6Cak1n9mzePz.js"
strategy="afterInteractive"
+136 -40
View File
@@ -1,56 +1,152 @@
import { Metadata } from 'next';
import type { Metadata } from 'next';
import HomePage from '@/components/HomePage';
import {
SITE_NAME,
SITE_URL,
buildPageMetadata,
getStructuredDataLanguage,
} from '@/lib/seo';
export const metadata: Metadata = {
title: 'OpenClaw 101 - Master Your AI Assistant in 7 Days',
description: 'The definitive guide to building your AI assistant with OpenClaw. Tutorials, skills, and community resources for your personal AI agent.',
alternates: {
canonical: 'https://openclaw101.dev',
languages: {
'en': 'https://openclaw101.dev',
'zh': 'https://openclaw101.dev/zh',
},
},
openGraph: {
title: 'OpenClaw 101 - Master Your AI Assistant in 7 Days',
description: 'The definitive guide to building your AI assistant with OpenClaw.',
type: 'website',
url: 'https://openclaw101.dev',
siteName: 'OpenClaw 101',
images: [
{
url: '/og-image.png',
width: 1200,
height: 630,
alt: 'OpenClaw 101 - Master Your AI Assistant in 7 Days',
},
],
},
twitter: {
card: 'summary_large_image',
title: 'OpenClaw 101 - Master Your AI Assistant in 7 Days',
description: 'The definitive guide to building your AI assistant with OpenClaw.',
images: ['/og-image.png'],
},
};
export const metadata: Metadata = buildPageMetadata({
title: 'Master Your AI Assistant in 7 Days',
description:
'The definitive guide to building your AI assistant with OpenClaw. Step-by-step tutorials, curated resources, and practical workflows for your personal AI agent.',
locale: 'en',
enPath: '/',
zhPath: '/zh',
});
const jsonLd = {
'@context': 'https://schema.org',
'@type': 'WebSite',
name: 'OpenClaw 101',
url: 'https://openclaw101.dev',
description: 'Master your AI personal assistant in 7 days',
inLanguage: 'en',
'@graph': [
{
'@type': 'WebSite',
'@id': `${SITE_URL}/#website`,
url: SITE_URL,
name: SITE_NAME,
description: 'Master your AI personal assistant in 7 days.',
inLanguage: getStructuredDataLanguage('en'),
},
{
'@type': 'Course',
'@id': `${SITE_URL}/#course`,
url: SITE_URL,
name: 'OpenClaw 7-Day Tutorial',
description:
'Learn to build and customize your own AI personal assistant with OpenClaw in seven practical lessons.',
provider: {
'@type': 'Organization',
name: SITE_NAME,
url: SITE_URL,
},
hasCourseInstance: {
'@type': 'CourseInstance',
courseMode: 'online',
courseWorkload: 'P7D',
},
numberOfLessons: 7,
isAccessibleForFree: true,
availableLanguage: ['en', 'zh-CN'],
},
{
'@type': 'FAQPage',
'@id': `${SITE_URL}/#faq`,
mainEntity: [
{
'@type': 'Question',
name: 'What is OpenClaw?',
acceptedAnswer: {
'@type': 'Answer',
text: 'OpenClaw is an open-source AI agent framework for building a self-hosted personal AI assistant that can chat, automate tasks, use tools, and stay online for you.',
},
},
{
'@type': 'Question',
name: 'Is OpenClaw free?',
acceptedAnswer: {
'@type': 'Answer',
text: 'Yes. OpenClaw is open source and free to use. You only need to cover model API usage and the machine or server where you run it.',
},
},
{
'@type': 'Question',
name: 'How long does the tutorial take?',
acceptedAnswer: {
'@type': 'Answer',
text: 'The tutorial is split into seven focused days so you can learn installation, setup, skills, integrations, and automation step by step.',
},
},
{
'@type': 'Question',
name: 'Which AI models does OpenClaw support?',
acceptedAnswer: {
'@type': 'Answer',
text: 'OpenClaw supports Claude, OpenAI models, Google Gemini, xAI Grok, and other providers available through OpenRouter.',
},
},
],
},
{
'@type': 'ItemList',
'@id': `${SITE_URL}/#tutorial-list`,
name: 'OpenClaw 7-Day Learning Path',
numberOfItems: 7,
itemListElement: [
{
'@type': 'ListItem',
position: 1,
name: 'Day 1: Meet OpenClaw',
url: `${SITE_URL}/day/1`,
},
{
'@type': 'ListItem',
position: 2,
name: 'Day 2: Build Your Assistant in 10 Minutes',
url: `${SITE_URL}/day/2`,
},
{
'@type': 'ListItem',
position: 3,
name: 'Day 3: Give Your Assistant a Soul',
url: `${SITE_URL}/day/3`,
},
{
'@type': 'ListItem',
position: 4,
name: 'Day 4: Connect Your Digital Life',
url: `${SITE_URL}/day/4`,
},
{
'@type': 'ListItem',
position: 5,
name: 'Day 5: Unlock the Skill Tree',
url: `${SITE_URL}/day/5`,
},
{
'@type': 'ListItem',
position: 6,
name: 'Day 6: Make Your Assistant Work Proactively',
url: `${SITE_URL}/day/6`,
},
{
'@type': 'ListItem',
position: 7,
name: 'Day 7: Advanced Techniques & Future Outlook',
url: `${SITE_URL}/day/7`,
},
],
},
],
};
export default function Home() {
return (
<main>
<>
<script
type="application/ld+json"
dangerouslySetInnerHTML={{ __html: JSON.stringify(jsonLd) }}
/>
<HomePage locale="en" />
</main>
</>
);
}
-34
View File
@@ -1,37 +1,3 @@
import type { Metadata } from 'next';
export const metadata: Metadata = {
title: '全网 OpenClaw 资源聚合 — 35+ 篇精选教程 | OpenClaw 101',
description:
'阿里云、腾讯云、DigitalOcean、B站、Codecademy 等 35+ 篇 OpenClaw 教程资源聚合,涵盖部署、平台接入、技能开发等 8 大分类。',
alternates: {
canonical: 'https://openclaw101.dev/resources',
},
openGraph: {
title: '全网 OpenClaw 资源聚合 — 35+ 篇精选教程 | OpenClaw 101',
description:
'阿里云、腾讯云、DigitalOcean、B站、Codecademy 等 35+ 篇 OpenClaw 教程资源聚合,涵盖部署、平台接入、技能开发等 8 大分类。',
type: 'website',
url: 'https://openclaw101.dev/resources',
siteName: 'OpenClaw 101',
images: [
{
url: '/og-image.png',
width: 1200,
height: 630,
alt: '全网 OpenClaw 资源聚合 — 35+ 篇精选教程',
},
],
},
twitter: {
card: 'summary_large_image',
title: '全网 OpenClaw 资源聚合 — 35+ 篇精选教程 | OpenClaw 101',
description:
'阿里云、腾讯云、DigitalOcean、B站、Codecademy 等 35+ 篇 OpenClaw 教程资源聚合,涵盖部署、平台接入、技能开发等 8 大分类。',
images: ['/og-image.png'],
},
};
export default function ResourcesLayout({
children,
}: {
+23 -39
View File
@@ -1,50 +1,34 @@
import { Metadata } from 'next';
import type { Metadata } from 'next';
import ResourcesPage from '@/components/ResourcesPage';
import {
SITE_NAME,
SITE_URL,
buildPageMetadata,
getStructuredDataLanguage,
} from '@/lib/seo';
export const metadata: Metadata = {
title: 'Resource Hub',
description: 'One-stop access to the best OpenClaw tutorials from Alibaba Cloud, Tencent Cloud, DigitalOcean, Bilibili, Codecademy, IBM and more.',
alternates: {
canonical: 'https://openclaw101.dev/resources',
languages: {
'en': 'https://openclaw101.dev/resources',
'zh': 'https://openclaw101.dev/zh/resources',
},
},
openGraph: {
title: 'Resource Hub',
description: 'One-stop access to the best OpenClaw tutorials from Alibaba Cloud, Tencent Cloud, DigitalOcean, Bilibili, Codecademy, IBM and more.',
type: 'website',
url: 'https://openclaw101.dev/resources',
siteName: 'OpenClaw 101',
images: [
{
url: '/og-image.png',
width: 1200,
height: 630,
alt: 'Resource Hub - OpenClaw 101',
},
],
},
twitter: {
card: 'summary_large_image',
title: 'Resource Hub',
description: 'One-stop access to the best OpenClaw tutorials from Alibaba Cloud, Tencent Cloud, DigitalOcean, Bilibili, Codecademy, IBM and more.',
images: ['/og-image.png'],
},
};
export const metadata: Metadata = buildPageMetadata({
title: 'OpenClaw Resource Hub',
description:
'Browse 35+ curated OpenClaw tutorials, deployment guides, videos, and integration resources from Alibaba Cloud, Tencent Cloud, DigitalOcean, Bilibili, IBM, Codecademy, and more.',
locale: 'en',
enPath: '/resources',
zhPath: '/zh/resources',
});
const jsonLd = {
'@context': 'https://schema.org',
'@type': 'CollectionPage',
name: 'Resource Hub - OpenClaw 101',
url: 'https://openclaw101.dev/resources',
description: 'One-stop access to the best OpenClaw tutorials from Alibaba Cloud, Tencent Cloud, DigitalOcean, Bilibili, Codecademy, IBM and more.',
inLanguage: 'en',
'@id': `${SITE_URL}/resources#collection`,
name: 'OpenClaw Resource Hub',
url: `${SITE_URL}/resources`,
description:
'Curated OpenClaw tutorials, deployment guides, videos, and integration resources in one place.',
inLanguage: getStructuredDataLanguage('en'),
isPartOf: {
'@type': 'WebSite',
name: 'OpenClaw 101',
url: 'https://openclaw101.dev',
name: SITE_NAME,
url: SITE_URL,
},
};
+68 -70
View File
@@ -1,86 +1,84 @@
import { Metadata } from 'next';
import type { Metadata } from 'next';
import { notFound } from 'next/navigation';
import fs from 'fs';
import path from 'path';
import matter from 'gray-matter';
import DayContent from '@/components/DayContent';
import { getDayContent, getDayStaticParams } from '@/lib/days';
import {
SITE_NAME,
SITE_URL,
absoluteUrl,
buildPageMetadata,
getStructuredDataLanguage,
} from '@/lib/seo';
interface Props {
params: Promise<{ day: string }>;
}
const DAYS = [1, 2, 3, 4, 5, 6, 7];
export async function generateStaticParams() {
return DAYS.map((day) => ({ day: day.toString() }));
}
function getDay(day: string): { content: string; frontmatter: any } | null {
const dayNum = parseInt(day);
if (!DAYS.includes(dayNum)) return null;
const filePath = path.join(process.cwd(), 'content', 'days', `day${dayNum}.md`);
if (!fs.existsSync(filePath)) return null;
const fileContent = fs.readFileSync(filePath, 'utf8');
const { data, content } = matter(fileContent);
return { content, frontmatter: data };
}
export async function generateMetadata({ params }: Props): Promise<Metadata> {
const { day } = await params;
const data = getDay(day);
if (!data) return { title: 'Not Found' };
const dayNum = parseInt(day);
const titles: Record<number, string> = {
1: '初识 OpenClaw',
2: '深入对话',
3: '文件与代码',
4: '网络能力',
5: '技能扩展',
6: '自动化',
7: '高级技巧',
params: {
day: string;
};
const title = `${dayNum} 天:${titles[dayNum]} | OpenClaw 101`;
return {
title,
}
export function generateStaticParams() {
return getDayStaticParams();
}
export function generateMetadata({ params }: Props): Metadata {
const data = getDayContent('zh', params.day);
if (!data) {
return {
title: 'Not Found',
};
}
return buildPageMetadata({
title: data.frontmatter.title,
description: data.frontmatter.description,
alternates: {
canonical: `https://openclaw101.dev/zh/day/${day}`,
languages: {
'en': `https://openclaw101.dev/day/${day}`,
'zh': `https://openclaw101.dev/zh/day/${day}`,
},
},
openGraph: {
title,
description: data.frontmatter.description,
type: 'article',
url: `https://openclaw101.dev/zh/day/${day}`,
locale: 'zh_CN',
},
};
locale: 'zh',
enPath: `/day/${params.day}`,
zhPath: `/zh/day/${params.day}`,
type: 'article',
});
}
export default async function DayPage({ params }: Props) {
const { day } = await params;
const data = getDay(day);
export default function DayPage({ params }: Props) {
const data = getDayContent('zh', params.day);
if (!data) {
notFound();
}
const dayNum = parseInt(day);
const prevDay = dayNum > 1 ? dayNum - 1 : null;
const nextDay = dayNum < 7 ? dayNum + 1 : null;
const dayNumber = Number(params.day);
const prevDay = dayNumber > 1 ? dayNumber - 1 : null;
const nextDay = dayNumber < 7 ? dayNumber + 1 : null;
const url = absoluteUrl(`/zh/day/${params.day}`);
const jsonLd = {
'@context': 'https://schema.org',
'@type': 'Article',
'@id': `${url}#article`,
headline: data.frontmatter.title,
description: data.frontmatter.description,
url,
inLanguage: getStructuredDataLanguage('zh'),
isPartOf: {
'@type': 'WebSite',
name: SITE_NAME,
url: SITE_URL,
},
author: {
'@type': 'Organization',
name: SITE_NAME,
url: SITE_URL,
},
dateModified: data.lastModified,
};
return (
<main className="min-h-screen bg-gradient-to-b from-gray-900 to-gray-950">
<DayContent
day={dayNum}
<script
type="application/ld+json"
dangerouslySetInnerHTML={{ __html: JSON.stringify(jsonLd) }}
/>
<DayContent
day={dayNumber}
content={data.content}
frontmatter={data.frontmatter}
prevDay={prevDay}
+134 -39
View File
@@ -1,56 +1,151 @@
import { Metadata } from 'next';
import type { Metadata } from 'next';
import HomePage from '@/components/HomePage';
import {
SITE_NAME,
SITE_URL,
buildPageMetadata,
getStructuredDataLanguage,
} from '@/lib/seo';
export const metadata: Metadata = {
export const metadata: Metadata = buildPageMetadata({
title: '7天掌握你的AI私人助理',
description: '从零开始,7天掌握你的AI私人助理。教程、技能和社区资源一站式获取。',
alternates: {
canonical: 'https://openclaw101.dev/zh',
languages: {
'en': 'https://openclaw101.dev',
'zh': 'https://openclaw101.dev/zh',
},
},
openGraph: {
title: 'OpenClaw 101 - 从零开始,7天掌握你的AI私人助理',
description: '从零开始,7天掌握你的AI私人助理',
type: 'website',
url: 'https://openclaw101.dev/zh',
siteName: 'OpenClaw 101',
images: [
{
url: '/og-image.png',
width: 1200,
height: 630,
alt: 'OpenClaw 101 - 从零开始,7天掌握你的AI私人助理',
},
],
},
twitter: {
card: 'summary_large_image',
title: 'OpenClaw 101 - 从零开始,7天掌握你的AI私人助理',
description: '从零开始,7天掌握你的AI私人助理',
images: ['/og-image.png'],
},
};
description:
'从零开始,7天掌握你的 OpenClaw AI 私人助理。包含安装、配置、技能、自动化与精选资源的一站式教程。',
locale: 'zh',
enPath: '/',
zhPath: '/zh',
});
const jsonLd = {
'@context': 'https://schema.org',
'@type': 'WebSite',
name: 'OpenClaw 101',
url: 'https://openclaw101.dev/zh',
description: '从零开始,7天掌握你的AI私人助理',
inLanguage: 'zh-CN',
'@graph': [
{
'@type': 'WebSite',
'@id': `${SITE_URL}/zh#website`,
url: `${SITE_URL}/zh`,
name: SITE_NAME,
description: '从零开始,7天掌握你的 AI 私人助理。',
inLanguage: getStructuredDataLanguage('zh'),
},
{
'@type': 'Course',
'@id': `${SITE_URL}/zh#course`,
url: `${SITE_URL}/zh`,
name: 'OpenClaw 7天教程',
description: '7天循序渐进学习 OpenClaw 的安装、配置、技能、接入与自动化。',
provider: {
'@type': 'Organization',
name: SITE_NAME,
url: SITE_URL,
},
hasCourseInstance: {
'@type': 'CourseInstance',
courseMode: 'online',
courseWorkload: 'P7D',
},
numberOfLessons: 7,
isAccessibleForFree: true,
availableLanguage: ['zh-CN', 'en'],
},
{
'@type': 'FAQPage',
'@id': `${SITE_URL}/zh#faq`,
mainEntity: [
{
'@type': 'Question',
name: 'OpenClaw 是什么?',
acceptedAnswer: {
'@type': 'Answer',
text: 'OpenClaw 是一个开源 AI Agent 框架,你可以把它部署到自己的电脑或服务器上,打造能聊天、调用工具、执行自动化任务的私人 AI 助手。',
},
},
{
'@type': 'Question',
name: 'OpenClaw 免费吗?',
acceptedAnswer: {
'@type': 'Answer',
text: 'OpenClaw 本身是开源免费的。你主要需要承担模型 API 调用费用,以及运行它的本地机器或云服务器成本。',
},
},
{
'@type': 'Question',
name: '这套教程适合新手吗?',
acceptedAnswer: {
'@type': 'Answer',
text: '适合。教程按 7 天拆解,从部署、配置到技能和自动化,尽量用最少术语带你一步步搭起来。',
},
},
{
'@type': 'Question',
name: 'OpenClaw 支持哪些模型?',
acceptedAnswer: {
'@type': 'Answer',
text: 'OpenClaw 支持 Claude、OpenAI、Google Gemini、xAI Grok,以及通过 OpenRouter 接入的其他模型。',
},
},
],
},
{
'@type': 'ItemList',
'@id': `${SITE_URL}/zh#tutorial-list`,
name: 'OpenClaw 7天学习路径',
numberOfItems: 7,
itemListElement: [
{
'@type': 'ListItem',
position: 1,
name: '第 1 天:初识 OpenClaw',
url: `${SITE_URL}/zh/day/1`,
},
{
'@type': 'ListItem',
position: 2,
name: '第 2 天:10 分钟,搭建你的助手',
url: `${SITE_URL}/zh/day/2`,
},
{
'@type': 'ListItem',
position: 3,
name: '第 3 天:给助手一个灵魂',
url: `${SITE_URL}/zh/day/3`,
},
{
'@type': 'ListItem',
position: 4,
name: '第 4 天:接入你的数字生活',
url: `${SITE_URL}/zh/day/4`,
},
{
'@type': 'ListItem',
position: 5,
name: '第 5 天:解锁技能树',
url: `${SITE_URL}/zh/day/5`,
},
{
'@type': 'ListItem',
position: 6,
name: '第 6 天:让助手主动工作',
url: `${SITE_URL}/zh/day/6`,
},
{
'@type': 'ListItem',
position: 7,
name: '第 7 天:进阶玩法 & 未来展望',
url: `${SITE_URL}/zh/day/7`,
},
],
},
],
};
export default function ZhHome() {
return (
<main>
<>
<script
type="application/ld+json"
dangerouslySetInnerHTML={{ __html: JSON.stringify(jsonLd) }}
/>
<HomePage locale="zh" />
</main>
</>
);
}
+22 -39
View File
@@ -1,50 +1,33 @@
import { Metadata } from 'next';
import type { Metadata } from 'next';
import ResourcesPage from '@/components/ResourcesPage';
import {
SITE_NAME,
SITE_URL,
buildPageMetadata,
getStructuredDataLanguage,
} from '@/lib/seo';
export const metadata: Metadata = {
title: '全网资源聚合',
description: '阿里云、腾讯云、DigitalOcean、B站、Codecademy、IBM……一站式获取 OpenClaw 最佳教程。',
alternates: {
canonical: 'https://openclaw101.dev/zh/resources',
languages: {
'en': 'https://openclaw101.dev/resources',
'zh': 'https://openclaw101.dev/zh/resources',
},
},
openGraph: {
title: '全网资源聚合',
description: '阿里云、腾讯云、DigitalOcean、B站、Codecademy、IBM……一站式获取 OpenClaw 最佳教程。',
type: 'website',
url: 'https://openclaw101.dev/zh/resources',
siteName: 'OpenClaw 101',
images: [
{
url: '/og-image.png',
width: 1200,
height: 630,
alt: '全网资源聚合 - OpenClaw 101',
},
],
},
twitter: {
card: 'summary_large_image',
title: '全网资源聚合',
description: '阿里云、腾讯云、DigitalOcean、B站、Codecademy、IBM……一站式获取 OpenClaw 最佳教程。',
images: ['/og-image.png'],
},
};
export const metadata: Metadata = buildPageMetadata({
title: '全网 OpenClaw 资源聚合',
description:
'汇总 35+ 篇 OpenClaw 精选教程、部署指南、视频和平台接入资源,覆盖阿里云、腾讯云、DigitalOcean、B 站、IBM、Codecademy 等来源。',
locale: 'zh',
enPath: '/resources',
zhPath: '/zh/resources',
});
const jsonLd = {
'@context': 'https://schema.org',
'@type': 'CollectionPage',
name: '全网资源聚合 - OpenClaw 101',
url: 'https://openclaw101.dev/zh/resources',
description: '阿里云、腾讯云、DigitalOcean、B站、Codecademy、IBM……一站式获取 OpenClaw 最佳教程。',
inLanguage: 'zh-CN',
'@id': `${SITE_URL}/zh/resources#collection`,
name: '全网 OpenClaw 资源聚合',
url: `${SITE_URL}/zh/resources`,
description: '一站式收录 OpenClaw 教程、部署指南、视频与接入资源。',
inLanguage: getStructuredDataLanguage('zh'),
isPartOf: {
'@type': 'WebSite',
name: 'OpenClaw 101',
url: 'https://openclaw101.dev',
name: SITE_NAME,
url: SITE_URL,
},
};
+2 -2
View File
@@ -33,7 +33,7 @@ const itemsZh = [
{
icon: '📦',
title: 'OpenClaw GitHub',
desc: 'OpenClaw 主仓库源码 (312k+ ⭐) 和社区贡献',
desc: 'OpenClaw 主仓库源码 (337k+ ⭐) 和社区贡献',
link: 'https://github.com/openclaw/openclaw',
color: 'hover:border-gray-400 hover:bg-gray-50',
},
@@ -78,7 +78,7 @@ const itemsEn = [
{
icon: '📦',
title: 'OpenClaw GitHub',
desc: 'OpenClaw main repo source code (312k+ ⭐) and community contributions',
desc: 'OpenClaw main repo source code (337k+ ⭐) and community contributions',
link: 'https://github.com/openclaw/openclaw',
color: 'hover:border-gray-400 hover:bg-gray-50',
},
+1 -11
View File
@@ -25,16 +25,6 @@ export default function DayContent({ day, content, frontmatter, prevDay, nextDay
setMounted(true);
}, []);
const titles: Record<number, { en: string; zh: string }> = {
1: { en: 'Getting Started with OpenClaw', zh: '初识 OpenClaw' },
2: { en: 'Deep Conversations', zh: '深入对话' },
3: { en: 'Files & Code', zh: '文件与代码' },
4: { en: 'Web Capabilities', zh: '网络能力' },
5: { en: 'Skill Extensions', zh: '技能扩展' },
6: { en: 'Automation', zh: '自动化' },
7: { en: 'Advanced Techniques', zh: '高级技巧' },
};
const t = locale === 'zh' ? {
day: '第',
dayUnit: '天',
@@ -87,7 +77,7 @@ export default function DayContent({ day, content, frontmatter, prevDay, nextDay
{locale === 'zh' ? `${t.day} ${day} ${t.dayUnit}` : `${t.day} ${day}`}
</span>
<h1 className="text-4xl md:text-5xl font-bold text-white mb-4">
{titles[day]?.[locale] || frontmatter.title}
{frontmatter.title}
</h1>
<p className="text-xl text-gray-400">
{frontmatter.description}
+1 -1
View File
@@ -21,7 +21,7 @@ export default function Footer({ locale, dict }: FooterProps) {
<ul className="space-y-1.5 sm:space-y-2 text-xs sm:text-sm" style={{ color: 'rgba(255,255,255,0.5)' }}>
<li><a href="https://openclaw.ai" target="_blank" rel="noopener noreferrer" className="hover:text-white transition-colors">{isZh ? 'OpenClaw 官网' : 'OpenClaw Website'}</a></li>
<li><a href="https://docs.openclaw.ai" target="_blank" rel="noopener noreferrer" className="hover:text-white transition-colors">{isZh ? '官方文档' : 'Documentation'}</a></li>
<li><a href="https://github.com/openclaw/openclaw" target="_blank" rel="noopener noreferrer" className="hover:text-white transition-colors">OpenClaw GitHub (312k+ )</a></li>
<li><a href="https://github.com/openclaw/openclaw" target="_blank" rel="noopener noreferrer" className="hover:text-white transition-colors">OpenClaw GitHub (337k+ )</a></li>
<li><a href="https://clawhub.com" target="_blank" rel="noopener noreferrer" className="hover:text-white transition-colors">{isZh ? 'ClawHub 技能市场' : 'ClawHub Skills'}</a></li>
</ul>
</div>
+2 -2
View File
@@ -94,7 +94,7 @@ export default function Hero({ locale, dict }: HeroProps) {
<div className="text-xs" style={{ color: 'rgba(255,255,255,0.4)' }}>{isZh ? '学习路径' : 'Learning Path'}</div>
</div>
<div className="text-center">
<div className="text-xl font-bold" style={{ color: '#fff' }}>312k+</div>
<div className="text-xl font-bold" style={{ color: '#fff' }}>337k+</div>
<div className="text-xs" style={{ color: 'rgba(255,255,255,0.4)' }}>OpenClaw Stars</div>
</div>
<div className="text-center">
@@ -116,7 +116,7 @@ export default function Hero({ locale, dict }: HeroProps) {
</div>
<div className="w-px h-8" style={{ background: 'rgba(255,255,255,0.1)' }} />
<div className="text-center">
<div className="text-2xl md:text-3xl font-bold" style={{ color: '#fff' }}>312k+</div>
<div className="text-2xl md:text-3xl font-bold" style={{ color: '#fff' }}>337k+</div>
<div className="text-xs" style={{ color: 'rgba(255,255,255,0.4)' }}>OpenClaw Stars</div>
</div>
<div className="w-px h-8" style={{ background: 'rgba(255,255,255,0.1)' }} />
+2 -2
View File
@@ -334,7 +334,7 @@ export default function Skills({ locale, dict }: SkillsProps) {
<div className="inline-flex items-center gap-2 px-4 py-2 bg-gradient-to-r from-primary/10 to-accent/10 rounded-full mb-4">
<span className="text-2xl">🚀</span>
<span className="text-sm font-semibold text-primary">
{isZh ? '5490+ 社区技能' : '5490+ Community Skills'}
{isZh ? '5400+ 社区技能' : '5400+ Community Skills'}
</span>
</div>
<h2 className="text-3xl md:text-4xl font-bold text-gray-900 mb-4">
@@ -391,7 +391,7 @@ export default function Skills({ locale, dict }: SkillsProps) {
<div className="reveal bg-gradient-to-r from-gray-50 to-gray-100 rounded-xl sm:rounded-2xl p-4 sm:p-6 mb-8">
<div className="grid grid-cols-2 gap-3 sm:gap-4 text-center">
<div className="bg-white/60 rounded-lg p-3 sm:p-4">
<div className="text-xl sm:text-3xl font-bold text-primary">5490+</div>
<div className="text-xl sm:text-3xl font-bold text-primary">5400+</div>
<div className="text-[10px] sm:text-sm text-gray-500">{isZh ? '总技能数' : 'Total Skills'}</div>
</div>
<div className="bg-white/60 rounded-lg p-3 sm:p-4">
+3 -3
View File
@@ -17,7 +17,7 @@ const featuresZh = [
{
icon: '⚡',
title: '技能扩展',
desc: '5490+ 社区技能,从天气查询到代码生成,一键安装即用。',
desc: '5400+ 社区技能,从天气查询到代码生成,一键安装即用。',
},
{
icon: '🔒',
@@ -35,7 +35,7 @@ const featuresEn = [
{
icon: '⚡',
title: 'Extensible Skills',
desc: '5490+ community skills, from weather queries to code generation. One-click install.',
desc: '5400+ community skills, from weather queries to code generation. One-click install.',
},
{
icon: '🔒',
@@ -114,7 +114,7 @@ export default function WhatIs({ locale, dict }: WhatIsProps) {
<svg className="w-5 h-5" fill="currentColor" viewBox="0 0 24 24">
<path d="M12 0c-6.626 0-12 5.373-12 12 0 5.302 3.438 9.8 8.207 11.387.599.111.793-.261.793-.577v-2.234c-3.338.726-4.033-1.416-4.033-1.416-.546-1.387-1.333-1.756-1.333-1.756-1.089-.745.083-.729.083-.729 1.205.084 1.839 1.237 1.839 1.237 1.07 1.834 2.807 1.304 3.492.997.107-.775.418-1.305.762-1.604-2.665-.305-5.467-1.334-5.467-5.931 0-1.311.469-2.381 1.236-3.221-.124-.303-.535-1.524.117-3.176 0 0 1.008-.322 3.301 1.23.957-.266 1.983-.399 3.003-.404 1.02.005 2.047.138 3.006.404 2.291-1.552 3.297-1.23 3.297-1.23.653 1.653.242 2.874.118 3.176.77.84 1.235 1.911 1.235 3.221 0 4.609-2.807 5.624-5.479 5.921.43.372.823 1.102.823 2.222v3.293c0 .319.192.694.801.576 4.765-1.589 8.199-6.086 8.199-11.386 0-6.627-5.373-12-12-12z" />
</svg>
<span className="font-semibold">312k+ OpenClaw Stars</span>
<span className="font-semibold">337k+ OpenClaw Stars</span>
<span className="text-white/60">{isZh ? '来自主仓库' : 'from the main repo'}</span>
</a>
</div>
+367 -1
View File
@@ -95,7 +95,7 @@ export const resources: Resource[] = [
},
{
title: 'GitHub — openclaw/openclaw',
desc: '源代码、Issue 跟踪和社区贡献指南 (312k+ ⭐)',
desc: '源代码、Issue 跟踪和社区贡献指南 (337k+ ⭐)',
url: 'https://github.com/openclaw/openclaw',
source: 'GitHub',
lang: 'en',
@@ -4291,6 +4291,372 @@ export const resources: Resource[] = [
category: 'getting-started',
tags: ['香港', '繁體中文', '粵語', '技能包', '大灣區'],
},
// ============ New — Week of 2026-03-16 ============
{
title: "OpenClaw Newsletter — 2026-03-14",
desc: "官方周刊:OpenClaw 超越 React 成为 GitHub Stars 第一项目,并汇总 Android 聊天设置改版、Homebrew 安装量与社区热点。",
url: "https://buttondown.com/openclaw-newsletter/archive/openclaw-newsletter-2026-03-14/",
source: "OpenClaw Newsletter",
lang: "en",
category: "official",
featured: true,
tags: ["官方周刊", "2026-03-14", "GitHub Stars", "社区动态"],
},
{
title: "How to Install OpenClaw (Moltbot/Clawdbot) on macOS, Windows, Linux, VPS, and Raspberry Pi",
desc: "全平台安装指南:覆盖 macOS、Linux、Windows WSL、DigitalOcean/Hetzner VPS 与树莓派,并附 Node.js、API Key、systemd 等前置要求。",
url: "https://anakin.ai/blog/how-to-install-openclaw-any-platform/",
source: "Anakin AI",
lang: "en",
category: "getting-started",
featured: true,
tags: ["全平台", "Windows WSL", "VPS", "Raspberry Pi"],
},
{
title: "阿里云百炼 — OpenClaw(原 Clawdbot、Moltbot)接入指南",
desc: "阿里云官方文档:通过百炼 OpenAI 兼容接口接入 OpenClaw,涵盖 Qwen/DeepSeek/Kimi 等模型、dashboard 配置和地域差异说明。",
url: "https://help.aliyun.com/zh/model-studio/openclaw",
source: "阿里云百炼",
lang: "zh",
category: "cloud-deploy",
featured: true,
tags: ["阿里云", "百炼", "Qwen", "模型配置"],
},
{
title: "B站 — 【Clawdbot/OpenClaw】超详细Windows下安全(基于WSL)安装指南",
desc: "Windows 安全部署视频:基于 WSL 跑通 OpenClaw,附本地 LLM / MiniMax 替换说明,适合想在 Windows 本机长期使用的用户。",
url: "https://www.bilibili.com/video/BV1SPFMzQErh/",
source: "Bilibili",
lang: "zh",
category: "video",
tags: ["B站", "Windows", "WSL", "安全部署"],
},
{
title: "B站 — 效率X10!我开源了一个 OpenClaw 的控制中心",
desc: "开源 OpenClaw 控制中心:集中查看多 Agent 状态、token 消耗、排队任务,以及每个 Agent 的人设、记忆和任务文档。",
url: "https://www.bilibili.com/video/BV1kDckzGEMm/",
source: "Bilibili",
lang: "zh",
category: "tools",
tags: ["B站", "控制中心", "多Agent", "可视化"],
},
// ============ New — Week of 2026-03-17 ============
{
title: 'GitHub Releases — OpenClaw v2026.3.13-1',
desc: '恢复版发布:修复 broken v2026.3.13 tag/release 路径,并汇总 live Chrome session attach 后续修复、Android chat settings 改版、OPENCLAW_TZ 时区支持等更新。',
url: 'https://github.com/openclaw/openclaw/releases/tag/v2026.3.13-1',
source: 'GitHub Releases',
lang: 'en',
category: 'official',
featured: true,
tags: ['v2026.3.13-1', '版本更新', 'Chrome attach', 'Android'],
},
{
title: 'OpenClaw Newsletter — 2026-03-16',
desc: '官方周刊:OpenClaw 超越 React 成为 GitHub Stars 第一软件项目;Ollama 成为官方 providerv2026.3.13 带来 live Chrome session attach 与 Android 聊天设置改版。',
url: 'https://buttondown.com/openclaw-newsletter/archive/openclaw-newsletter-2026-03-16/',
source: 'OpenClaw Newsletter',
lang: 'en',
category: 'official',
featured: true,
tags: ['官方周刊', '2026-03-16', 'Ollama', 'Chrome attach'],
},
{
title: 'B站 — OpenClaw小龙虾保姆级安装教程!【Mac电脑版】小白10分钟搞定本地部署',
desc: '最新中文视频教程:聚焦 Mac 本地部署,适合第一次在个人电脑上跑通 OpenClaw 的新手,配套讲解常见接入场景。',
url: 'https://www.bilibili.com/video/BV1t4Psz1EmW/',
source: 'Bilibili',
lang: 'zh',
category: 'video',
tags: ['B站', 'Mac', '本地部署', '新手'],
},
{
title: 'B站 — OpenClaw (龙虾) Windows 本地部署保姆级教程',
desc: 'Windows 本机部署完整指南:从环境准备到跑通 OpenClaw 的保姆级演示,适合希望长期在 Windows 环境使用 OpenClaw 的用户。',
url: 'https://www.bilibili.com/video/BV1jscdzqEa8/',
source: 'Bilibili',
lang: 'zh',
category: 'video',
tags: ['B站', 'Windows', '本地部署', '保姆级'],
},
{
title: 'B站 —【保姆级】OpenClaw 全网最细教学:安装→Skills实战→多Agent协作,1 小时全精通!',
desc: '覆盖安装、Skills 实战与多 Agent 协作的近期中文长视频,适合想一次性建立完整使用心智的进阶新手。',
url: 'https://www.bilibili.com/video/BV1TpAZzeEiZ/',
source: 'Bilibili',
lang: 'zh',
category: 'video',
tags: ['B站', 'Skills', '多Agent', '长视频'],
},
{
title: 'Next Platform — OpenClaw 是 agentic AI 的“GPT 时代”类比?',
desc: '行业观点文章,讨论 OpenClaw 对 AI-agent 基础设施的影响与发展路径,附带行业讨论与市场观察。',
url: 'https://www.nextplatform.com/ai/2026/03/17/nvidia-says-openclaw-is-to-agentic-ai-what-gpt-was-to-chattybots/5209428',
source: 'The Next Platform',
lang: 'en',
category: 'deep-dive',
featured: false,
tags: ['行业观点', 'agentic AI', '趋势观察'],
},
{
title: 'Reuters — 百度加入中国 OpenClaw 狂热浪潮',
desc: '路透社报道中国企业与厂商围绕 OpenClaw 的最新动态与本土化落地。',
url: 'https://www.reuters.com/business/media-telecom/baidu-joins-chinas-openclaw-frenzy-with-new-ai-agents-2026-03-17/',
source: 'Reuters',
lang: 'en',
category: 'deep-dive',
featured: false,
tags: ['行业资讯', '本土化', '企业动作'],
},
// ============ New — Week of 2026-03-20 ============
{
title: 'YouTube — The only OpenClaw tutorial you\'ll ever need (March 2026)',
desc: '近期英文长视频教程:从搭建第一个 AI 员工到完整工作流配置,适合想一次性补齐安装与使用心智的用户。',
url: 'https://www.youtube.com/watch?v=CxErCGVo-oo',
source: 'YouTube',
lang: 'en',
category: 'video',
featured: true,
tags: ['YouTube', '完整教程', 'March 2026', '最新'],
},
{
title: 'Substack — OpenClaw News for Mar. 18/26',
desc: '最新社区情报汇总:聚合 3 月 18 日前后的 OpenClaw 新闻、版本动态与生态观察,适合快速补齐最近一周信息。',
url: 'https://pau1.substack.com/p/openclaw-news-for-mar-1826',
source: 'Substack',
lang: 'en',
category: 'deep-dive',
tags: ['新闻汇总', '社区动态', 'March 2026', '最新'],
},
{
title: 'Substack — I Studied OpenClaw Memory System — Here\'s What I Found',
desc: '围绕 OpenClaw 记忆系统的最新分析:从长期记忆归属到上下文连续性,适合想深入理解 Memory 机制的用户。',
url: 'https://gaodalie.substack.com/p/i-studied-openclaw-memory-system',
source: 'Substack',
lang: 'en',
category: 'deep-dive',
tags: ['记忆系统', 'Memory', 'Substack', 'March 2026'],
},
// ============ New — Week of 2026-03-21 ============
{
title: "YouTube — Install & Run OpenClaw on Raspberry Pi 5 | Zero Cost Local AI | Offline AI",
desc: "最新树莓派 5 视频教程:在本地离线环境部署 OpenClaw,主打零 API 成本和低门槛硬件方案。",
url: "https://www.youtube.com/watch?v=P2-ZeB7O0nA",
source: "YouTube",
lang: 'en',
category: 'video',
tags: ["YouTube", "Raspberry Pi 5", "离线部署", "零成本", "2026-03"],
},
{
title: "The OpenClaw Saga: How Two Weeks Changed the Agentic AI World Forever",
desc: "长文复盘 OpenClaw 在 2026 年 2 月的爆发式演进:品牌更名、基金会过渡、生态扩张与安全争议。",
url: "https://thesingularitypoint.substack.com/p/the-openclaw-saga-how-two-weeks-changed",
source: "Substack",
lang: 'en',
category: 'deep-dive',
tags: ["Substack", "历史复盘", "生态演进", "安全争议", "2026-03"],
},
{
title: "B站 — OpenClaw 接入微信、QQ、飞书等教程!打造 24 小时在线 AI 助手!",
desc: "3 月最新中文视频教程:聚焦微信、QQ、飞书等国内平台接入,并演示 OpenClaw 的 24 小时在线助手玩法。",
url: "https://www.bilibili.com/video/BV1mcwtzVEnt/",
source: "Bilibili",
lang: 'zh',
category: 'video',
tags: ["B站", "微信", "QQ", "飞书", "国内平台", "2026-03"],
},
{
title: "B站 — OpenClaw 6 大必要配置推荐",
desc: "近期中文经验视频:总结安全、记忆、搜索、浏览器、Skills 与 Token 控制等 6 类高频配置建议。",
url: "https://www.bilibili.com/video/BV1G7PFz1E7x/",
source: "Bilibili",
lang: 'zh',
category: 'getting-started',
tags: ["B站", "配置优化", "安全", "Skills", "Token", "2026-03"],
},
// ============ New — Week of 2026-03-22 ============
{
title: 'Medium — OpenClaw: The Lobster That Took Over the AI World',
desc: '3 月新文回顾 OpenClaw 的爆发式增长,梳理其从 side project 到 GitHub 现象级项目的关键节点。',
url: 'https://thamizhelango.medium.com/openclaw-the-lobster-that-took-over-the-ai-world-7d901bc387bb',
source: 'Medium',
lang: 'en',
category: 'deep-dive',
tags: ['增长', 'Medium', '现象级', '2026-03'],
},
{
title: 'Substack — The Sequence Opinion #827: Taming the Agentic Lobster: Learning from OpenClaw',
desc: 'The Sequence 最新评论:从 Agent 基础设施视角复盘 OpenClaw 的崛起,并总结可供团队借鉴的产品与安全启示。',
url: 'https://thesequence.substack.com/p/the-sequence-opinion-827-taming-the',
source: 'The Sequence',
lang: 'en',
category: 'deep-dive',
tags: ['The Sequence', '行业评论', '安全启示', '2026-03'],
},
// ============ New — Week of 2026-03-24 ============
{
title: 'OpenClaw News for Mar. 22/26',
desc: '最新社区情报汇总:聚合最近一周 OpenClaw 新闻、版本动态与生态观察,适合快速补齐 March 下旬的更新。',
url: 'https://pau1.substack.com/p/openclaw-news-for-mar-2226',
source: 'Substack',
lang: 'en',
category: 'deep-dive',
tags: ['新闻汇总', '社区动态', 'March 2026', '最新'],
},
{
title: 'Deploy OpenClaw with GLM 5: Self-Hosted AI Agent in 10 Min',
desc: '最新英文实操:用 GLM-5 在 10 分钟内跑起自托管 OpenClaw,覆盖安装、模型接入与快速启动。',
url: 'https://michielh.medium.com/deploy-openclaw-with-glm-5-self-hosted-ai-agent-in-10-min-7f6a8ed985d4',
source: 'Medium',
lang: 'en',
category: 'getting-started',
tags: ['GLM-5', '10分钟', '自托管', '2026-03'],
},
{
title: 'YouTube — 微信养龙虾:OpenClaw 微信插件 Clawbot 发布',
desc: '近期中文视频教程:演示如何把 OpenClaw 接入微信,一条命令完成插件安装与配对,适合想把 AI 助手装进微信的用户。',
url: 'https://www.youtube.com/watch?v=KZKT27Gk9lA',
source: 'YouTube',
lang: 'zh',
category: 'channel-integration',
tags: ['微信', '插件', '中文教程', 'YouTube', '2026-03'],
},
// ============ New — Week of 2026-03-24 ============
{
title: 'GitHub Releases — OpenClaw v2026.3.22',
desc: '3 月最新正式版发布:ClawHub 安装优先级改为优先技能市场、移除旧版 Chrome extension relay 路径,并带来新的 Matrix 插件、插件 SDK 迁移与多项安全收紧。',
url: 'https://github.com/openclaw/openclaw/releases/tag/v2026.3.22',
source: 'GitHub Releases',
lang: 'en',
category: 'official',
featured: true,
tags: ['v2026.3.22', '版本更新', 'ClawHub', 'Matrix', 'Chrome MCP'],
},
{
title: 'OpenClaw Newsletter — 2026-03-24',
desc: '官方日报:汇总最新改名讨论、微信插件兼容性问题、v2026.3.23 / v2026.3.22 发版动态,以及插件超时保护与 WebChat 性能改进。',
url: 'https://buttondown.com/openclaw-newsletter/archive/openclaw-newsletter-2026-03-24/',
source: 'OpenClaw Newsletter',
lang: 'en',
category: 'official',
featured: true,
tags: ['官方周刊', '2026-03-24', '微信插件', 'v2026.3.23', 'WebChat'],
},
{
title: 'CNBC — OpenClaw 的“ChatGPT 时刻”引发模型商品化担忧',
desc: 'CNBC 3 月 21 日报道:OpenClaw 的爆发式增长让市场重新讨论底层模型是否会进一步商品化,以及 Agent 层的价值正在上移。',
url: 'https://www.cnbc.com/2026/03/21/openclaw-chatgpt-moment-sparks-concern-ai-models-becoming-commodities.html',
source: 'CNBC',
lang: 'en',
category: 'deep-dive',
featured: true,
tags: ['CNBC', '行业分析', '模型商品化', '2026-03'],
},
{
title: 'YouTube — OpenClaw v2026.3.22The Biggest Release Yet',
desc: '近期英文视频解读:聚焦 v2026.3.22 的 breaking changes、新功能、Bug 修复与安全加固,适合想快速掌握这次大版本变化的用户。',
url: 'https://www.youtube.com/watch?v=aAcWV5WcSXg',
source: 'YouTube',
lang: 'en',
category: 'video',
tags: ['YouTube', 'v2026.3.22', '版本解读', 'March 2026'],
},
{
title: 'B站 — [中配] 你唯一需要的 OpenClaw 教程(2026 年 3 月版)',
desc: '3 月较新的中文视频教程:从安装到工作流配置的完整 walkthrough,适合想一次补齐 OpenClaw 上手心智的中文用户。',
url: 'https://www.bilibili.com/video/BV1W3APzGEx5/',
source: 'Bilibili',
lang: 'zh',
category: 'video',
featured: true,
tags: ['B站', '中文教程', 'March 2026', '完整教程'],
},
// ============ New — Week of 2026-03-26 ============
{
title: 'The Biggest OpenClaw Update Just Dropped. Here Is Everything You Need to Know (March 2026)',
desc: '聚焦 v2026.3.22 的实战解读:ClawHub 成为默认技能市场、/btw 侧对话、子 Agent 模型与 thinking 调整、会话膨胀治理与 30+ 安全补丁。',
url: 'https://www.gauraw.com/openclaw-update-march-2026-clawhub-subagents-session-management/',
source: 'Gauraw',
lang: 'en',
category: 'deep-dive',
tags: ['v2026.3.22', 'ClawHub', '子Agent', '会话管理', 'March 2026'],
},
{
title: 'OpenClaw 2026.3.13 Release: Memory Fix, Chrome DevTools, and Mobile Redesign',
desc: '版本解读:回顾 v2026.3.13 的内存回归修复、Chrome DevTools attach、新版 Android 设计、Docker 时区支持与 Windows Gateway 修复。',
url: 'https://openclawdc.com/blog/openclaw-3-13-release/',
source: 'OpenClaw DC',
lang: 'en',
category: 'official',
tags: ['v2026.3.13', 'memory fix', 'Chrome DevTools', 'Android', 'Windows Gateway'],
},
{
title: 'Whats New in OpenClaw (March 2026): Reliability Features',
desc: '从生产可用性视角解读 3 月更新:增强 cron、allowlist-first 渠道安全、配置校验与 openclaw doctor 诊断路径,更适合长期自动化运行。',
url: 'https://atlaslionclaw.com/blog/openclaw-march-2026-updates/',
source: 'Atlas Lion Claw',
lang: 'en',
category: 'deep-dive',
tags: ['cron', 'reliability', 'allowlist', 'openclaw doctor', 'March 2026'],
},
// ============ New — Week of 2026-03-27 ============
{
title: "YouTube — OpenClaw Setup in 2026: The Only Guide You Need",
desc: "近一周内出现的英文新视频教程:覆盖安装 OpenClaw、连接模型 API Key、初始化工作区与 Dashboard,上手路径相对完整。",
url: "https://www.youtube.com/watch?v=9epvGKyHIek",
source: "YouTube",
lang: "en",
category: "video",
tags: ["YouTube", "setup", "March 2026", "完整教程"],
},
{
title: "Verdent — OpenClaw Setup Guide 2026: Install, Configure & Connect in 15 Min",
desc: "15 分钟上手指南:从 Node.js 22、API Key 到 provider 选择与多渠道连接,适合第一次部署 OpenClaw 的新用户。",
url: "https://www.verdent.ai/guides/openclaw-setup-guide-from-zero-to-ai-assistant",
source: "Verdent",
lang: "en",
category: "getting-started",
tags: ["快速上手", "安装指南", "provider", "2026-03"],
},
{
title: "Nimo PC — 2026 Guide: How to Install OpenClaw AI on Windows",
desc: "Windows 11 向导:聚焦 PowerShell 安装、Node.js / Git 前置依赖与本机环境准备,适合想在 Windows 侧跑通 OpenClaw 的用户。",
url: "https://www.nimopc.com/blogs/our-blog/2026-guide-how-to-install-openclaw-ai-on-windows",
source: "Nimo PC",
lang: "en",
category: "getting-started",
tags: ["Windows", "PowerShell", "安装指南", "2026-03"],
},
];
export function getResourcesByCategory(cat: ResourceCategory): Resource[] {
+54
View File
@@ -0,0 +1,54 @@
import fs from 'fs';
import path from 'path';
import matter from 'gray-matter';
import type { SiteLocale } from '@/lib/seo';
export const DAY_NUMBERS = [1, 2, 3, 4, 5, 6, 7] as const;
type DayNumber = (typeof DAY_NUMBERS)[number];
export interface DayFrontmatter {
title: string;
day: number;
description: string;
}
export interface DayContentEntry {
content: string;
frontmatter: DayFrontmatter;
filePath: string;
lastModified: string;
}
export function getDayStaticParams() {
return DAY_NUMBERS.map((day) => ({ day: day.toString() }));
}
export function getDayContent(locale: SiteLocale, day: string | number): DayContentEntry | null {
const dayNumber = Number(day);
if (!DAY_NUMBERS.includes(dayNumber as DayNumber)) {
return null;
}
const contentDir = locale === 'zh' ? 'days' : 'days-en';
const filePath = path.join(process.cwd(), 'content', contentDir, `day${dayNumber}.md`);
if (!fs.existsSync(filePath)) {
return null;
}
const fileContent = fs.readFileSync(filePath, 'utf8');
const { data, content } = matter(fileContent);
return {
content,
frontmatter: {
title: String(data.title ?? `Day ${dayNumber}`),
day: Number(data.day ?? dayNumber),
description: String(data.description ?? ''),
},
filePath,
lastModified: fs.statSync(filePath).mtime.toISOString(),
};
}
+129
View File
@@ -0,0 +1,129 @@
import type { Metadata } from 'next';
export type SiteLocale = 'en' | 'zh';
export const SITE_NAME = 'OpenClaw 101';
export const SITE_URL = 'https://openclaw101.dev';
export const DEFAULT_OG_IMAGE = `${SITE_URL}/og-image.png`;
export const DEFAULT_SITE_DESCRIPTION =
'Free 7-day tutorial to master OpenClaw (Clawdbot/Moltbot). Learn to build your own AI personal assistant with installation guides, curated resources, automation tips, and step-by-step workflows.';
export const SITE_KEYWORDS = [
'OpenClaw',
'OpenClaw tutorial',
'OpenClaw guide',
'OpenClaw 教程',
'Clawdbot',
'Moltbot',
'AI assistant',
'AI Agent',
'personal AI',
'Telegram bot',
'self-hosted AI',
'open source AI',
'AI automation',
'OpenClaw skills',
'OpenClaw installation',
'OpenClaw setup',
'7 day AI tutorial',
'AI助理',
'AI私人助手',
'开源AI',
];
const localeConfig: Record<
SiteLocale,
{ ogLocale: string; alternateOgLocale: string; languageCode: string }
> = {
en: {
ogLocale: 'en_US',
alternateOgLocale: 'zh_CN',
languageCode: 'en',
},
zh: {
ogLocale: 'zh_CN',
alternateOgLocale: 'en_US',
languageCode: 'zh-CN',
},
};
function normalizePath(pathname: string): string {
if (!pathname || pathname === '/') {
return '/';
}
return pathname.startsWith('/') ? pathname : `/${pathname}`;
}
export function absoluteUrl(pathname: string = '/'): string {
const normalizedPath = normalizePath(pathname);
return new URL(normalizedPath, SITE_URL).toString();
}
export function getAlternateLanguageLinks(enPath: string, zhPath: string) {
return {
en: absoluteUrl(enPath),
'zh-CN': absoluteUrl(zhPath),
'x-default': absoluteUrl(enPath),
};
}
interface PageMetadataOptions {
title: string;
description: string;
locale: SiteLocale;
enPath: string;
zhPath: string;
type?: 'website' | 'article';
}
export function buildPageMetadata({
title,
description,
locale,
enPath,
zhPath,
type = 'website',
}: PageMetadataOptions): Metadata {
const canonicalPath = locale === 'zh' ? zhPath : enPath;
const fullTitle = `${title} | ${SITE_NAME}`;
const { ogLocale, alternateOgLocale } = localeConfig[locale];
return {
title: {
absolute: fullTitle,
},
description,
alternates: {
canonical: absoluteUrl(canonicalPath),
languages: getAlternateLanguageLinks(enPath, zhPath),
},
openGraph: {
title: fullTitle,
description,
url: absoluteUrl(canonicalPath),
siteName: SITE_NAME,
images: [
{
url: DEFAULT_OG_IMAGE,
width: 1200,
height: 630,
alt: fullTitle,
},
],
locale: ogLocale,
alternateLocale: [alternateOgLocale],
type,
},
twitter: {
card: 'summary_large_image',
title: fullTitle,
description,
images: [DEFAULT_OG_IMAGE],
},
};
}
export function getStructuredDataLanguage(locale: SiteLocale): string {
return localeConfig[locale].languageCode;
}