Claude Code Hooks — Biến AI thành đồng đội thực sự trong frontend workflow
Hooks trong Claude Code cho phép tự động chạy script khi AI hoàn thành task hoặc gặp lỗi. Hướng dẫn thực tế: auto-format với Prettier, StopFailure notifications, CwdChanged context loading, và auto-run tests.
Nếu bạn chỉ dùng Claude Code như "chat với AI" thì bạn đang bỏ phí 60% sức mạnh của nó
Hooks là tính năng ít được nói đến nhất nhưng lại có impact lớn nhất đối với daily workflow. Thay vì chỉ ra lệnh cho AI và ngồi chờ, hooks cho phép bạn kết nối Claude Code với toàn bộ toolchain của project — linter, formatter, test runner, notification system — một cách tự động.
Hooks hoạt động như thế nào?
Tương tự Git hooks, bạn định nghĩa script chạy vào các thời điểm cụ thể trong lifecycle của một AI turn. Config trong ~/.claude/settings.json (global) hoặc .claude/settings.json (per-project).
Các hook events hiện có:
- PreToolUse — trước khi Claude dùng tool (file write, bash command)
- PostToolUse — sau khi tool chạy xong
- Stop — khi turn kết thúc bình thường
- StopFailure — khi turn kết thúc do lỗi API, rate limit, auth failure
- CwdChanged — khi working directory thay đổi
Use case 1: Auto-format sau khi AI chỉnh file
Pain point quen thuộc: Claude sửa code nhưng không follow đúng Prettier config. Thay vì nhắc "hãy format theo Prettier" mỗi lần, setup một PostToolUse hook:
// ~/.claude/settings.json
{
"hooks": {
"PostToolUse": [
{
"matcher": "Write|Edit",
"hooks": [
{
"type": "command",
"command": "cd $CLAUDE_CWD && npx prettier --write \"$CLAUDE_TOOL_INPUT_FILE_PATH\" 2>/dev/null || true"
}
]
}
]
}
}
Từ giờ mỗi khi Claude write hoặc edit file, Prettier chạy tự động. Code sạch không cần nghĩ đến.
Use case 2: StopFailure — Biết ngay khi AI bị stuck
StopFailure hook (thêm trong v2.1.78) fire khi turn kết thúc do lỗi. Cực kỳ hữu ích khi chạy task dài và rời khỏi màn hình:
// macOS — desktop notification khi AI gặp lỗi
{
"hooks": {
"StopFailure": [
{
"hooks": [
{
"type": "command",
"command": "osascript -e 'display notification \"Claude gặp lỗi — cần kiểm tra\" with title \"Claude Code\" sound name \"Basso\"'"
}
]
}
]
}
}
// Linux — dùng notify-send
// "command": "notify-send 'Claude Code' 'Task thất bại, cần kiểm tra' -i dialog-error"
Kịch bản thực tế: bạn nhờ Claude refactor một module lớn, đi uống cà phê 15 phút. Không có hook này, bạn quay lại thấy Claude đã dừng từ 10 phút trước do rate limit — và không biết đã làm được đến đâu.
Use case 3: Auto-run tests sau khi AI viết code
Setup hook tự động chạy test file tương ứng ngay sau khi AI write component:
// settings.json
{
"hooks": {
"PostToolUse": [
{
"matcher": "Write",
"hooks": [
{
"type": "command",
"command": "FILE=\"$CLAUDE_TOOL_INPUT_FILE_PATH\"; TEST_FILE=\"${FILE%.tsx}.test.tsx\"; [ -f \"$TEST_FILE\" ] && cd $CLAUDE_CWD && npx vitest run \"$TEST_FILE\" --reporter=verbose 2>&1 | tail -30 || true"
}
]
}
]
}
}
Logic: hook tìm file test tương ứng (ví dụ Button.tsx → Button.test.tsx) và chạy luôn sau khi AI write xong. Quan trọng hơn: output của hook được inject vào context của Claude — nếu test fail, Claude sẽ thấy lỗi và tự sửa trong turn tiếp theo.
Đây là vòng lặp tôi đang dùng:
// Workflow với hooks
// 1. Bạn: "Viết component UserCard với tests"
// 2. Claude viết UserCard.tsx
// 3. Hook tự động chạy UserCard.test.tsx
// 4. Test fail → output được inject vào context
// 5. Claude thấy lỗi → tự fix component
// 6. Hook chạy lại → test pass
// 7. Claude report "Done, all tests passing"
//
// Bạn không cần làm gì cả ngoài việc review kết quả cuối.
Use case 4: CwdChanged — Tự động load context khi đổi thư mục
CwdChanged hook (thêm trong v2.1.83) rất hữu ích cho monorepo. Mỗi khi Claude chuyển sang sub-package khác, hook tự động inject thông tin về package đó:
#!/bin/bash
# ~/.claude/hooks/on-cwd-changed.sh
PROJECT_DIR="$CLAUDE_CWD"
if [ -f "$PROJECT_DIR/package.json" ]; then
NAME=$(node -p "require('$PROJECT_DIR/package.json').name" 2>/dev/null)
FRAMEWORK=$(node -p "
const p = require('$PROJECT_DIR/package.json');
const deps = {...p.dependencies, ...p.devDependencies};
if (deps.next) 'Next.js ' + deps.next;
else if (deps['@remix-run/react']) 'Remix';
else if (deps.react) 'React ' + deps.react;
else 'Unknown';
" 2>/dev/null)
echo "=== Switched to: $NAME ($FRAMEWORK) ==="
# Auto-switch Node version nếu có .nvmrc
if [ -f "$PROJECT_DIR/.nvmrc" ]; then
nvm use 2>/dev/null && echo "=== Node: $(node -v) ==="
fi
fi
Tips quan trọng khi dùng Hooks
- Luôn thêm
|| trueđể hook không làm interrupt turn khi có lỗi phụ - Log để debug: thêm
2>>> /tmp/claude-hooks.logtrong quá trình setup - Giữ hook nhanh — hooks chạy đồng bộ. Hook chậm = AI turn chậm theo
- Per-project config ở
.claude/settings.jsonoverride global config
Kết luận
Hooks biến Claude Code từ "AI chat trong terminal" thành một real coding agent tích hợp sâu vào toolchain của bạn. Kết hợp auto-format + auto-test + failure notifications, bạn có một vòng feedback loop mà trước đây phải setup thủ công với Makefile hoặc Bash script phức tạp.
Điểm thú vị nhất: output của hooks được inject vào AI context, nghĩa là Claude không chỉ biết nó đã làm gì mà còn biết kết quả thực tế — và tự điều chỉnh. Đây mới là hướng AI coding thực sự đáng dùng.
Admin
Bình luận (0)
Đăng nhập để bình luận
Chưa có bình luận nào. Hãy là người đầu tiên!