openclaw101-resource-platform

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

OpenClaw 101 Resource Platform Skill

OpenClaw 101资源平台Skill

Skill by ara.so — Hermes Skills collection.
ara.so开发的Skill —— Hermes Skills合集。

What is OpenClaw 101?

什么是OpenClaw 101?

OpenClaw 101 is an open-source resource aggregation platform built with Next.js 14 and TypeScript. It serves as a comprehensive Chinese-language guide for OpenClaw, collecting 35+ tutorials from platforms like Alibaba Cloud, Tencent Cloud, DigitalOcean, and Bilibili. The platform features:
  • Resource aggregation with search and filtering
  • 7-day learning path (linked to Feishu knowledge base)
  • AI skill recommendations by use case
  • Bilingual support (Chinese and English)
  • Category-based organization and tagging system
OpenClaw 101是一个基于Next.js 14和TypeScript构建的开源资源聚合平台,作为OpenClaw的全面中文指南,收集了来自阿里云、腾讯云、DigitalOcean、B站等平台的35+篇教程。该平台具备以下特性:
  • 支持搜索与筛选的资源聚合功能
  • 关联飞书知识库的7天学习路径
  • 基于使用场景的AI Skill推荐
  • 双语支持(中文和英文)
  • 基于分类的组织与标签系统

Installation & Setup

安装与设置

bash
undefined
bash
undefined

Clone the repository

Clone the repository

Install dependencies

Install dependencies

npm install
npm install

Start development server

Start development server

npm run dev

Access at `http://localhost:3000`
npm run dev

访问地址:`http://localhost:3000`

Build & Deploy

构建与部署

bash
undefined
bash
undefined

Production build

Production build

npm run build
npm run build

Start production server

Start production server

npm start
npm start

Deploy to Cloudflare Pages

Deploy to Cloudflare Pages

(Typically automated via Git integration)

(Typically automated via Git integration)

npm run build
undefined
npm run build
undefined

Project Structure

项目结构

src/
├── app/
│   ├── page.tsx                    # Homepage
│   ├── resources/page.tsx          # Resources listing page
│   ├── layout.tsx                  # Root layout
│   └── globals.css                 # Global styles
├── components/
│   ├── Hero.tsx                    # Hero section
│   ├── WhatIs.tsx                  # Introduction section
│   ├── LearningPath.tsx            # 7-day learning path
│   ├── Skills.tsx                  # Skill recommendations
│   ├── ResourcesSection.tsx        # Featured resources
│   ├── Community.tsx               # Community section
│   ├── Navbar.tsx                  # Navigation
│   └── Footer.tsx                  # Footer
└── data/
    └── resources.ts                # Resource database
src/
├── app/
│   ├── page.tsx                    # 首页
│   ├── resources/page.tsx          # 资源列表页
│   ├── layout.tsx                  # 根布局
│   └── globals.css                 # 全局样式
├── components/
│   ├── Hero.tsx                    # Hero区域
│   ├── WhatIs.tsx                  # 介绍区域
│   ├── LearningPath.tsx            # 7天学习路径
│   ├── Skills.tsx                  # Skill推荐
│   ├── ResourcesSection.tsx        # 精选资源
│   ├── Community.tsx               # 社区区域
│   ├── Navbar.tsx                  # 导航栏
│   └── Footer.tsx                  # 页脚
└── data/
    └── resources.ts                # 资源数据库

Adding New Resources

添加新资源

The core of the platform is the resource database in
src/data/resources.ts
:
typescript
// src/data/resources.ts
export interface Resource {
  title: string;
  desc: string;
  url: string;
  source: string;
  lang: 'zh' | 'en';
  category: 'official' | 'getting-started' | 'channel-integration' | 
            'skill-dev' | 'video' | 'deep-dive' | 'tools' | 'cloud-deploy';
  featured?: boolean;
  tags?: string[];
}

export const resources: Resource[] = [
  {
    title: 'OpenClaw 飞书接入完整指南',
    desc: '详细介绍如何将 OpenClaw 接入飞书平台的步骤',
    url: 'https://cloud.tencent.com/developer/article/2505478',
    source: '腾讯云',
    lang: 'zh',
    category: 'channel-integration',
    featured: true,
    tags: ['飞书', 'Lark', '接入'],
  },
  {
    title: 'Deploy OpenClaw on DigitalOcean',
    desc: 'One-click deployment guide for DigitalOcean platform',
    url: 'https://www.digitalocean.com/community/tutorials/how-to-deploy-openclaw',
    source: 'DigitalOcean',
    lang: 'en',
    category: 'cloud-deploy',
    featured: false,
    tags: ['deployment', 'cloud', 'VPS'],
  },
  // Add more resources...
];
平台核心是
src/data/resources.ts
中的资源数据库:
typescript
// src/data/resources.ts
export interface Resource {
  title: string;
  desc: string;
  url: string;
  source: string;
  lang: 'zh' | 'en';
  category: 'official' | 'getting-started' | 'channel-integration' | 
            'skill-dev' | 'video' | 'deep-dive' | 'tools' | 'cloud-deploy';
  featured?: boolean;
  tags?: string[];
}

export const resources: Resource[] = [
  {
    title: 'OpenClaw 飞书接入完整指南',
    desc: '详细介绍如何将 OpenClaw 接入飞书平台的步骤',
    url: 'https://cloud.tencent.com/developer/article/2505478',
    source: '腾讯云',
    lang: 'zh',
    category: 'channel-integration',
    featured: true,
    tags: ['飞书', 'Lark', '接入'],
  },
  {
    title: 'Deploy OpenClaw on DigitalOcean',
    desc: 'One-click deployment guide for DigitalOcean platform',
    url: 'https://www.digitalocean.com/community/tutorials/how-to-deploy-openclaw',
    source: 'DigitalOcean',
    lang: 'en',
    category: 'cloud-deploy',
    featured: false,
    tags: ['deployment', 'cloud', 'VPS'],
  },
  // 添加更多资源...
];

Resource Categories

资源分类

CategoryDescription
official
Official OpenClaw documentation
getting-started
Installation and deployment tutorials
channel-integration
Platform integrations (Feishu, DingTalk, Telegram)
skill-dev
AI skill development guides
video
Video tutorials
deep-dive
In-depth analysis articles
tools
Tools and plugins
cloud-deploy
Cloud platform deployment guides
分类描述
official
OpenClaw官方文档
getting-started
安装与部署教程
channel-integration
平台集成(飞书、钉钉、Telegram)
skill-dev
AI Skill开发指南
video
视频教程
deep-dive
深度分析文章
tools
工具与插件
cloud-deploy
云平台部署指南

Component Development Patterns

组件开发模式

Creating a New Component

创建新组件

typescript
// src/components/NewSection.tsx
import React from 'react';

export default function NewSection() {
  return (
    <section className="py-20 px-4">
      <div className="max-w-6xl mx-auto">
        <h2 className="text-3xl md:text-4xl font-bold text-center mb-12">
          Section Title
        </h2>
        <div className="grid md:grid-cols-2 lg:grid-cols-3 gap-6">
          {/* Content grid */}
        </div>
      </div>
    </section>
  );
}
typescript
// src/components/NewSection.tsx
import React from 'react';

export default function NewSection() {
  return (
    <section className="py-20 px-4">
      <div className="max-w-6xl mx-auto">
        <h2 className="text-3xl md:text-4xl font-bold text-center mb-12">
          区域标题
        </h2>
        <div className="grid md:grid-cols-2 lg:grid-cols-3 gap-6">
          {/* 内容网格 */}
        </div>
      </div>
    </section>
  );
}

Using Resources Data

使用资源数据

typescript
// Example: Filtering resources in a component
import { resources } from '@/data/resources';

export default function FeaturedResources() {
  const featured = resources.filter(r => r.featured);
  const chineseResources = resources.filter(r => r.lang === 'zh');
  const videoTutorials = resources.filter(r => r.category === 'video');

  return (
    <div>
      {featured.map((resource, idx) => (
        <div key={idx} className="border rounded-lg p-4 hover:shadow-lg transition">
          <h3 className="font-bold text-lg mb-2">{resource.title}</h3>
          <p className="text-gray-600 mb-3">{resource.desc}</p>
          <div className="flex items-center justify-between">
            <span className="text-sm text-gray-500">{resource.source}</span>
            <a 
              href={resource.url} 
              target="_blank" 
              rel="noopener noreferrer"
              className="text-blue-600 hover:underline"
            >
              阅读 →
            </a>
          </div>
        </div>
      ))}
    </div>
  );
}
typescript
// 示例:在组件中筛选资源
import { resources } from '@/data/resources';

export default function FeaturedResources() {
  const featured = resources.filter(r => r.featured);
  const chineseResources = resources.filter(r => r.lang === 'zh');
  const videoTutorials = resources.filter(r => r.category === 'video');

  return (
    <div>
      {featured.map((resource, idx) => (
        <div key={idx} className="border rounded-lg p-4 hover:shadow-lg transition">
          <h3 className="font-bold text-lg mb-2">{resource.title}</h3>
          <p className="text-gray-600 mb-3">{resource.desc}</p>
          <div className="flex items-center justify-between">
            <span className="text-sm text-gray-500">{resource.source}</span>
            <a 
              href={resource.url} 
              target="_blank" 
              rel="noopener noreferrer"
              className="text-blue-600 hover:underline"
            >
              阅读 →
            </a>
          </div>
        </div>
      ))}
    </div>
  );
}

Resources Page Implementation

资源页实现

The resources page includes search and filtering:
typescript
// src/app/resources/page.tsx
'use client';

import { useState, useMemo } from 'react';
import { resources } from '@/data/resources';

export default function ResourcesPage() {
  const [search, setSearch] = useState('');
  const [langFilter, setLangFilter] = useState<'all' | 'zh' | 'en'>('all');
  const [categoryFilter, setCategoryFilter] = useState<string>('all');

  const filtered = useMemo(() => {
    return resources.filter(r => {
      const matchesSearch = r.title.toLowerCase().includes(search.toLowerCase()) ||
                           r.desc.toLowerCase().includes(search.toLowerCase());
      const matchesLang = langFilter === 'all' || r.lang === langFilter;
      const matchesCategory = categoryFilter === 'all' || r.category === categoryFilter;
      
      return matchesSearch && matchesLang && matchesCategory;
    });
  }, [search, langFilter, categoryFilter]);

  return (
    <div className="max-w-7xl mx-auto px-4 py-12">
      <h1 className="text-4xl font-bold mb-8">资源库</h1>
      
      {/* Filters */}
      <div className="mb-8 flex flex-wrap gap-4">
        <input
          type="text"
          placeholder="搜索资源..."
          value={search}
          onChange={(e) => setSearch(e.target.value)}
          className="px-4 py-2 border rounded-lg flex-1 min-w-[200px]"
        />
        
        <select 
          value={langFilter} 
          onChange={(e) => setLangFilter(e.target.value as any)}
          className="px-4 py-2 border rounded-lg"
        >
          <option value="all">全部语言</option>
          <option value="zh">中文</option>
          <option value="en">English</option>
        </select>
        
        <select 
          value={categoryFilter} 
          onChange={(e) => setCategoryFilter(e.target.value)}
          className="px-4 py-2 border rounded-lg"
        >
          <option value="all">全部分类</option>
          <option value="getting-started">入门部署</option>
          <option value="channel-integration">平台接入</option>
          <option value="skill-dev">技能开发</option>
          {/* More categories */}
        </select>
      </div>

      {/* Results */}
      <div className="grid md:grid-cols-2 lg:grid-cols-3 gap-6">
        {filtered.map((resource, idx) => (
          <ResourceCard key={idx} resource={resource} />
        ))}
      </div>
    </div>
  );
}
资源页包含搜索与筛选功能:
typescript
// src/app/resources/page.tsx
'use client';

import { useState, useMemo } from 'react';
import { resources } from '@/data/resources';

export default function ResourcesPage() {
  const [search, setSearch] = useState('');
  const [langFilter, setLangFilter] = useState<'all' | 'zh' | 'en'>('all');
  const [categoryFilter, setCategoryFilter] = useState<string>('all');

  const filtered = useMemo(() => {
    return resources.filter(r => {
      const matchesSearch = r.title.toLowerCase().includes(search.toLowerCase()) ||
                           r.desc.toLowerCase().includes(search.toLowerCase());
      const matchesLang = langFilter === 'all' || r.lang === langFilter;
      const matchesCategory = categoryFilter === 'all' || r.category === categoryFilter;
      
      return matchesSearch && matchesLang && matchesCategory;
    });
  }, [search, langFilter, categoryFilter]);

  return (
    <div className="max-w-7xl mx-auto px-4 py-12">
      <h1 className="text-4xl font-bold mb-8">资源库</h1>
      
      {/* 筛选器 */}
      <div className="mb-8 flex flex-wrap gap-4">
        <input
          type="text"
          placeholder="搜索资源..."
          value={search}
          onChange={(e) => setSearch(e.target.value)}
          className="px-4 py-2 border rounded-lg flex-1 min-w-[200px]"
        />
        
        <select 
          value={langFilter} 
          onChange={(e) => setLangFilter(e.target.value as any)}
          className="px-4 py-2 border rounded-lg"
        >
          <option value="all">全部语言</option>
          <option value="zh">中文</option>
          <option value="en">English</option>
        </select>
        
        <select 
          value={categoryFilter} 
          onChange={(e) => setCategoryFilter(e.target.value)}
          className="px-4 py-2 border rounded-lg"
        >
          <option value="all">全部分类</option>
          <option value="getting-started">入门部署</option>
          <option value="channel-integration">平台接入</option>
          <option value="skill-dev">技能开发</option>
          {/* 更多分类 */}
        </select>
      </div>

      {/* 结果列表 */}
      <div className="grid md:grid-cols-2 lg:grid-cols-3 gap-6">
        {filtered.map((resource, idx) => (
          <ResourceCard key={idx} resource={resource} />
        ))}
      </div>
    </div>
  );
}

Styling with Tailwind CSS

使用Tailwind CSS进行样式设计

Common utility patterns used in the project:
typescript
// Container pattern
<div className="max-w-6xl mx-auto px-4">

// Responsive grid
<div className="grid md:grid-cols-2 lg:grid-cols-3 gap-6">

// Card with hover effect
<div className="border rounded-lg p-6 hover:shadow-lg transition-shadow">

// Button styles
<button className="px-6 py-3 bg-blue-600 text-white rounded-lg hover:bg-blue-700 transition">

// Text gradients
<h1 className="text-4xl font-bold bg-gradient-to-r from-blue-600 to-purple-600 bg-clip-text text-transparent">
项目中常用的工具类模式:
typescript
// 容器模式
<div className="max-w-6xl mx-auto px-4">

// 响应式网格
<div className="grid md:grid-cols-2 lg:grid-cols-3 gap-6">

// 带悬停效果的卡片
<div className="border rounded-lg p-6 hover:shadow-lg transition-shadow">

// 按钮样式
<button className="px-6 py-3 bg-blue-600 text-white rounded-lg hover:bg-blue-700 transition">

// 文字渐变效果
<h1 className="text-4xl font-bold bg-gradient-to-r from-blue-600 to-purple-600 bg-clip-text text-transparent">

Configuration

配置

Next.js Configuration

Next.js配置

javascript
// next.config.js
/** @type {import('next').NextConfig} */
const nextConfig = {
  output: 'export', // For static export to Cloudflare Pages
  images: {
    unoptimized: true, // Required for static export
  },
};

module.exports = nextConfig;
javascript
// next.config.js
/** @type {import('next').NextConfig} */
const nextConfig = {
  output: 'export', // 用于静态导出至Cloudflare Pages
  images: {
    unoptimized: true, // 静态导出时必填
  },
};

module.exports = nextConfig;

Tailwind Configuration

Tailwind配置

javascript
// tailwind.config.ts
import type { Config } from 'tailwindcss';

const config: Config = {
  content: [
    './src/pages/**/*.{js,ts,jsx,tsx,mdx}',
    './src/components/**/*.{js,ts,jsx,tsx,mdx}',
    './src/app/**/*.{js,ts,jsx,tsx,mdx}',
  ],
  theme: {
    extend: {
      // Custom theme extensions
    },
  },
  plugins: [],
};

export default config;
javascript
// tailwind.config.ts
import type { Config } from 'tailwindcss';

const config: Config = {
  content: [
    './src/pages/**/*.{js,ts,jsx,tsx,mdx}',
    './src/components/**/*.{js,ts,jsx,tsx,mdx}',
    './src/app/**/*.{js,ts,jsx,tsx,mdx}',
  ],
  theme: {
    extend: {
      // 自定义主题扩展
    },
  },
  plugins: [],
};

export default config;

Common Patterns

常见模式

Adding a New Learning Path Item

添加新学习路径项

typescript
// In src/components/LearningPath.tsx
const pathItems = [
  {
    day: 1,
    title: '认识 OpenClaw',
    desc: '了解基本概念、架构和使用场景',
  },
  {
    day: 2,
    title: '快速部署',
    desc: '选择云平台,完成首次部署',
  },
  // Add more days...
];
typescript
// 在src/components/LearningPath.tsx中
const pathItems = [
  {
    day: 1,
    title: '认识 OpenClaw',
    desc: '了解基本概念、架构和使用场景',
  },
  {
    day: 2,
    title: '快速部署',
    desc: '选择云平台,完成首次部署',
  },
  // 添加更多天数...
];

Adding Skill Recommendations

添加Skill推荐

typescript
// In src/components/Skills.tsx
const skills = [
  {
    icon: '💬',
    title: 'Chat Integration',
    desc: '接入微信、飞书、Telegram 等聊天平台',
    tags: ['WeChat', 'Feishu', 'Telegram'],
  },
  {
    icon: '🤖',
    title: 'Custom AI Skills',
    desc: '开发专属的 AI 助手技能',
    tags: ['Python', 'JavaScript', 'API'],
  },
  // Add more skills...
];
typescript
// 在src/components/Skills.tsx中
const skills = [
  {
    icon: '💬',
    title: 'Chat Integration',
    desc: '接入微信、飞书、Telegram 等聊天平台',
    tags: ['WeChat', 'Feishu', 'Telegram'],
  },
  {
    icon: '🤖',
    title: 'Custom AI Skills',
    desc: '开发专属的 AI 助手技能',
    tags: ['Python', 'JavaScript', 'API'],
  },
  // 添加更多Skill...
];

Creating External Links

创建外部链接

typescript
// Safe external link pattern
<a 
  href={resource.url}
  target="_blank"
  rel="noopener noreferrer"
  className="text-blue-600 hover:underline"
>
  {resource.title}
</a>
typescript
// 安全外部链接模式
<a 
  href={resource.url}
  target="_blank"
  rel="noopener noreferrer"
  className="text-blue-600 hover:underline"
>
  {resource.title}
</a>

Troubleshooting

故障排查

Build Errors

构建错误

Issue:
Type error: Property does not exist on type
Solution: Ensure resource types match the interface:
typescript
// Check src/data/resources.ts
const newResource: Resource = {
  title: string,
  desc: string,
  url: string,
  source: string,
  lang: 'zh' | 'en',
  category: /* valid category */,
  // Optional fields
  featured: boolean,
  tags: string[],
};
问题
Type error: Property does not exist on type
解决方案:确保资源类型与接口匹配:
typescript
// 检查src/data/resources.ts
const newResource: Resource = {
  title: string,
  desc: string,
  url: string,
  source: string,
  lang: 'zh' | 'en',
  category: /* 有效分类 */,
  // 可选字段
  featured: boolean,
  tags: string[],
};

Deployment Issues

部署问题

Issue: Static export fails with image optimization
Solution: Set
images.unoptimized: true
in
next.config.js
Issue: 404 on client-side navigation
Solution: Ensure proper routing in
app/
directory structure
问题:静态导出因图片优化失败
解决方案:在
next.config.js
中设置
images.unoptimized: true
问题:客户端导航出现404
解决方案:确保
app/
目录结构中的路由配置正确

Development Server Issues

开发服务器问题

Issue: Changes not reflecting
Solution:
bash
undefined
问题:修改内容未生效
解决方案
bash
undefined

Clear Next.js cache

清除Next.js缓存

rm -rf .next npm run dev
undefined
rm -rf .next npm run dev
undefined

Testing Locally

本地测试

bash
undefined
bash
undefined

Development mode

开发模式

npm run dev
npm run dev

Production build test

生产构建测试

npm run build npm start
npm run build npm start

Type checking

类型检查

npx tsc --noEmit
npx tsc --noEmit

Lint

代码检查

npm run lint
undefined
npm run lint
undefined

Contributing Workflow

贡献流程

  1. Fork the repository
  2. Create a feature branch:
    git checkout -b feature/new-resources
  3. Add resources to
    src/data/resources.ts
  4. Test locally:
    npm run dev
  5. Commit changes:
    git commit -m "Add 5 new OpenClaw tutorials"
  6. Push and create PR
  1. Fork仓库
  2. 创建功能分支:
    git checkout -b feature/new-resources
  3. src/data/resources.ts
    中添加资源
  4. 本地测试:
    npm run dev
  5. 提交更改:
    git commit -m "Add 5 new OpenClaw tutorials"
  6. 推送并创建PR

Key Files to Modify

主要修改文件

  • Add resources:
    src/data/resources.ts
  • Edit homepage:
    src/app/page.tsx
  • Edit resources page:
    src/app/resources/page.tsx
  • Add components:
    src/components/
  • Global styles:
    src/app/globals.css
  • Site metadata:
    src/app/layout.tsx
  • 添加资源
    src/data/resources.ts
  • 编辑首页
    src/app/page.tsx
  • 编辑资源页
    src/app/resources/page.tsx
  • 添加组件
    src/components/
  • 全局样式
    src/app/globals.css
  • 站点元数据
    src/app/layout.tsx