2025-08-11 05:58:27 -06:00
{% extends "base.html" %}
{% block title %}{{ title }}{% endblock %}
{% block content %}
< div class = "container-fluid" >
< div class = "row" >
< div class = "col-md-12" >
<!-- Header -->
< div class = "d-flex justify-content-between align-items-center mb-4" >
< div >
< nav aria-label = "breadcrumb" >
< ol class = "breadcrumb" >
< li class = "breadcrumb-item" > < a href = "/dashboard/docs" > Documentation< / a > < / li >
< li class = "breadcrumb-item active" aria-current = "page" > Hook Setup Guide< / li >
< / ol >
< / nav >
< h2 > < i class = "fas fa-link me-3" > < / i > Hook Setup Guide< / h2 >
< p class = "lead text-muted" > Configure Claude Code hooks for automatic activity tracking< / p >
< / div >
< div class = "text-muted" >
< i class = "fas fa-clock me-1" > < / i >
10 min read
< / div >
< / div >
< div class = "row" >
< div class = "col-lg-8" >
<!-- Overview -->
< div class = "card border-0 shadow-sm mb-4" >
< div class = "card-body" >
< h3 > < i class = "fas fa-info-circle me-2 text-primary" > < / i > What are Claude Code Hooks?< / h3 >
< p > Claude Code hooks are callback mechanisms that allow external applications (like this tracker) to receive notifications about various events in your Claude Code sessions. They enable real-time tracking of your development activity without manual intervention.< / p >
< div class = "alert alert-info" >
< i class = "fas fa-lightbulb me-2" > < / i >
< strong > Benefits:< / strong > Hooks provide automatic, real-time data collection, ensuring you never miss tracking a session or conversation.
< / div >
< / div >
< / div >
<!-- Hook Types -->
< div class = "card border-0 shadow-sm mb-4" >
< div class = "card-header bg-primary text-white" >
< h3 class = "mb-0" > < i class = "fas fa-list me-2" > < / i > Available Hook Types< / h3 >
< / div >
< div class = "card-body" >
< div class = "row" >
< div class = "col-md-6 mb-3" >
< div class = "card border-0 bg-light h-100" >
< div class = "card-body" >
< h5 > < i class = "fas fa-play-circle me-2 text-success" > < / i > session_start< / h5 >
< p class = "text-muted small mb-2" > Triggered when a new Claude Code session begins< / p >
< div class = "badge bg-success" > Required< / div >
< / div >
< / div >
< / div >
< div class = "col-md-6 mb-3" >
< div class = "card border-0 bg-light h-100" >
< div class = "card-body" >
< h5 > < i class = "fas fa-stop-circle me-2 text-danger" > < / i > session_end< / h5 >
< p class = "text-muted small mb-2" > Triggered when a Claude Code session ends< / p >
< div class = "badge bg-success" > Required< / div >
< / div >
< / div >
< / div >
< div class = "col-md-6 mb-3" >
< div class = "card border-0 bg-light h-100" >
< div class = "card-body" >
< h5 > < i class = "fas fa-comments me-2 text-info" > < / i > conversation_update< / h5 >
< p class = "text-muted small mb-2" > Triggered when conversation messages are added< / p >
< div class = "badge bg-warning" > Recommended< / div >
< / div >
< / div >
< / div >
< div class = "col-md-6 mb-3" >
< div class = "card border-0 bg-light h-100" >
< div class = "card-body" >
< h5 > < i class = "fas fa-file-edit me-2 text-warning" > < / i > file_modified< / h5 >
< p class = "text-muted small mb-2" > Triggered when files are created or modified< / p >
< div class = "badge bg-info" > Optional< / div >
< / div >
< / div >
< / div >
< div class = "col-md-6 mb-3" >
< div class = "card border-0 bg-light h-100" >
< div class = "card-body" >
< h5 > < i class = "fas fa-tools me-2 text-primary" > < / i > tool_call< / h5 >
< p class = "text-muted small mb-2" > Triggered when Claude Code tools are used< / p >
< div class = "badge bg-warning" > Recommended< / div >
< / div >
< / div >
< / div >
< / div >
< / div >
< / div >
2025-08-11 09:30:37 -06:00
<!-- Automatic Installation -->
2025-08-11 05:58:27 -06:00
< div class = "card border-0 shadow-sm mb-4" >
< div class = "card-header bg-success text-white" >
2025-08-11 09:30:37 -06:00
< h3 class = "mb-0" > < i class = "fas fa-magic me-2" > < / i > Automatic Installation (Recommended)< / h3 >
< / div >
< div class = "card-body" >
< p > The easiest way to set up hooks is using our automated installation script that configures everything for you.< / p >
< div class = "alert alert-success" >
< h5 > < i class = "fas fa-rocket me-1" > < / i > Quick Setup< / h5 >
< p class = "mb-2" > For most users, this one-liner will set up everything you need:< / p >
< pre class = "bg-dark text-light p-3 rounded" > < code > # Set your domain and run the installer
export DOMAIN=claude.l.supported.systems
./setup-hooks< / code > < / pre >
< / div >
< h5 class = "mt-4" > < i class = "fas fa-cog me-2" > < / i > Installation Options< / h5 >
< div class = "row" >
< div class = "col-md-6" >
< div class = "card bg-light" >
< div class = "card-header" >
< strong > Basic Installation< / strong >
< / div >
< div class = "card-body" >
< pre > < code > # Install basic hook set
./install-hooks.sh basic< / code > < / pre >
< p class = "small text-muted mb-0" > Includes essential session and conversation tracking< / p >
< / div >
< / div >
< / div >
< div class = "col-md-6" >
< div class = "card bg-light" >
< div class = "card-header" >
< strong > Comprehensive Installation< / strong >
< / div >
< div class = "card-body" >
< pre > < code > # Install all available hooks
./install-hooks.sh comprehensive< / code > < / pre >
< p class = "small text-muted mb-0" > Includes all 39+ hooks for complete tracking< / p >
< / div >
< / div >
< / div >
< / div >
< h5 class = "mt-4" > < i class = "fas fa-list me-2" > < / i > Available Profiles< / h5 >
< div class = "row" >
< div class = "col-md-6" >
< ul class = "list-unstyled" >
< li class = "mb-2" > < span class = "badge bg-primary me-2" > basic< / span > Essential hooks only< / li >
< li class = "mb-2" > < span class = "badge bg-success me-2" > essential< / span > Core development tracking< / li >
< li class = "mb-2" > < span class = "badge bg-info me-2" > comprehensive< / span > All available hooks< / li >
< li class = "mb-2" > < span class = "badge bg-warning me-2" > developer< / span > For active developers< / li >
< / ul >
< / div >
< div class = "col-md-6" >
< ul class = "list-unstyled" >
< li class = "mb-2" > < span class = "badge bg-secondary me-2" > power_user< / span > Advanced tracking features< / li >
< li class = "mb-2" > < span class = "badge bg-dark me-2" > research< / span > Research and analytics focused< / li >
< li class = "mb-2" > < span class = "badge bg-purple me-2" > team< / span > Team collaboration features< / li >
< / ul >
< / div >
< / div >
< div class = "alert alert-info mt-3" >
< h6 > < i class = "fas fa-terminal me-1" > < / i > Script Commands< / h6 >
< ul class = "mb-0" >
< li > < code > ./install-hooks.sh --list< / code > - List available profiles< / li >
< li > < code > ./install-hooks.sh --verify< / code > - Verify installation< / li >
< li > < code > ./install-hooks.sh --uninstall< / code > - Remove all hooks< / li >
< li > < code > ./install-hooks.sh --help< / code > - Show detailed help< / li >
< / ul >
< / div >
< / div >
< / div >
<!-- Manual Setup Instructions -->
< div class = "card border-0 shadow-sm mb-4" >
< div class = "card-header bg-warning text-dark" >
< h3 class = "mb-0" > < i class = "fas fa-wrench me-2" > < / i > Manual Setup Instructions< / h3 >
2025-08-11 05:58:27 -06:00
< / div >
< div class = "card-body" >
<!-- Step 1: Ensure Server Running -->
< div class = "d-flex align-items-start mb-4 pb-4 border-bottom" >
< div class = "bg-primary rounded-circle text-white d-flex align-items-center justify-content-center me-3" style = "width: 40px; height: 40px; min-width: 40px;" >
< strong > 1< / strong >
< / div >
< div class = "flex-grow-1" >
< h5 class = "mb-2" > Ensure Claude Code Tracker is Running< / h5 >
< p class = "text-muted mb-3" > The tracker server must be running to receive hook notifications.< / p >
< div class = "bg-dark text-light p-3 rounded mb-3" >
< h6 class = "text-light" > < i class = "fas fa-terminal me-2" > < / i > Start the server:< / h6 >
< code > python main.py< / code >
< br > < small class = "text-muted" > Server runs on http://localhost:8000 by default< / small >
< / div >
< div class = "alert alert-info mb-0" >
< i class = "fas fa-info-circle me-2" > < / i >
Keep the server running while using Claude Code to ensure hooks work properly.
< / div >
< / div >
< / div >
<!-- Step 2: Locate Settings File -->
< div class = "d-flex align-items-start mb-4 pb-4 border-bottom" >
< div class = "bg-warning rounded-circle text-dark d-flex align-items-center justify-content-center me-3" style = "width: 40px; height: 40px; min-width: 40px;" >
< strong > 2< / strong >
< / div >
< div class = "flex-grow-1" >
< h5 class = "mb-2" > Locate Claude Code Settings< / h5 >
< p class = "text-muted mb-3" > Find your Claude Code configuration file to add hooks.< / p >
< div class = "row" >
< div class = "col-md-4 mb-3" >
< div class = "card border-0 bg-light" >
< div class = "card-body p-3" >
< h6 > < i class = "fab fa-apple me-2" > < / i > macOS< / h6 >
< code class = "small" > ~/.config/claude/settings.json< / code >
< / div >
< / div >
< / div >
< div class = "col-md-4 mb-3" >
< div class = "card border-0 bg-light" >
< div class = "card-body p-3" >
< h6 > < i class = "fab fa-linux me-2" > < / i > Linux< / h6 >
< code class = "small" > ~/.config/claude/settings.json< / code >
< / div >
< / div >
< / div >
< div class = "col-md-4 mb-3" >
< div class = "card border-0 bg-light" >
< div class = "card-body p-3" >
< h6 > < i class = "fab fa-windows me-2" > < / i > Windows< / h6 >
< code class = "small" > %APPDATA%\claude\settings.json< / code >
< / div >
< / div >
< / div >
< / div >
< div class = "alert alert-warning mb-0" >
< i class = "fas fa-exclamation-triangle me-2" > < / i >
< strong > Note:< / strong > If the file doesn't exist, create it with the hook configuration below.
< / div >
< / div >
< / div >
<!-- Step 3: Add Hook Configuration -->
< div class = "d-flex align-items-start" >
< div class = "bg-success rounded-circle text-white d-flex align-items-center justify-content-center me-3" style = "width: 40px; height: 40px; min-width: 40px;" >
< strong > 3< / strong >
< / div >
< div class = "flex-grow-1" >
< h5 class = "mb-2" > Add Hook Configuration< / h5 >
< p class = "text-muted mb-3" > Add the hook configuration to your Claude Code settings file.< / p >
< div class = "nav nav-tabs" id = "configTabs" role = "tablist" >
< button class = "nav-link active" id = "basic-tab" data-bs-toggle = "tab" data-bs-target = "#basic" type = "button" >
< i class = "fas fa-rocket me-1" > < / i > Basic Setup
< / button >
< button class = "nav-link" id = "advanced-tab" data-bs-toggle = "tab" data-bs-target = "#advanced" type = "button" >
< i class = "fas fa-cogs me-1" > < / i > Advanced Setup
< / button >
< button class = "nav-link" id = "custom-tab" data-bs-toggle = "tab" data-bs-target = "#custom" type = "button" >
< i class = "fas fa-edit me-1" > < / i > Custom Port
< / button >
< / div >
< div class = "tab-content" id = "configTabsContent" >
<!-- Basic Setup -->
< div class = "tab-pane fade show active" id = "basic" role = "tabpanel" >
< div class = "bg-dark text-light p-3 rounded mt-3" >
< div class = "d-flex justify-content-between align-items-center mb-2" >
< h6 class = "text-light mb-0" > Basic Configuration< / h6 >
< button class = "btn btn-sm btn-outline-light" onclick = "copyToClipboard('basic-config')" >
< i class = "fas fa-copy me-1" > < / i > Copy
< / button >
< / div >
< pre id = "basic-config" class = "mb-0" > < code > {
"hooks": {
"session_start": "curl -X POST http://localhost:8000/api/sessions/start -H 'Content-Type: application/json' -d '{\"project_path\": \"$PWD\", \"start_time\": \"$TIMESTAMP\"}'",
"session_end": "curl -X POST http://localhost:8000/api/sessions/end -H 'Content-Type: application/json' -d '{\"session_id\": \"$SESSION_ID\", \"end_time\": \"$TIMESTAMP\"}'",
"conversation_update": "curl -X POST http://localhost:8000/api/conversations -H 'Content-Type: application/json' -d '{\"session_id\": \"$SESSION_ID\", \"content\": \"$CONTENT\"}'",
"tool_call": "curl -X POST http://localhost:8000/api/tool-calls -H 'Content-Type: application/json' -d '{\"tool_name\": \"$TOOL_NAME\", \"parameters\": $TOOL_PARAMS, \"result_status\": \"$RESULT_STATUS\", \"execution_time_ms\": $EXECUTION_TIME}'"
}
}< / code > < / pre >
< / div >
< / div >
<!-- Advanced Setup -->
< div class = "tab-pane fade" id = "advanced" role = "tabpanel" >
< div class = "bg-dark text-light p-3 rounded mt-3" >
< div class = "d-flex justify-content-between align-items-center mb-2" >
< h6 class = "text-light mb-0" > Advanced Configuration< / h6 >
< button class = "btn btn-sm btn-outline-light" onclick = "copyToClipboard('advanced-config')" >
< i class = "fas fa-copy me-1" > < / i > Copy
< / button >
< / div >
< pre id = "advanced-config" class = "mb-0" > < code > {
"hooks": {
"session_start": "curl -X POST http://localhost:8000/api/sessions/start -H 'Content-Type: application/json' -d '{\"project_path\": \"$PWD\", \"start_time\": \"$TIMESTAMP\", \"user\": \"$USER\"}'",
"session_end": "curl -X POST http://localhost:8000/api/sessions/end -H 'Content-Type: application/json' -d '{\"session_id\": \"$SESSION_ID\", \"end_time\": \"$TIMESTAMP\"}'",
"conversation_update": "curl -X POST http://localhost:8000/api/conversations -H 'Content-Type: application/json' -d '{\"session_id\": \"$SESSION_ID\", \"content\": \"$CONTENT\", \"timestamp\": \"$TIMESTAMP\"}'",
"file_modified": "curl -X POST http://localhost:8000/api/activities -H 'Content-Type: application/json' -d '{\"session_id\": \"$SESSION_ID\", \"file_path\": \"$FILE_PATH\", \"action\": \"$ACTION\", \"timestamp\": \"$TIMESTAMP\"}'",
"tool_call": "curl -X POST http://localhost:8000/api/tool-calls -H 'Content-Type: application/json' -d '{\"tool_name\": \"$TOOL_NAME\", \"parameters\": $TOOL_PARAMS, \"result_status\": \"$RESULT_STATUS\", \"execution_time_ms\": $EXECUTION_TIME, \"timestamp\": \"$TIMESTAMP\"}'"
},
"hook_settings": {
"timeout": 5,
"retry_count": 3,
"async": true
}
}< / code > < / pre >
< / div >
< / div >
<!-- Custom Port -->
< div class = "tab-pane fade" id = "custom" role = "tabpanel" >
< div class = "alert alert-info mt-3" >
< i class = "fas fa-info-circle me-2" > < / i >
If you're running the tracker on a different port, update the URLs accordingly.
< / div >
< div class = "bg-dark text-light p-3 rounded" >
< div class = "d-flex justify-content-between align-items-center mb-2" >
< h6 class = "text-light mb-0" > Custom Port Configuration< / h6 >
< button class = "btn btn-sm btn-outline-light" onclick = "copyToClipboard('custom-config')" >
< i class = "fas fa-copy me-1" > < / i > Copy
< / button >
< / div >
< pre id = "custom-config" class = "mb-0" > < code > {
"hooks": {
"session_start": "curl -X POST http://localhost:YOUR_PORT/api/sessions/start -H 'Content-Type: application/json' -d '{\"project_path\": \"$PWD\", \"start_time\": \"$TIMESTAMP\"}'",
"session_end": "curl -X POST http://localhost:YOUR_PORT/api/sessions/end -H 'Content-Type: application/json' -d '{\"session_id\": \"$SESSION_ID\", \"end_time\": \"$TIMESTAMP\"}'",
"conversation_update": "curl -X POST http://localhost:YOUR_PORT/api/conversations -H 'Content-Type: application/json' -d '{\"session_id\": \"$SESSION_ID\", \"content\": \"$CONTENT\"}'",
"tool_call": "curl -X POST http://localhost:YOUR_PORT/api/tool-calls -H 'Content-Type: application/json' -d '{\"tool_name\": \"$TOOL_NAME\", \"parameters\": $TOOL_PARAMS, \"result_status\": \"$RESULT_STATUS\"}'"
}
}< / code > < / pre >
< small class = "text-muted" > Replace YOUR_PORT with your actual port number< / small >
< / div >
< / div >
< / div >
< / div >
< / div >
< / div >
< / div >
<!-- Available Variables -->
< div class = "card border-0 shadow-sm mb-4" >
< div class = "card-body" >
< h3 > < i class = "fas fa-dollar-sign me-2 text-info" > < / i > Available Variables< / h3 >
< p class = "text-muted mb-4" > Claude Code provides these variables that you can use in your hook commands:< / p >
< div class = "row" >
< div class = "col-md-6" >
< div class = "card border-0 bg-light" >
< div class = "card-body" >
< h6 > < i class = "fas fa-clock text-primary me-2" > < / i > Session Variables< / h6 >
< ul class = "list-unstyled mb-0" >
< li class = "mb-2" >
< code > $SESSION_ID< / code >
< br > < small class = "text-muted" > Unique session identifier< / small >
< / li >
< li class = "mb-2" >
< code > $TIMESTAMP< / code >
< br > < small class = "text-muted" > Current timestamp (ISO format)< / small >
< / li >
< li >
< code > $PWD< / code >
< br > < small class = "text-muted" > Current working directory< / small >
< / li >
< / ul >
< / div >
< / div >
< / div >
< div class = "col-md-6" >
< div class = "card border-0 bg-light" >
< div class = "card-body" >
< h6 > < i class = "fas fa-user text-success me-2" > < / i > Context Variables< / h6 >
< ul class = "list-unstyled mb-0" >
< li class = "mb-2" >
< code > $USER< / code >
< br > < small class = "text-muted" > Current system user< / small >
< / li >
< li class = "mb-2" >
< code > $CONTENT< / code >
< br > < small class = "text-muted" > Conversation content< / small >
< / li >
< li class = "mb-2" >
< code > $FILE_PATH< / code >
< br > < small class = "text-muted" > Modified file path< / small >
< / li >
< li class = "mb-2" >
< code > $TOOL_NAME< / code >
< br > < small class = "text-muted" > Name of tool being called< / small >
< / li >
< li class = "mb-2" >
< code > $TOOL_PARAMS< / code >
< br > < small class = "text-muted" > Tool parameters (JSON object)< / small >
< / li >
< li >
< code > $RESULT_STATUS< / code >
< br > < small class = "text-muted" > Success/error status< / small >
< / li >
< / ul >
< / div >
< / div >
< / div >
< / div >
< / div >
< / div >
<!-- Testing Hooks -->
< div class = "card border-0 shadow-sm mb-4" >
< div class = "card-body" >
< h3 > < i class = "fas fa-vial me-2 text-warning" > < / i > Testing Your Hook Setup< / h3 >
< div class = "alert alert-success" >
< i class = "fas fa-check-circle me-2" > < / i >
< strong > Quick Test:< / strong > Start a new Claude Code session after setting up hooks. You should see new data appearing in the tracker dashboard.
< / div >
< h5 > Manual Testing< / h5 >
< p > You can test individual hooks manually to ensure they work:< / p >
< div class = "bg-dark text-light p-3 rounded mb-3" >
< h6 class = "text-light" > Test session start hook:< / h6 >
< code > curl -X POST http://localhost:8000/api/sessions/start -H 'Content-Type: application/json' -d '{"project_path": "/path/to/project", "start_time": "2024-01-01T12:00:00"}'< / code >
< / div >
< div class = "bg-dark text-light p-3 rounded mb-3" >
< h6 class = "text-light" > Check server logs:< / h6 >
< code > tail -f logs/tracker.log< / code >
< / div >
< h5 class = "mt-4" > Troubleshooting< / h5 >
< div class = "accordion" id = "testingAccordion" >
< div class = "accordion-item border-0" >
< h2 class = "accordion-header" >
< button class = "accordion-button collapsed bg-light" type = "button" data-bs-toggle = "collapse" data-bs-target = "#collapseTest1" >
Hook commands not executing
< / button >
< / h2 >
< div id = "collapseTest1" class = "accordion-collapse collapse" data-bs-parent = "#testingAccordion" >
< div class = "accordion-body" >
< ul >
< li > Check that curl is installed on your system< / li >
< li > Verify the tracker server is running< / li >
< li > Test the hook URL manually in a browser or with curl< / li >
< li > Check Claude Code logs for hook execution errors< / li >
< / ul >
< / div >
< / div >
< / div >
< div class = "accordion-item border-0" >
< h2 class = "accordion-header" >
< button class = "accordion-button collapsed bg-light" type = "button" data-bs-toggle = "collapse" data-bs-target = "#collapseTest2" >
Data not appearing in tracker
< / button >
< / h2 >
< div id = "collapseTest2" class = "accordion-collapse collapse" data-bs-parent = "#testingAccordion" >
< div class = "accordion-body" >
< ul >
< li > Check the tracker server logs for incoming requests< / li >
< li > Verify the JSON payload format matches API expectations< / li >
< li > Ensure the database is writable< / li >
< li > Try refreshing the dashboard after a few minutes< / li >
< / ul >
< / div >
< / div >
< / div >
< / div >
< / div >
< / div >
< / div >
<!-- Sidebar -->
< div class = "col-lg-4" >
< div class = "sticky-top" style = "top: 2rem;" >
<!-- Quick Reference -->
< div class = "card border-0 shadow-sm mb-4" >
< div class = "card-header bg-success text-white" >
< h5 class = "mb-0" > < i class = "fas fa-bolt me-2" > < / i > Quick Reference< / h5 >
< / div >
< div class = "card-body" >
< h6 > Default Server URL< / h6 >
< code class = "d-block mb-3 p-2 bg-light rounded" > http://localhost:8000< / code >
< h6 > Settings File Location< / h6 >
< div class = "small" >
< div class = "mb-2" > < strong > macOS/Linux:< / strong > < / div >
< code class = "d-block mb-2 p-2 bg-light rounded small" > ~/.config/claude/settings.json< / code >
< div class = "mb-2" > < strong > Windows:< / strong > < / div >
< code class = "d-block p-2 bg-light rounded small" > %APPDATA%\claude\settings.json< / code >
< / div >
< / div >
< / div >
<!-- Table of Contents -->
< div class = "card border-0 shadow-sm mb-4" >
< div class = "card-header bg-light" >
< h6 class = "mb-0" > < i class = "fas fa-list me-2" > < / i > Contents< / h6 >
< / div >
< div class = "card-body" >
< nav class = "nav nav-pills flex-column" >
< a class = "nav-link py-1 px-2 text-sm" href = "#overview" > What are hooks?< / a >
< a class = "nav-link py-1 px-2 text-sm" href = "#types" > Hook types< / a >
< a class = "nav-link py-1 px-2 text-sm" href = "#setup" > Setup instructions< / a >
< a class = "nav-link py-1 px-2 text-sm" href = "#variables" > Available variables< / a >
< a class = "nav-link py-1 px-2 text-sm" href = "#testing" > Testing hooks< / a >
< / nav >
< / div >
< / div >
<!-- Help -->
< div class = "card border-0 shadow-sm" >
< div class = "card-header bg-warning text-dark" >
< h6 class = "mb-0" > < i class = "fas fa-life-ring me-2" > < / i > Need Help?< / h6 >
< / div >
< div class = "card-body" >
< p class = "small text-muted mb-3" > Still having trouble with hooks?< / p >
< div class = "d-grid gap-2" >
< a href = "/dashboard/docs/faq" class = "btn btn-outline-warning btn-sm" >
< i class = "fas fa-question-circle me-1" > < / i >
Check FAQ
< / a >
< a href = "/dashboard/docs/api-reference" class = "btn btn-outline-info btn-sm" >
< i class = "fas fa-code me-1" > < / i >
API Reference
< / a >
< / div >
< / div >
< / div >
< / div >
< / div >
< / div >
< / div >
< / div >
< / div >
< script >
function copyToClipboard(elementId) {
const element = document.getElementById(elementId);
const text = element.textContent;
navigator.clipboard.writeText(text).then(function() {
// Show success feedback
const button = element.parentElement.querySelector('button');
const originalText = button.innerHTML;
button.innerHTML = '< i class = "fas fa-check me-1" > < / i > Copied!';
button.classList.add('btn-success');
button.classList.remove('btn-outline-light');
setTimeout(function() {
button.innerHTML = originalText;
button.classList.remove('btn-success');
button.classList.add('btn-outline-light');
}, 2000);
});
}
< / script >
{% endblock %}