Install command
Provided
Analyzes Next.js page routes and generates a route map when pages are added or modified.
Open the source and read safety notes before installing.
Source-backed facts for citing this resource, derived directly from the registry — also available as plain text for AI assistants.
Decision playbook
Signals are present but mixed. Use the checklist below to confirm the source and operational safety for your environment.
0
78
—
No baseline selected
No major trust-signal divergence detected in the current selection.
Confirm ownership and provenance before trusting install instructions.
Source link availableRequired
Open the canonical repository and verify ownership.
Source provenance statusRequired
Marked as source-backed.
Metadata reviewed
Registry metadata indicates a reviewed listing.
Validate risk disclosures before installation or API wiring.
Safety notes presentRequired
Review the listed safety guidance before running commands.
Privacy notes presentRequired
Review data handling notes before connecting accounts or secrets.
Trust level risk gateRequired
Trust level does not block evaluation.
Check package metadata and artifact integrity signals.
Install payload available
Install or copy payload is available for review.
Package verification flag
No package verification flag provided.
Checksum metadata
No checksum provided for downloaded artifact.
Use compare context to validate trade-offs before adoption.
Compare tray has multiple entries
Add at least one more entry to compare trust differences.
Baseline comparison available
No baseline peer selected yet.
Diverging trust signals identified
No major trust-signal divergence found.
Setup at a glance
Copy-ready — paste the snippet to get started.
Install command
Provided
Config snippet
Provided
Copy snippet
Provided
Prerequisites
None
Platforms
1 listed
Difficulty
0/100
Adoption plan
Current risk score 16/100. Use staged verification before broader rollout.
Validate source and review signals before any execution.
Confirm source provenanceRequired
Source URL/provenance metadata is present.
Confirm metadata review state
Listing has review metadata.
Verify install payload
Install/config payload exists and can be inspected.
Confirm safety, privacy, and package integrity signals.
Review safety notesRequired
Safety notes are present.
Review privacy notesRequired
Privacy notes are present.
Verify package integrity metadata
No package verification/checksum metadata.
Adopt in controlled steps based on the selected plan.
Run in isolated sandbox firstRequired
Use a constrained sandbox and observe behavior across multiple tasks.
Roll out graduallyRequired
Roll out to a small cohort before wider usage.
Set monitoring and fallback
Define rollback path and monitor errors after adoption.
Evidence readiness
Required evidence gates are covered (5/6 signals complete).
Source repository/provenance is listed.
Required in this preset
Review metadata is present.
Required in this preset
Safety notes are present.
Required in this preset
Privacy notes are present.
Optional in this preset
Package integrity metadata is missing.
Optional in this preset
Install payload is available.
Required in this preset
Required evidence gates are covered for this preset.
Decision timeline
5/6 steps complete with no blocking gaps for this preset.
triage
Source/provenance metadata is available.
triage
Review metadata is available.
verify
Safety notes are available.
verify
Privacy notes are available.
verify
Package integrity metadata is missing.
rollout
Install payload is available.
No required blockers for this timeline preset.
Safety & privacy surface
1 safety and 1 privacy notes across 2 risk areas. Review closely: credentials & tokens, permissions & scopes.
#!/usr/bin/env bash
# Read the tool input from stdin
INPUT=$(cat)
TOOL_NAME=$(echo "$INPUT" | jq -r '.tool_name')
FILE_PATH=$(echo "$INPUT" | jq -r '.tool_input.file_path // .tool_input.path // ""')
if [ -z "$FILE_PATH" ]; then
exit 0
fi
# Check if this is a Next.js page, component, or route file
if [[ "$FILE_PATH" == *pages/*.* ]] || [[ "$FILE_PATH" == *app/*.* ]] || [[ "$FILE_PATH" == *src/pages/*.* ]] || [[ "$FILE_PATH" == *src/app/*.* ]]; then
echo "🗺️ Next.js Route Analysis for: $(basename "$FILE_PATH")" >&2
# Initialize analysis counters
TOTAL_ROUTES=0
STATIC_ROUTES=0
DYNAMIC_ROUTES=0
API_ROUTES=0
CATCH_ALL_ROUTES=0
ERRORS=0
WARNINGS=0
# Function to report analysis results
report_analysis() {
local level="$1"
local message="$2"
case "$level" in
"ERROR")
echo "❌ ERROR: $message" >&2
ERRORS=$((ERRORS + 1))
;;
"WARNING")
echo "⚠️ WARNING: $message" >&2
WARNINGS=$((WARNINGS + 1))
;;
"INFO")
echo "ℹ️ INFO: $message" >&2
;;
"FOUND")
echo "✅ FOUND: $message" >&2
;;
esac
}
# Detect Next.js project structure
PROJECT_ROOT="."
PAGES_DIR=""
APP_DIR=""
SRC_PAGES_DIR=""
SRC_APP_DIR=""
# Find project root and routing directories
if [ -f "./package.json" ]; then
# Check if this is a Next.js project
if grep -q '"next"' "./package.json" 2>/dev/null; then
echo " 📦 Next.js project detected" >&2
# Check for different routing structures
[ -d "./pages" ] && PAGES_DIR="./pages"
[ -d "./app" ] && APP_DIR="./app"
[ -d "./src/pages" ] && SRC_PAGES_DIR="./src/pages"
[ -d "./src/app" ] && SRC_APP_DIR="./src/app"
if [ -n "$APP_DIR" ] || [ -n "$SRC_APP_DIR" ]; then
echo " 🔧 App Router structure detected" >&2
fi
if [ -n "$PAGES_DIR" ] || [ -n "$SRC_PAGES_DIR" ]; then
echo " 📄 Pages Router structure detected" >&2
fi
else
report_analysis "WARNING" "Not a Next.js project (no Next.js dependency found)"
fi
else
report_analysis "WARNING" "No package.json found - may not be in project root"
fi
# Create temporary files for route analysis
ROUTES_FILE="/tmp/nextjs_routes_$$"
API_ROUTES_FILE="/tmp/nextjs_api_routes_$$"
ROUTE_MAP_FILE="/tmp/nextjs_route_map_$$"
echo "📊 Analyzing route structure..." >&2
# Function to analyze route type
analyze_route_type() {
local route_path="$1"
local file_path="$2"
# Check if it's an API route
if [[ "$file_path" == *"/api/"* ]] || [[ "$route_path" == *"/api/"* ]]; then
API_ROUTES=$((API_ROUTES + 1))
echo "api|$route_path|$file_path" >> "$API_ROUTES_FILE"
return
fi
# Check route complexity
if [[ "$route_path" == *"[..."* ]]; then
# Catch-all route
CATCH_ALL_ROUTES=$((CATCH_ALL_ROUTES + 1))
echo "catch-all|$route_path|$file_path" >> "$ROUTES_FILE"
elif [[ "$route_path" == *"["* ]]; then
# Dynamic route
DYNAMIC_ROUTES=$((DYNAMIC_ROUTES + 1))
echo "dynamic|$route_path|$file_path" >> "$ROUTES_FILE"
else
# Static route
STATIC_ROUTES=$((STATIC_ROUTES + 1))
echo "static|$route_path|$file_path" >> "$ROUTES_FILE"
fi
}
# Function to convert file path to route
file_to_route() {
local file_path="$1"
local base_dir="$2"
# Remove base directory and file extension
local route=$(echo "$file_path" | sed "s|^$base_dir||" | sed 's|\\.[jt]sx\\?$||')
# Handle special Next.js file names
route=$(echo "$route" | sed 's|/page$||') # Remove /page suffix
route=$(echo "$route" | sed 's|/route$||') # Remove /route suffix
route=$(echo "$route" | sed 's|/index$||') # Remove /index suffix
# Convert empty route to root
[ -z "$route" ] && route="/"
# Ensure route starts with /
[[ "$route" != /* ]] && route="/$route"
echo "$route"
}
# Analyze Pages Router (if exists)
for pages_dir in "$PAGES_DIR" "$SRC_PAGES_DIR"; do
if [ -n "$pages_dir" ] && [ -d "$pages_dir" ]; then
echo " 📄 Analyzing Pages Router in $pages_dir..." >&2
# Find all page files
find "$pages_dir" -type f \( -name "*.js" -o -name "*.jsx" -o -name "*.ts" -o -name "*.tsx" \) 2>/dev/null | while read -r file; do
if [ -f "$file" ]; then
route=$(file_to_route "$file" "$pages_dir")
analyze_route_type "$route" "$file"
echo " 📋 $route <- $file" >&2
fi
done
fi
done
# Analyze App Router (if exists)
for app_dir in "$APP_DIR" "$SRC_APP_DIR"; do
if [ -n "$app_dir" ] && [ -d "$app_dir" ]; then
echo " 🔧 Analyzing App Router in $app_dir..." >&2
# Find page.tsx/jsx and route.tsx/jsx files
find "$app_dir" -type f \( -name "page.js" -o -name "page.jsx" -o -name "page.ts" -o -name "page.tsx" -o -name "route.js" -o -name "route.jsx" -o -name "route.ts" -o -name "route.tsx" \) 2>/dev/null | while read -r file; do
if [ -f "$file" ]; then
route=$(file_to_route "$file" "$app_dir")
analyze_route_type "$route" "$file"
echo " 📋 $route <- $file" >&2
fi
done
# Find layout files
find "$app_dir" -type f \( -name "layout.js" -o -name "layout.jsx" -o -name "layout.ts" -o -name "layout.tsx" \) 2>/dev/null | while read -r file; do
if [ -f "$file" ]; then
layout_path=$(echo "$file" | sed "s|^$app_dir||" | sed 's|/layout\\.[jt]sx\\?$||')
[ -z "$layout_path" ] && layout_path="/"
[[ "$layout_path" != /* ]] && layout_path="/$layout_path"
echo " 🎨 Layout: $layout_path <- $file" >&2
fi
done
fi
done
# Calculate totals
TOTAL_ROUTES=$((STATIC_ROUTES + DYNAMIC_ROUTES + CATCH_ALL_ROUTES))
# Generate route analysis report
echo "" >&2
echo "📊 Route Analysis Results:" >&2
echo "=========================" >&2
echo " 📄 Total Routes: $TOTAL_ROUTES" >&2
echo " 📋 Static Routes: $STATIC_ROUTES" >&2
echo " 🔧 Dynamic Routes: $DYNAMIC_ROUTES" >&2
echo " 🌐 Catch-all Routes: $CATCH_ALL_ROUTES" >&2
echo " 🚀 API Routes: $API_ROUTES" >&2
# Route complexity analysis
if [ "$TOTAL_ROUTES" -eq 0 ]; then
report_analysis "WARNING" "No routes found in the project"
elif [ "$TOTAL_ROUTES" -gt 50 ]; then
report_analysis "INFO" "Large application with $TOTAL_ROUTES routes"
else
report_analysis "INFO" "Application has $TOTAL_ROUTES routes"
fi
# API route analysis
if [ "$API_ROUTES" -gt 0 ]; then
report_analysis "FOUND" "$API_ROUTES API endpoints detected"
if [ -f "$API_ROUTES_FILE" ]; then
echo " 🚀 API Endpoints:" >&2
cat "$API_ROUTES_FILE" | while IFS='|' read -r type route file; do
echo " • $route" >&2
done
fi
fi
# Dynamic route analysis
if [ "$DYNAMIC_ROUTES" -gt 0 ] || [ "$CATCH_ALL_ROUTES" -gt 0 ]; then
report_analysis "FOUND" "$((DYNAMIC_ROUTES + CATCH_ALL_ROUTES)) dynamic routes detected"
if [ -f "$ROUTES_FILE" ]; then
echo " 🔧 Dynamic Routes:" >&2
grep -E "^(dynamic|catch-all)" "$ROUTES_FILE" | while IFS='|' read -r type route file; do
echo " • $route ($type)" >&2
done
fi
fi
# Generate route map file
if [ "$TOTAL_ROUTES" -gt 0 ] || [ "$API_ROUTES" -gt 0 ]; then
echo "📄 Generating route map..." >&2
ROUTE_MAP_OUTPUT="nextjs-routes.json"
cat > "$ROUTE_MAP_OUTPUT" << EOF
{
"generated": "$(date -u +"%Y-%m-%dT%H:%M:%SZ")",
"project": "$(basename "$(pwd)")",
"totalRoutes": $TOTAL_ROUTES,
"apiRoutes": $API_ROUTES,
"routes": {
"static": [
EOF
# Add static routes
if [ -f "$ROUTES_FILE" ]; then
grep "^static" "$ROUTES_FILE" | while IFS='|' read -r type route file; do
echo " { \"path\": \"$route\", \"file\": \"$file\" }," >> "$ROUTE_MAP_OUTPUT"
done
# Remove trailing comma from last entry
sed -i '$ s/,$//' "$ROUTE_MAP_OUTPUT" 2>/dev/null || sed -i '' '$ s/,$//' "$ROUTE_MAP_OUTPUT" 2>/dev/null
fi
cat >> "$ROUTE_MAP_OUTPUT" << EOF
],
"dynamic": [
EOF
# Add dynamic routes
if [ -f "$ROUTES_FILE" ]; then
grep "^dynamic" "$ROUTES_FILE" | while IFS='|' read -r type route file; do
echo " { \"path\": \"$route\", \"file\": \"$file\", \"type\": \"dynamic\" }," >> "$ROUTE_MAP_OUTPUT"
done
grep "^catch-all" "$ROUTES_FILE" | while IFS='|' read -r type route file; do
echo " { \"path\": \"$route\", \"file\": \"$file\", \"type\": \"catch-all\" }," >> "$ROUTE_MAP_OUTPUT"
done
# Remove trailing comma from last entry
sed -i '$ s/,$//' "$ROUTE_MAP_OUTPUT" 2>/dev/null || sed -i '' '$ s/,$//' "$ROUTE_MAP_OUTPUT" 2>/dev/null
fi
cat >> "$ROUTE_MAP_OUTPUT" << EOF
],
"api": [
EOF
# Add API routes
if [ -f "$API_ROUTES_FILE" ]; then
cat "$API_ROUTES_FILE" | while IFS='|' read -r type route file; do
echo " { \"path\": \"$route\", \"file\": \"$file\" }," >> "$ROUTE_MAP_OUTPUT"
done
# Remove trailing comma from last entry
sed -i '$ s/,$//' "$ROUTE_MAP_OUTPUT" 2>/dev/null || sed -i '' '$ s/,$//' "$ROUTE_MAP_OUTPUT" 2>/dev/null
fi
cat >> "$ROUTE_MAP_OUTPUT" << EOF
]
}
}
EOF
report_analysis "FOUND" "Route map generated: $ROUTE_MAP_OUTPUT"
fi
# Performance and optimization recommendations
echo "💡 Route optimization recommendations..." >&2
if [ "$DYNAMIC_ROUTES" -gt 10 ]; then
echo " • Consider using ISR for frequently accessed dynamic routes" >&2
fi
if [ "$API_ROUTES" -gt 0 ]; then
echo " • Consider API route optimization and caching strategies" >&2
fi
if [ "$CATCH_ALL_ROUTES" -gt 3 ]; then
echo " • Review catch-all routes for potential over-use" >&2
fi
if [ "$TOTAL_ROUTES" -gt 100 ]; then
echo " • Large application - consider route-based code splitting" >&2
fi
# Clean up temporary files
rm -f "$ROUTES_FILE" "$API_ROUTES_FILE" "$ROUTE_MAP_FILE"
echo "" >&2
echo "📋 Next.js Route Analysis Summary:" >&2
echo "=================================" >&2
echo " 📄 File analyzed: $(basename "$FILE_PATH")" >&2
echo " 🗺️ Total routes found: $((TOTAL_ROUTES + API_ROUTES))" >&2
echo " 📊 Route breakdown: $STATIC_ROUTES static, $DYNAMIC_ROUTES dynamic, $API_ROUTES API" >&2
echo " ⚠️ Warnings: $WARNINGS" >&2
echo " ❌ Errors: $ERRORS" >&2
if [ "$ERRORS" -eq 0 ]; then
if [ "$TOTAL_ROUTES" -gt 0 ] || [ "$API_ROUTES" -gt 0 ]; then
echo " 🎉 Status: SUCCESS - Route analysis complete" >&2
else
echo " ✅ Status: INFO - No routes found to analyze" >&2
fi
else
echo " ❌ Status: ISSUES - Route analysis completed with errors" >&2
fi
echo "" >&2
echo "💡 Next.js Routing Best Practices:" >&2
echo " • Use static routes when possible for better performance" >&2
echo " • Implement proper error boundaries for dynamic routes" >&2
echo " • Consider ISR for dynamic content that doesn't change often" >&2
echo " • Use API routes for server-side functionality" >&2
echo " • Organize routes logically with proper folder structure" >&2
echo " • Document your routing strategy for team collaboration" >&2
else
# Not a Next.js file, exit silently
exit 0
fi
exit 0{
"hooks": {
"postToolUse": {
"script": "./.claude/hooks/nextjs-route-analyzer.sh",
"matchers": [
"write",
"edit"
]
}
}
}.claude/settings.local.json~/.claude/settings.json.claude/settings.json{
"hooks": {
"postToolUse": {
"script": "./.claude/hooks/nextjs-route-analyzer.sh",
"matchers": ["write", "edit"]
}
}
}
#!/usr/bin/env bash
# Read the tool input from stdin
INPUT=$(cat)
TOOL_NAME=$(echo "$INPUT" | jq -r '.tool_name')
FILE_PATH=$(echo "$INPUT" | jq -r '.tool_input.file_path // .tool_input.path // ""')
if [ -z "$FILE_PATH" ]; then
exit 0
fi
# Check if this is a Next.js page, component, or route file
if [[ "$FILE_PATH" == *pages/*.* ]] || [[ "$FILE_PATH" == *app/*.* ]] || [[ "$FILE_PATH" == *src/pages/*.* ]] || [[ "$FILE_PATH" == *src/app/*.* ]]; then
echo "🗺️ Next.js Route Analysis for: $(basename "$FILE_PATH")" >&2
# Initialize analysis counters
TOTAL_ROUTES=0
STATIC_ROUTES=0
DYNAMIC_ROUTES=0
API_ROUTES=0
CATCH_ALL_ROUTES=0
ERRORS=0
WARNINGS=0
# Function to report analysis results
report_analysis() {
local level="$1"
local message="$2"
case "$level" in
"ERROR")
echo "❌ ERROR: $message" >&2
ERRORS=$((ERRORS + 1))
;;
"WARNING")
echo "⚠️ WARNING: $message" >&2
WARNINGS=$((WARNINGS + 1))
;;
"INFO")
echo "ℹ️ INFO: $message" >&2
;;
"FOUND")
echo "✅ FOUND: $message" >&2
;;
esac
}
# Detect Next.js project structure
PROJECT_ROOT="."
PAGES_DIR=""
APP_DIR=""
SRC_PAGES_DIR=""
SRC_APP_DIR=""
# Find project root and routing directories
if [ -f "./package.json" ]; then
# Check if this is a Next.js project
if grep -q '"next"' "./package.json" 2>/dev/null; then
echo " 📦 Next.js project detected" >&2
# Check for different routing structures
[ -d "./pages" ] && PAGES_DIR="./pages"
[ -d "./app" ] && APP_DIR="./app"
[ -d "./src/pages" ] && SRC_PAGES_DIR="./src/pages"
[ -d "./src/app" ] && SRC_APP_DIR="./src/app"
if [ -n "$APP_DIR" ] || [ -n "$SRC_APP_DIR" ]; then
echo " 🔧 App Router structure detected" >&2
fi
if [ -n "$PAGES_DIR" ] || [ -n "$SRC_PAGES_DIR" ]; then
echo " 📄 Pages Router structure detected" >&2
fi
else
report_analysis "WARNING" "Not a Next.js project (no Next.js dependency found)"
fi
else
report_analysis "WARNING" "No package.json found - may not be in project root"
fi
# Create temporary files for route analysis
ROUTES_FILE="/tmp/nextjs_routes_$$"
API_ROUTES_FILE="/tmp/nextjs_api_routes_$$"
ROUTE_MAP_FILE="/tmp/nextjs_route_map_$$"
echo "📊 Analyzing route structure..." >&2
# Function to analyze route type
analyze_route_type() {
local route_path="$1"
local file_path="$2"
# Check if it's an API route
if [[ "$file_path" == *"/api/"* ]] || [[ "$route_path" == *"/api/"* ]]; then
API_ROUTES=$((API_ROUTES + 1))
echo "api|$route_path|$file_path" >> "$API_ROUTES_FILE"
return
fi
# Check route complexity
if [[ "$route_path" == *"[..."* ]]; then
# Catch-all route
CATCH_ALL_ROUTES=$((CATCH_ALL_ROUTES + 1))
echo "catch-all|$route_path|$file_path" >> "$ROUTES_FILE"
elif [[ "$route_path" == *"["* ]]; then
# Dynamic route
DYNAMIC_ROUTES=$((DYNAMIC_ROUTES + 1))
echo "dynamic|$route_path|$file_path" >> "$ROUTES_FILE"
else
# Static route
STATIC_ROUTES=$((STATIC_ROUTES + 1))
echo "static|$route_path|$file_path" >> "$ROUTES_FILE"
fi
}
# Function to convert file path to route
file_to_route() {
local file_path="$1"
local base_dir="$2"
# Remove base directory and file extension
local route=$(echo "$file_path" | sed "s|^$base_dir||" | sed 's|\\.[jt]sx\\?$||')
# Handle special Next.js file names
route=$(echo "$route" | sed 's|/page$||') # Remove /page suffix
route=$(echo "$route" | sed 's|/route$||') # Remove /route suffix
route=$(echo "$route" | sed 's|/index$||') # Remove /index suffix
# Convert empty route to root
[ -z "$route" ] && route="/"
# Ensure route starts with /
[[ "$route" != /* ]] && route="/$route"
echo "$route"
}
# Analyze Pages Router (if exists)
for pages_dir in "$PAGES_DIR" "$SRC_PAGES_DIR"; do
if [ -n "$pages_dir" ] && [ -d "$pages_dir" ]; then
echo " 📄 Analyzing Pages Router in $pages_dir..." >&2
# Find all page files
find "$pages_dir" -type f \( -name "*.js" -o -name "*.jsx" -o -name "*.ts" -o -name "*.tsx" \) 2>/dev/null | while read -r file; do
if [ -f "$file" ]; then
route=$(file_to_route "$file" "$pages_dir")
analyze_route_type "$route" "$file"
echo " 📋 $route <- $file" >&2
fi
done
fi
done
# Analyze App Router (if exists)
for app_dir in "$APP_DIR" "$SRC_APP_DIR"; do
if [ -n "$app_dir" ] && [ -d "$app_dir" ]; then
echo " 🔧 Analyzing App Router in $app_dir..." >&2
# Find page.tsx/jsx and route.tsx/jsx files
find "$app_dir" -type f \( -name "page.js" -o -name "page.jsx" -o -name "page.ts" -o -name "page.tsx" -o -name "route.js" -o -name "route.jsx" -o -name "route.ts" -o -name "route.tsx" \) 2>/dev/null | while read -r file; do
if [ -f "$file" ]; then
route=$(file_to_route "$file" "$app_dir")
analyze_route_type "$route" "$file"
echo " 📋 $route <- $file" >&2
fi
done
# Find layout files
find "$app_dir" -type f \( -name "layout.js" -o -name "layout.jsx" -o -name "layout.ts" -o -name "layout.tsx" \) 2>/dev/null | while read -r file; do
if [ -f "$file" ]; then
layout_path=$(echo "$file" | sed "s|^$app_dir||" | sed 's|/layout\\.[jt]sx\\?$||')
[ -z "$layout_path" ] && layout_path="/"
[[ "$layout_path" != /* ]] && layout_path="/$layout_path"
echo " 🎨 Layout: $layout_path <- $file" >&2
fi
done
fi
done
# Calculate totals
TOTAL_ROUTES=$((STATIC_ROUTES + DYNAMIC_ROUTES + CATCH_ALL_ROUTES))
# Generate route analysis report
echo "" >&2
echo "📊 Route Analysis Results:" >&2
echo "=========================" >&2
echo " 📄 Total Routes: $TOTAL_ROUTES" >&2
echo " 📋 Static Routes: $STATIC_ROUTES" >&2
echo " 🔧 Dynamic Routes: $DYNAMIC_ROUTES" >&2
echo " 🌐 Catch-all Routes: $CATCH_ALL_ROUTES" >&2
echo " 🚀 API Routes: $API_ROUTES" >&2
# Route complexity analysis
if [ "$TOTAL_ROUTES" -eq 0 ]; then
report_analysis "WARNING" "No routes found in the project"
elif [ "$TOTAL_ROUTES" -gt 50 ]; then
report_analysis "INFO" "Large application with $TOTAL_ROUTES routes"
else
report_analysis "INFO" "Application has $TOTAL_ROUTES routes"
fi
# API route analysis
if [ "$API_ROUTES" -gt 0 ]; then
report_analysis "FOUND" "$API_ROUTES API endpoints detected"
if [ -f "$API_ROUTES_FILE" ]; then
echo " 🚀 API Endpoints:" >&2
cat "$API_ROUTES_FILE" | while IFS='|' read -r type route file; do
echo " • $route" >&2
done
fi
fi
# Dynamic route analysis
if [ "$DYNAMIC_ROUTES" -gt 0 ] || [ "$CATCH_ALL_ROUTES" -gt 0 ]; then
report_analysis "FOUND" "$((DYNAMIC_ROUTES + CATCH_ALL_ROUTES)) dynamic routes detected"
if [ -f "$ROUTES_FILE" ]; then
echo " 🔧 Dynamic Routes:" >&2
grep -E "^(dynamic|catch-all)" "$ROUTES_FILE" | while IFS='|' read -r type route file; do
echo " • $route ($type)" >&2
done
fi
fi
# Generate route map file
if [ "$TOTAL_ROUTES" -gt 0 ] || [ "$API_ROUTES" -gt 0 ]; then
echo "📄 Generating route map..." >&2
ROUTE_MAP_OUTPUT="nextjs-routes.json"
cat > "$ROUTE_MAP_OUTPUT" << EOF
{
"generated": "$(date -u +"%Y-%m-%dT%H:%M:%SZ")",
"project": "$(basename "$(pwd)")",
"totalRoutes": $TOTAL_ROUTES,
"apiRoutes": $API_ROUTES,
"routes": {
"static": [
EOF
# Add static routes
if [ -f "$ROUTES_FILE" ]; then
grep "^static" "$ROUTES_FILE" | while IFS='|' read -r type route file; do
echo " { \"path\": \"$route\", \"file\": \"$file\" }," >> "$ROUTE_MAP_OUTPUT"
done
# Remove trailing comma from last entry
sed -i '$ s/,$//' "$ROUTE_MAP_OUTPUT" 2>/dev/null || sed -i '' '$ s/,$//' "$ROUTE_MAP_OUTPUT" 2>/dev/null
fi
cat >> "$ROUTE_MAP_OUTPUT" << EOF
],
"dynamic": [
EOF
# Add dynamic routes
if [ -f "$ROUTES_FILE" ]; then
grep "^dynamic" "$ROUTES_FILE" | while IFS='|' read -r type route file; do
echo " { \"path\": \"$route\", \"file\": \"$file\", \"type\": \"dynamic\" }," >> "$ROUTE_MAP_OUTPUT"
done
grep "^catch-all" "$ROUTES_FILE" | while IFS='|' read -r type route file; do
echo " { \"path\": \"$route\", \"file\": \"$file\", \"type\": \"catch-all\" }," >> "$ROUTE_MAP_OUTPUT"
done
# Remove trailing comma from last entry
sed -i '$ s/,$//' "$ROUTE_MAP_OUTPUT" 2>/dev/null || sed -i '' '$ s/,$//' "$ROUTE_MAP_OUTPUT" 2>/dev/null
fi
cat >> "$ROUTE_MAP_OUTPUT" << EOF
],
"api": [
EOF
# Add API routes
if [ -f "$API_ROUTES_FILE" ]; then
cat "$API_ROUTES_FILE" | while IFS='|' read -r type route file; do
echo " { \"path\": \"$route\", \"file\": \"$file\" }," >> "$ROUTE_MAP_OUTPUT"
done
# Remove trailing comma from last entry
sed -i '$ s/,$//' "$ROUTE_MAP_OUTPUT" 2>/dev/null || sed -i '' '$ s/,$//' "$ROUTE_MAP_OUTPUT" 2>/dev/null
fi
cat >> "$ROUTE_MAP_OUTPUT" << EOF
]
}
}
EOF
report_analysis "FOUND" "Route map generated: $ROUTE_MAP_OUTPUT"
fi
# Performance and optimization recommendations
echo "💡 Route optimization recommendations..." >&2
if [ "$DYNAMIC_ROUTES" -gt 10 ]; then
echo " • Consider using ISR for frequently accessed dynamic routes" >&2
fi
if [ "$API_ROUTES" -gt 0 ]; then
echo " • Consider API route optimization and caching strategies" >&2
fi
if [ "$CATCH_ALL_ROUTES" -gt 3 ]; then
echo " • Review catch-all routes for potential over-use" >&2
fi
if [ "$TOTAL_ROUTES" -gt 100 ]; then
echo " • Large application - consider route-based code splitting" >&2
fi
# Clean up temporary files
rm -f "$ROUTES_FILE" "$API_ROUTES_FILE" "$ROUTE_MAP_FILE"
echo "" >&2
echo "📋 Next.js Route Analysis Summary:" >&2
echo "=================================" >&2
echo " 📄 File analyzed: $(basename "$FILE_PATH")" >&2
echo " 🗺️ Total routes found: $((TOTAL_ROUTES + API_ROUTES))" >&2
echo " 📊 Route breakdown: $STATIC_ROUTES static, $DYNAMIC_ROUTES dynamic, $API_ROUTES API" >&2
echo " ⚠️ Warnings: $WARNINGS" >&2
echo " ❌ Errors: $ERRORS" >&2
if [ "$ERRORS" -eq 0 ]; then
if [ "$TOTAL_ROUTES" -gt 0 ] || [ "$API_ROUTES" -gt 0 ]; then
echo " 🎉 Status: SUCCESS - Route analysis complete" >&2
else
echo " ✅ Status: INFO - No routes found to analyze" >&2
fi
else
echo " ❌ Status: ISSUES - Route analysis completed with errors" >&2
fi
echo "" >&2
echo "💡 Next.js Routing Best Practices:" >&2
echo " • Use static routes when possible for better performance" >&2
echo " • Implement proper error boundaries for dynamic routes" >&2
echo " • Consider ISR for dynamic content that doesn't change often" >&2
echo " • Use API routes for server-side functionality" >&2
echo " • Organize routes logically with proper folder structure" >&2
echo " • Document your routing strategy for team collaboration" >&2
else
# Not a Next.js file, exit silently
exit 0
fi
exit 0
Complete hook script that performs Next.js route analysis
#!/usr/bin/env bash
INPUT=$(cat)
FILE_PATH=$(echo "$INPUT" | jq -r '.tool_input.file_path // .tool_input.path // ""')
if [ -z "$FILE_PATH" ]; then
exit 0
fi
if [[ "$FILE_PATH" == *pages/*.* ]] || [[ "$FILE_PATH" == *app/*.* ]]; then
echo "🗺️ Next.js Route Analysis for: $(basename "$FILE_PATH")" >&2
if [ -f "./package.json" ] && grep -q '"next"' "./package.json" 2>/dev/null; then
if [ -d "./app" ]; then
echo "🔧 App Router detected" >&2
find "./app" -name "page.tsx" -o -name "page.jsx" 2>/dev/null | while read file; do
ROUTE=$(echo "$file" | sed 's|^./app||' | sed 's|/page\.[jt]sx$||')
[ -z "$ROUTE" ] && ROUTE="/"
echo " 📋 $ROUTE" >&2
done
fi
fi
fi
exit 0
Complete hook configuration for .claude/settings.json to enable Next.js route analysis
{
"hooks": {
"postToolUse": {
"script": "./.claude/hooks/nextjs-route-analyzer.sh",
"matchers": ["write", "edit"]
}
}
}
Enhanced hook script for route type classification (static, dynamic, catch-all)
#!/usr/bin/env bash
INPUT=$(cat)
FILE_PATH=$(echo "$INPUT" | jq -r '.tool_input.file_path // .tool_input.path // ""')
if [[ "$FILE_PATH" == *app/* ]] || [[ "$FILE_PATH" == *pages/* ]]; then
if [ -d "./app" ]; then
find "./app" -type f \( -name "page.tsx" -o -name "page.jsx" -o -name "route.tsx" -o -name "route.jsx" \) 2>/dev/null | while read file; do
ROUTE=$(echo "$file" | sed 's|^./app||' | sed 's|/page\.[jt]sx$||' | sed 's|/route\.[jt]sx$||')
[ -z "$ROUTE" ] && ROUTE="/"
if [[ "$ROUTE" == *"["* ]]; then
if [[ "$ROUTE" == *"[..."* ]]; then
echo "🌐 Catch-all: $ROUTE" >&2
else
echo "🔧 Dynamic: $ROUTE" >&2
fi
else
echo "📋 Static: $ROUTE" >&2
fi
done
fi
fi
exit 0
Enhanced hook script for API route discovery in both App Router and Pages Router
#!/usr/bin/env bash
INPUT=$(cat)
FILE_PATH=$(echo "$INPUT" | jq -r '.tool_input.file_path // .tool_input.path // ""')
if [[ "$FILE_PATH" == *app/* ]] || [[ "$FILE_PATH" == *pages/* ]]; then
if [ -d "./app" ]; then
API_ROUTES=$(find "./app" -path "*/api/*" -name "route.tsx" -o -name "route.jsx" 2>/dev/null | wc -l | xargs)
if [ "$API_ROUTES" -gt 0 ]; then
echo "🚀 API Routes: $API_ROUTES endpoints" >&2
find "./app" -path "*/api/*" -name "route.tsx" -o -name "route.jsx" 2>/dev/null | while read file; do
API_PATH=$(echo "$file" | sed 's|^./app||' | sed 's|/route\.[jt]sx$||')
echo " • $API_PATH" >&2
done
fi
fi
if [ -d "./pages/api" ]; then
API_ROUTES=$(find "./pages/api" -name "*.tsx" -o -name "*.jsx" 2>/dev/null | wc -l | xargs)
if [ "$API_ROUTES" -gt 0 ]; then
echo "🚀 Pages Router API Routes: $API_ROUTES endpoints" >&2
fi
fi
fi
exit 0
Enhanced hook script for route groups and parallel routes detection
#!/usr/bin/env bash
INPUT=$(cat)
FILE_PATH=$(echo "$INPUT" | jq -r '.tool_input.file_path // .tool_input.path // ""')
if [[ "$FILE_PATH" == *app/* ]]; then
if [ -d "./app" ]; then
ROUTE_GROUPS=$(find "./app" -type d -name "(*)" 2>/dev/null | wc -l | xargs)
PARALLEL_ROUTES=$(find "./app" -type d -name "@*" 2>/dev/null | wc -l | xargs)
if [ "$ROUTE_GROUPS" -gt 0 ]; then
echo "📁 Route Groups: $ROUTE_GROUPS" >&2
find "./app" -type d -name "(*)" 2>/dev/null | while read dir; do
GROUP_NAME=$(basename "$dir" | sed 's/[()]//g')
echo " • ($GROUP_NAME)" >&2
done
fi
if [ "$PARALLEL_ROUTES" -gt 0 ]; then
echo "🔄 Parallel Routes: $PARALLEL_ROUTES" >&2
find "./app" -type d -name "@*" 2>/dev/null | while read dir; do
PARALLEL_NAME=$(basename "$dir" | sed 's/@//')
echo " • @$PARALLEL_NAME" >&2
done
fi
fi
fi
exit 0
Verify package.json contains 'next' dependency and run from project root. The hook checks both /pages and /app directories, and /src variants. Ensure at least one routing directory exists. Verify package.json location. Test with various project structures.
The sed command to remove trailing commas may fail on macOS. Update to use 'sed -i "" ' syntax for BSD sed, or install GNU sed with 'brew install gnu-sed'. Validate output with jq. Verify sed syntax. Test with various sed versions.
Ensure API routes use route.js/ts naming convention in App Router. The hook scans for /api/ path segments and route.* files. Pages Router uses pages/api/ directory structure. Verify route file naming. Test with various API route structures.
The hook identifies brackets in paths but doesn't parse parameter names. Use the generated nextjs-routes.json for accurate mapping. Review file paths in the 'file' property for exact parameter structure. Verify bracket pattern matching. Test with various dynamic route patterns.
The hook processes all files in pages/ or app/ directories. For large projects, consider adding file type filtering (_.tsx, _.jsx only) or exclude non-route files like components and utilities. Verify file path patterns. Test with various file types.
Route groups use (group) directory naming. Verify directory names match pattern: find with -name '(*)' pattern. Check for route group directories in app/ structure. Verify directory naming conventions. Test with various route group structures.
Parallel routes use @parallel directory naming. Verify directory names start with @: find with -name '@*' pattern. Check for parallel route directories in app/ structure. Verify directory naming conventions. Test with various parallel route structures.
Layout files are detected but not included in route map by default. Modify route map generation to include layout files in separate 'layouts' section. Verify layout file detection. Test with various layout structures.
Nextjs Route Analyzer - Hooks side by side with 3 alternatives on trust, install, platform support, and disclosed safety notes — all from reviewed registry metadata.
| Field | Analyzes Next.js page routes and generates a route map when pages are added or modified. Open dossier | Automated documentation coverage analysis with missing docstring detection, API documentation validation, and completeness scoring. This PostToolUse hook automatically checks documentation coverage when code files are modified, providing real-time documentation quality validation during development. Open dossier | Analyzes webpack bundle size when webpack config or entry files are modified. Open dossier | PostToolUse hook that extracts JSDoc and pydoc comments from modified API endpoint files and generates OpenAPI 3.1.0-compatible YAML documentation on every save. Open dossier |
|---|---|---|---|---|
| Next steps | ||||
| Trust | ||||
| Review status | ReviewedMaintainer reviewed | ReviewedMaintainer reviewed | ReviewedMaintainer reviewed | ReviewedMaintainer reviewed |
| Package trust | Package not verified | Package not verified | Package not verified | Package not verified |
| Source provenance | Source-backed | Source-backed | Source-backed | Source-backed |
| Submitter | — | — | — | — |
| Install risk | Review first | Review first | Review first | Review first |
| Notes | Safety ✓ Privacy ✓ | Safety ✓ Privacy ✓ | Safety ✓ Privacy ✓ | Safety ✓ Privacy ✓ |
| Brand | — | — | — | — |
| Category | hooks | hooks | hooks | hooks |
| Source | source-backed | source-backed | source-backed | source-backed |
| Author | JSONbored | JSONbored | JSONbored | JSONbored |
| Added | 2025-09-19 | 2025-10-19 | 2025-09-19 | 2025-09-19 |
| Platforms | Claude Code | Claude Code | Claude Code | Claude Code |
| Source repo | — | — | — | — |
| Safety notes | ✓Runs automatically on its configured Claude Code hook event and executes shell logic that can read, modify, or delete files in your project (and may run builds, installs, or network calls); review the script and scope it to expected paths before enabling. | ✓Runs automatically on its configured Claude Code hook event and executes shell logic that can read, modify, or delete files in your project (and may run builds, installs, or network calls); review the script and scope it to expected paths before enabling. | ✓Runs automatically on its configured Claude Code hook event and executes shell logic that can read, modify, or delete files in your project (and may run builds, installs, or network calls); review the script and scope it to expected paths before enabling. | ✓Runs automatically after write or edit tool calls on route, controller, and API files. Invokes npx swagger-jsdoc or npx jsdoc to generate docs; executes python -m pydoc for Python files. Writes generated documentation files to ./docs/api/ in the project directory. |
| Privacy notes | ✓Receives Claude Code hook input (session metadata, file paths, and tool output) and reads local project files; review what the script logs or forwards to external services and keep credentials out of its output. | ✓Receives Claude Code hook input (session metadata, file paths, and tool output) and reads local project files; review what the script logs or forwards to external services and keep credentials out of its output. | ✓Receives Claude Code hook input (session metadata, file paths, and tool output) and reads local project files; review what the script logs or forwards to external services and keep credentials out of its output. | ✓Receives Claude Code hook input (session metadata, file paths, and tool output) and reads local project files; review what the script logs or forwards to external services and keep credentials out of its output. |
| Prerequisites | — none listed | — none listed | — none listed | — none listed |
| Install | | | | |
| Config | | | | |
| Citations | ||||
| Claim | Unclaimed | Unclaimed | Unclaimed | Unclaimed |
Loading live community signals…
A short, calm digest of reviewed Claude resources. Unsubscribe any time.