Claude-skill-registry bellog-structure
Provides file organization and naming conventions for the Bellog project. Triggers when creating new files or reorganizing code.
git clone https://github.com/majiayu000/claude-skill-registry
T=$(mktemp -d) && git clone --depth=1 https://github.com/majiayu000/claude-skill-registry "$T" && mkdir -p ~/.claude/skills && cp -r "$T/skills/data/bellog-structure" ~/.claude/skills/majiayu000-claude-skill-registry-bellog-structure && rm -rf "$T"
skills/data/bellog-structure/SKILL.mdBellog File Organization
This skill defines the file structure, naming conventions, and organization patterns for the Bellog blog project.
Project Structure
/Users/castle_bell/Projects/bellog/ ├── src/ │ ├── app/ # Next.js App Router │ │ ├── layout.tsx # Root layout with fonts & metadata │ │ ├── page.tsx # Home page │ │ ├── template.tsx # Page transition wrapper │ │ ├── providers.tsx # Client-side providers │ │ ├── posts/ │ │ │ ├── page.tsx # All posts page │ │ │ └── [slug]/ │ │ │ └── page.tsx # Individual post │ │ ├── api/ │ │ │ └── revalidate/ │ │ │ └── route.ts # Cache revalidation endpoint │ │ ├── robots.ts # SEO robots.txt │ │ └── sitemap.ts # Dynamic sitemap │ │ │ ├── components/ │ │ ├── common/ # App-wide shared components │ │ │ ├── Navbar.tsx │ │ │ ├── Footer.tsx │ │ │ ├── Intro.tsx │ │ │ ├── Header.tsx │ │ │ └── ... │ │ ├── posts/ # Post-specific components │ │ │ ├── PostCard.tsx │ │ │ ├── PostList.tsx │ │ │ ├── PostRenderer.tsx │ │ │ ├── NotionToc.tsx │ │ │ └── ... │ │ └── ui/ # Low-level UI primitives │ │ ├── Tag.tsx │ │ ├── ThemeToggle.tsx │ │ ├── switch.tsx │ │ └── ... │ │ │ ├── hooks/ # Custom React hooks │ │ ├── useScrollSpy.ts │ │ ├── useTocObserver.ts │ │ └── useHeadings.ts │ │ │ ├── lib/ # Business logic & utilities │ │ ├── notion.ts # Notion API client │ │ ├── posts.ts # Post data fetching │ │ ├── tags.ts # Tag utilities │ │ └── utils.ts # General utilities │ │ │ ├── constants/ # Shared constants │ │ └── ui.ts # UI-related constants │ │ │ ├── types/ # TypeScript types │ │ └── index.d.ts # Global type definitions │ │ │ └── styles/ # Global styles │ └── global.css # Theme variables + Tailwind │ ├── public/ # Static assets ├── .claude/ # Claude Code configuration │ ├── agents/ # Custom sub-agents │ └── skills/ # Custom skills ├── .github/ # GitHub configuration │ └── PULL_REQUEST_TEMPLATE.md ├── .husky/ # Git hooks ├── tailwind.config.ts # Tailwind configuration ├── tsconfig.json # TypeScript configuration ├── next.config.ts # Next.js configuration ├── package.json # Dependencies & scripts ├── commitlint.config.ts # Commit message linting ├── CLAUDE.md # Project guide └── README.md # Project documentation
Naming Conventions
Components
Rule: PascalCase
✅ Correct: PostCard.tsx NotionToc.tsx ScrollToTop.tsx ThemeToggle.tsx ❌ Wrong: postCard.tsx notion-toc.tsx scroll_to_top.tsx
Hooks
Rule: camelCase with
use prefix
✅ Correct: useScrollSpy.ts useTocObserver.ts useHeadings.ts useScrollPosition.ts ❌ Wrong: UseScrollSpy.ts scroll-spy-hook.ts scrollSpy.ts (missing use prefix)
Utilities & Libraries
Rule: camelCase
✅ Correct: notion.ts posts.ts tags.ts utils.ts ❌ Wrong: Notion.ts Posts.ts tag-utils.ts
Types
Rule: camelCase file, PascalCase exports
✅ Correct: File: index.d.ts Export: interface Post { } Export: type PostStatus = 'published' | 'draft'; ❌ Wrong: File: Post.d.ts Export: interface post { }
Constants
Rule: SCREAMING_SNAKE_CASE for values, camelCase for file
✅ Correct: File: ui.ts Exports: export const HEADER_OFFSET = 80; export const SCROLL_SPY_OFFSET = 100; ❌ Wrong: export const headerOffset = 80; export const header-offset = 80;
API Routes
Rule: camelCase folder, route.ts file
✅ Correct: app/api/revalidate/route.ts ❌ Wrong: app/api/Revalidate/route.ts app/api/revalidate/revalidate.ts
Where to Place Files
Decision Tree
Q: Is it a React component?
- Yes →
/src/components/- App-wide (Navbar, Footer) →
/src/components/common/ - Post-specific (PostCard, NotionToc) →
/src/components/posts/ - Reusable UI primitive (Tag, Button) →
/src/components/ui/
- App-wide (Navbar, Footer) →
Q: Is it a custom hook?
- Yes →
/src/hooks/use[Name].ts
Q: Is it business logic or data fetching?
- Yes →
/src/lib/- Notion API →
/src/lib/notion.ts - Post data →
/src/lib/posts.ts - Utility functions →
/src/lib/utils.ts
- Notion API →
Q: Is it a constant value?
- Yes →
/src/constants/- UI-related →
/src/constants/ui.ts - API-related →
/src/constants/api.ts
- UI-related →
Q: Is it a TypeScript type?
- Yes →
/src/types/index.d.ts
Q: Is it a page or route?
- Yes →
/src/app/[route]/page.tsx
Q: Is it an API endpoint?
- Yes →
/src/app/api/[endpoint]/route.ts
Component Organization
Common Components (/src/components/common/
)
/src/components/common/Components used across multiple pages:
- Layout components (Navbar, Footer)
- Page sections (Intro, Header)
- Shared widgets (ProgressBar)
Examples:
- Site navigationNavbar.tsx
- Site footerFooter.tsx
- Hero section with animationsIntro.tsx
- Scroll progress indicatorProgressBar.tsx
- Page headersHeader.tsx
Post Components (/src/components/posts/
)
/src/components/posts/Components specific to blog posts:
- Post rendering (PostRenderer)
- Post navigation (NotionToc, PostNavigation)
- Post lists (PostList, PostCard)
Examples:
- Individual post previewPostCard.tsx
- Grid of post cardsPostList.tsx
- Notion content rendererPostRenderer.tsx
- Table of contentsNotionToc.tsx
- Previous/Next navigationPostNavigation.tsx
- Comment systemGiscusComments.tsx
UI Components (/src/components/ui/
)
/src/components/ui/Low-level, reusable UI primitives:
- Buttons, inputs, switches
- Tags, badges
- Shadcn/ui components
Examples:
- Tag displayTag.tsx
- Tag filteringTagList.tsx
- Dark/light mode toggleThemeToggle.tsx
- Radix UI switch (shadcn/ui)switch.tsx
File Templates
Component Template
// For interactive components "use client"; import { useState } from 'react'; import { motion } from 'framer-motion'; interface ComponentNameProps { // Props } export function ComponentName({ }: ComponentNameProps) { // Logic return ( <div> {/* JSX */} </div> ); }
Hook Template
import { useState, useEffect } from 'react'; /** * Brief description of what this hook does * * @example * const value = useHookName(); */ export function useHookName() { // Hook logic return value; }
Utility Template
/** * Brief description of utility function * * @param paramName - Description * @returns Description */ export function utilityName(paramName: Type): ReturnType { // Implementation }
Type Definition Template
// /src/types/index.d.ts export interface Post { id: string; title: string; slug: string; date: string; description: string; tags: string[]; status: PostStatus; } export type PostStatus = 'published' | 'draft' | 'archived';
Import Organization
Order
// 1. React & Next.js import { useState } from 'react'; import Link from 'next/link'; // 2. Third-party libraries import { motion } from 'framer-motion'; import { Search } from 'lucide-react'; // 3. Internal imports (@/...) import { Button } from '@/components/ui/button'; import { getAllPosts } from '@/lib/posts'; import { HEADER_OFFSET } from '@/constants/ui'; // 4. Relative imports import { helperFunction } from '../utils'; // 5. Type imports (separate) import type { Post } from '@/types';
Path Aliases
Bellog uses
@/ for root imports:
// ✅ Correct import { PostCard } from '@/components/posts/PostCard'; import { getAllPosts } from '@/lib/posts'; import { HEADER_OFFSET } from '@/constants/ui'; // ❌ Wrong (no relative paths from root) import { PostCard } from '../../components/posts/PostCard';
Code Organization Patterns
Single Responsibility
// ✅ Good - Each file has one clear purpose // /src/lib/notion.ts - Notion API calls // /src/lib/posts.ts - Post data transformation // /src/lib/tags.ts - Tag utilities // ❌ Bad - Everything in one file // /src/lib/everything.ts
Group Related Code
// ✅ Good - Related components together /src/components/posts/ PostCard.tsx PostList.tsx PostNavigation.tsx // ❌ Bad - All components flat /src/components/ PostCard.tsx Navbar.tsx PostList.tsx Footer.tsx
Constants Extraction
// ✅ Good - Constants in separate file // /src/constants/ui.ts export const HEADER_OFFSET = 80; export const SCROLL_SPY_OFFSET = 100; // Component uses constants import { HEADER_OFFSET } from '@/constants/ui'; // ❌ Bad - Magic numbers in component const offset = 80; // What is this?
File Size Guidelines
Components: < 200 lines
- If larger, consider splitting into smaller components
Hooks: < 100 lines
- If larger, consider extracting helper functions
Utils: < 50 lines per function
- If larger, break into smaller functions
Types: No limit
- Types can be long, that's okay
Barrel Exports (Avoid)
// ❌ Avoid barrel exports (index.ts files) // /src/components/index.ts export { PostCard } from './PostCard'; export { PostList } from './PostList'; // ✅ Prefer direct imports import { PostCard } from '@/components/posts/PostCard'; import { PostList } from '@/components/posts/PostList';
Why: Barrel exports slow down builds and complicate tree-shaking.
Environment Files
.env.local # Local development secrets (gitignored) .env.example # Template (committed to git)
Never commit:
.env.local.env- Any file with actual secrets
Git Ignore Patterns
Ensure these are in
.gitignore:
# Dependencies node_modules/ .pnp .pnp.js # Next.js .next/ out/ # Environment .env.local .env # IDE .vscode/ .idea/ # OS .DS_Store
Documentation Structure
/ # Root ├── README.md # Project overview & setup ├── CLAUDE.md # Development guide (for AI) └── docs/ # Detailed documentation (if needed) ├── architecture.md └── deployment.md
Quick Reference
Components: PascalCase.tsx /src/components/{common,posts,ui}/ Hooks: useName.ts /src/hooks/ Utilities: name.ts /src/lib/ Constants: NAME /src/constants/ Types: name.d.ts /src/types/ Pages: page.tsx /src/app/[route]/ API: route.ts /src/app/api/[endpoint]/
Checklist for New Files
- File in correct directory
- Naming convention followed (PascalCase / camelCase)
- Imports organized by category
- Using @ alias for imports (not relative from root)
- TypeScript types defined
- No magic numbers (use constants)
- Single responsibility (one clear purpose)
- File size reasonable (< 200 lines for components)
Remember: Organization is about findability. When someone looks for a file, it should be obvious where it is.