github-trending-website
Next.js 15 GitHub Trending platform with Supabase backend - codebase analysis and API reference
Codex または Claude でインストール この Prompt をコピーして Codex、Claude、または他のアシスタントに貼り付けると、Skill ページを確認してインストールできます。
メニュー
Next.js 15 GitHub Trending platform with Supabase backend - codebase analysis and API reference
Codex または Claude でインストール この Prompt をコピーして Codex、Claude、または他のアシスタントに貼り付けると、Skill ページを確認してインストールできます。
SOC 職業分類に基づく
Local codebase analysis for github-trending-website
Use when searching this project's GitHub Trending export for AI memory, agent memory, long-term memory, persistent context, Claude Code memory plugins, or related repository clusters; generates/improves multilingual keywords, appends them to scripts/search_list.txt, runs scripts/search_novels.py, and summarizes matches by language.
Use when the user asks to inspect, summarize, compare, or report this project's GitHub Trending data from Supabase, especially for daily, weekly, or monthly rankings, repo overviews, stars, created dates, pushed dates, hot themes, or product inspiration.
| name | github-trending-website |
| description | Next.js 15 GitHub Trending platform with Supabase backend - codebase analysis and API reference |
| doc_version | 1 |
A comprehensive Next.js 15 + React 19 application that displays GitHub trending repositories with Chinese localization. This skill provides deep codebase analysis, API documentation, and real-world implementation patterns extracted from 42 TypeScript files.
Project Path: D:\github\2015\08\github-trending-website
Tech Stack: Next.js 15, React 19, TypeScript, Tailwind CSS 4, Supabase (PostgreSQL)
Deployment: Cloudflare Pages + Workers (OpenNext.js)
Files Analyzed: 42 TypeScript files
Analysis Depth: Deep (C2.5-C3.9)
Use this skill when you need to:
From codebase analysis - real implementation
// Client-side Supabase instance
import { createClient } from '@supabase/supabase-js'
const supabase = createClient(
process.env.NEXT_PUBLIC_SUPABASE_URL!,
process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY!
)
// Server-side admin instance (API routes)
const supabaseAdmin = createClient(
process.env.NEXT_PUBLIC_SUPABASE_URL!,
process.env.SUPABASE_SERVICE_ROLE_KEY!
)
From api/trending/route.ts - production code
export async function GET(request: NextRequest) {
const searchParams = request.nextUrl.searchParams
const date = searchParams.get('date')
const category = searchParams.get('category') || 'all'
const period = searchParams.get('period') || 'daily'
const { data, error } = await supabaseAdmin
.rpc('get_trending_repos', {
p_date: date,
p_category: category,
p_period: period
})
if (error) {
return NextResponse.json({ error: error.message }, { status: 500 })
}
return NextResponse.json(data)
}
From components/RepoCard.tsx - real component
interface RepoCardProps {
repo: TrendingRepo
showRank?: boolean
}
export function RepoCard({ repo, showRank = true }: RepoCardProps) {
return (
<div className="border rounded-lg p-4 hover:shadow-lg transition">
{showRank && <span className="text-2xl font-bold">#{repo.rank}</span>}
<h3 className="text-xl font-semibold">{repo.name}</h3>
<p className="text-gray-600">{repo.description_cn || repo.description}</p>
<div className="flex gap-4 mt-2">
<span>⭐ {formatNumber(repo.stars)}</span>
<span>🔥 {repo.stars_today} today</span>
</div>
</div>
)
}
From scripts/import-data.ts - production script
// Parse stars with k/K suffix
function parseStarsNumber(starsStr: string): number {
if (starsStr.toLowerCase().includes('k')) {
return Math.round(parseFloat(starsStr) * 1000)
}
return parseInt(starsStr.replace(/,/g, ''))
}
// Upsert repository data
async function upsertRepository(repoData: {
name: string
url: string
description: string
}) {
const { data, error } = await supabaseAdmin
.from('repositories')
.upsert(repoData, { onConflict: 'url' })
.select()
.single()
return data
}
From components/LanguageTabs.tsx - real component
interface LanguageTabsProps {
currentCategory: string
onCategoryChange: (category: string) => void
languageStats: LanguageStats[]
}
export function LanguageTabs({
currentCategory,
onCategoryChange,
languageStats = []
}: LanguageTabsProps) {
return (
<div className="flex gap-2 overflow-x-auto">
{languageStats.map(stat => (
<button
key={stat.language}
onClick={() => onCategoryChange(stat.language)}
className={`px-4 py-2 rounded ${
currentCategory === stat.language
? 'bg-blue-500 text-white'
: 'bg-gray-200'
}`}
>
{stat.language} ({stat.count})
</button>
))}
</div>
)
}
From API routes - production pattern
// Using Supabase RPC for complex queries
const { data: repos } = await supabaseAdmin.rpc('get_trending_repos', {
p_date: '2024-01-15',
p_category: 'python',
p_period: 'daily',
p_limit: 25,
p_offset: 0
})
// Get language statistics
const { data: stats } = await supabaseAdmin.rpc('get_language_stats', {
p_date: '2024-01-15',
p_period: 'weekly'
})
From components/SearchComponent.tsx - real implementation
interface SearchComponentProps {
onSearch: (params: SearchParams) => void
isLoading: boolean
currentCategory: string
currentPeriod: string
}
export function SearchComponent({
onSearch,
isLoading,
currentCategory,
currentPeriod
}: SearchComponentProps) {
const [query, setQuery] = useState('')
const handleSubmit = (e: React.FormEvent) => {
e.preventDefault()
onSearch({
query,
category: currentCategory,
period: currentPeriod
})
}
return (
<form onSubmit={handleSubmit} className="flex gap-2">
<input
type="text"
value={query}
onChange={(e) => setQuery(e.target.value)}
placeholder="搜索仓库..."
className="flex-1 px-4 py-2 border rounded"
/>
<button
type="submit"
disabled={isLoading}
className="px-6 py-2 bg-blue-500 text-white rounded"
>
{isLoading ? '搜索中...' : '搜索'}
</button>
</form>
)
}
From types/database.ts - production types
// Supabase database types
export interface Database {
public: {
Tables: {
repositories: {
Row: {
id: number
name: string
url: string
description: string
description_cn: string | null
language: string | null
stars: number
forks: number
created_at: string
}
}
trending_data: {
Row: {
id: number
repository_id: number
date: string
category: string
period: 'daily' | 'weekly' | 'monthly'
rank: number
stars_today: number
}
}
}
}
}
// Application types
export interface TrendingRepo {
id: number
name: string
url: string
description: string
description_cn?: string
language: string
stars: number
forks: number
stars_today: number
rank: number
}
From .env.example - required setup
# Supabase Configuration
NEXT_PUBLIC_SUPABASE_URL=your_supabase_url
NEXT_PUBLIC_SUPABASE_ANON_KEY=your_supabase_anon_key
SUPABASE_SERVICE_ROLE_KEY=your_service_role_key
From wrangler.jsonc - deployment config
{
"name": "github-trending",
"compatibility_date": "2024-01-01",
"pages_build_output_dir": ".open-next/worker",
"vars": {
"NEXT_PUBLIC_SUPABASE_URL": "",
"NEXT_PUBLIC_SUPABASE_ANON_KEY": ""
}
}
Confidence: 0.85 (High)
┌─────────────────────────────────────┐
│ Presentation Layer (Client) │
│ - React 19 Components │
│ - Tailwind CSS 4 Styling │
│ - Client-side State Management │
└──────────────┬──────────────────────┘
│
│ API Routes
▼
┌─────────────────────────────────────┐
│ Data Layer (Server) │
│ - Next.js API Routes │
│ - Supabase Client (Admin) │
│ - PostgreSQL Database │
│ - RPC Functions │
└─────────────────────────────────────┘
See references/architecture/ for complete analysis
github-trending-website/
├── app/ # Next.js 15 App Router
│ ├── api/ # API routes
│ │ ├── trending/ # Trending data endpoint
│ │ ├── languages/ # Language stats endpoint
│ │ ├── search/ # Search endpoint
│ │ └── date-stats/ # Date statistics
│ ├── layout.tsx # Root layout
│ ├── page.tsx # Home page
│ └── home-client.tsx # Client component
├── components/ # React components
│ ├── RepoCard.tsx # Repository card
│ ├── LanguageTabs.tsx # Language selector
│ ├── PeriodSelector.tsx # Time period selector
│ ├── DatePicker.tsx # Date picker
│ ├── SearchComponent.tsx # Search UI
│ └── Pagination.tsx # Pagination controls
├── types/ # TypeScript types
│ └── database.ts # Database & app types
├── scripts/ # Data processing
│ ├── import-data.ts # JSONL importer
│ ├── setup-database.ts # DB initialization
│ └── analyze-trending-data.mjs
├── lib/ # Utilities
│ └── supabase.ts # Supabase clients
└── public/ # Static assets
Fetch trending repositories with filters
Query Parameters:
date (string): Date in YYYY-MM-DD formatcategory (string): Language category (default: 'all')period (string): 'daily' | 'weekly' | 'monthly' (default: 'daily')limit (number): Results per page (default: 25)offset (number): Pagination offset (default: 0)Response:
[
{
"id": 1,
"name": "owner/repo",
"url": "https://github.com/owner/repo",
"description": "English description",
"description_cn": "中文描述",
"language": "TypeScript",
"stars": 12500,
"forks": 1200,
"stars_today": 150,
"rank": 1
}
]
Get language statistics for a specific date/period
Query Parameters:
date (string): Date in YYYY-MM-DD formatperiod (string): 'daily' | 'weekly' | 'monthly'Response:
[
{
"language": "TypeScript",
"count": 45,
"total_stars": 125000
}
]
Search repositories by keyword
Query Parameters:
q (string): Search querycategory (string): Filter by languageperiod (string): Time period filterResponse: Same as /api/trending
See references/api_reference/ for complete API documentation
Total Settings: 10,071 Confidence: Medium
# Supabase (Required)
NEXT_PUBLIC_SUPABASE_URL=https://xxx.supabase.co
NEXT_PUBLIC_SUPABASE_ANON_KEY=eyJxxx...
SUPABASE_SERVICE_ROLE_KEY=eyJxxx...
See references/config_patterns/ for detailed analysis
Stores GitHub repository metadata
CREATE TABLE repositories (
id SERIAL PRIMARY KEY,
name VARCHAR(255) NOT NULL,
url VARCHAR(500) UNIQUE NOT NULL,
description TEXT,
description_cn TEXT,
language VARCHAR(100),
stars INTEGER DEFAULT 0,
forks INTEGER DEFAULT 0,
created_at TIMESTAMP DEFAULT NOW()
);
Stores trending rankings by date/category/period
CREATE TABLE trending_data (
id SERIAL PRIMARY KEY,
repository_id INTEGER REFERENCES repositories(id),
date DATE NOT NULL,
category VARCHAR(100) NOT NULL,
period VARCHAR(20) NOT NULL,
rank INTEGER NOT NULL,
stars_today INTEGER DEFAULT 0,
UNIQUE(repository_id, date, category, period)
);
Returns trending repositories with full metadata
Returns language statistics with counts and total stars
See scripts/setup-database.ts for complete schema
# Development server
npm run dev
# Build for production
npm run build
# Start production server
npm start
# Cloudflare deployment
npm run deploy
# Cloudflare preview
npm run preview
# Database setup
npm run db:setup
# Import trending data
npm run import-data
# Code linting
npm run lint
api/trending/route.ts for basic patternscomponents/RepoCard.tsx for React patternstypes/database.ts for TypeScript definitions.env.example for required setupscripts/import-data.ts for ETL patternsapp/home-client.tsxreferences/api_reference/ - 22 documented filesreferences/dependencies/ - Dependency graphreferences/patterns/ - Design pattern analysisreferences/architecture/ - Architectural decisionsreferences/documentation/ - 30 markdown filesNEXT_PUBLIC_SUPABASE_ANON_KEY for client-side queriesSUPABASE_SERVICE_ROLE_KEY for admin operations in API routesPostgreSQL stored procedures called via Supabase for complex queries:
Three dimensions:
Complete TypeScript API documentation extracted from code:
Location: references/api_reference/
Dependency graph showing:
Location: references/dependencies/
Detected patterns from codebase analysis:
Location: references/patterns/
Analysis of 27 configuration files:
Location: references/config_patterns/
Deep dive into architecture:
Location: references/architecture/
Extracted markdown documentation:
Location: references/documentation/
api/trending/route.tsscripts/setup-database.tscomponents/lib/supabase.tsopen-next.config.ts as templatewrangler.jsonc for your projectpackage.jsonscripts/import-data.tsThis skill synthesizes knowledge from codebase analysis (single source type):
Confidence: Medium to High Source Type: Real production code
Key Files Analyzed:
api/trending/route.ts, api/languages/route.ts, api/search/route.tsRepoCard.tsx, LanguageTabs.tsx, SearchComponent.tsximport-data.ts, setup-database.tsdatabase.ts, cloudflare-env.d.tsAnalysis Depth:
Generated by Skill Seeker | Codebase Analyzer with C3.x Analysis Last Updated: 2026-03-12 Analysis Version: 1.0