| name | docs-analytics |
| description | Documentation usage analytics and insights. Integrate with Google Analytics, Algolia analytics, and custom tracking to measure documentation effectiveness, identify content gaps, and optimize user journeys. |
| allowed-tools | Read, Write, Edit, Bash, Glob, Grep |
| backlog-id | SK-018 |
| metadata | {"author":"babysitter-sdk","version":"1.0.0"} |
| graph | {"domains":["domain:software-engineering"],"specializations":["specialization:technical-documentation"],"skillAreas":["skill-area:analytics-tracking","skill-area:docs-as-code"],"roles":["role:technical-writer","role:documentation-engineer"]} |
Documentation Analytics Skill
Measure documentation effectiveness with analytics integration, search insights, user journey analysis, and content performance metrics.
Capabilities
- Google Analytics integration for documentation sites
- Algolia analytics for search patterns
- User journey analysis and flow tracking
- Content engagement metrics
- Search query analysis and gap identification
- Page performance metrics
- Heatmap integration (Hotjar, etc.)
- Custom event tracking
- Documentation ROI measurement
Usage
Invoke this skill when you need to:
- Set up documentation analytics
- Analyze documentation usage patterns
- Identify content gaps from search data
- Measure documentation effectiveness
- Optimize user journeys through docs
Inputs
| Parameter | Type | Required | Description |
|---|
| docsUrl | string | Yes | Documentation site URL |
| analyticsProvider | string | No | ga4, algolia, plausible, custom |
| trackingId | string | No | Analytics tracking ID |
| algoliaAppId | string | No | Algolia application ID |
| algoliaApiKey | string | No | Algolia API key for analytics |
| enableHeatmaps | boolean | No | Enable heatmap tracking |
| customEvents | array | No | Custom events to track |
Input Example
{
"docsUrl": "https://docs.example.com",
"analyticsProvider": "ga4",
"trackingId": "G-XXXXXXXXXX",
"algoliaAppId": "ALGOLIA_APP_ID",
"enableHeatmaps": true,
"customEvents": [
"code_copy",
"feedback_submitted",
"version_switch"
]
}
Output Structure
analytics/
├── reports/
│ ├── monthly-summary.json
│ ├── search-analysis.json
│ ├── content-gaps.json
│ └── user-journeys.json
├── dashboards/
│ ├── overview.html
│ └── search-insights.html
└── config/
├── ga4-config.json
└── algolia-config.json
Google Analytics 4 Integration
GA4 Configuration
window.dataLayer = window.dataLayer || [];
function gtag() {
dataLayer.push(arguments);
}
gtag('js', new Date());
gtag('config', 'G-XXXXXXXXXX', {
custom_map: {
dimension1: 'doc_version',
dimension2: 'doc_section',
dimension3: 'search_query',
dimension4: 'code_language',
},
});
gtag('set', 'user_properties', {
doc_version: document.querySelector('meta[name="docs-version"]')?.content,
});
Custom Events
document.querySelectorAll('pre code').forEach((block) => {
block.addEventListener('click', () => {
gtag('event', 'code_copy', {
event_category: 'engagement',
event_label: block.className,
page_location: window.location.href,
});
});
});
function trackFeedback(helpful, pageUrl) {
gtag('event', 'doc_feedback', {
event_category: 'feedback',
event_label: helpful ? 'helpful' : 'not_helpful',
page_location: pageUrl,
});
}
function trackVersionSwitch(fromVersion, toVersion) {
gtag('event', 'version_switch', {
event_category: 'navigation',
from_version: fromVersion,
to_version: toVersion,
});
}
let startTime = Date.();
.(, {
timeSpent = .((.() - startTime) / );
(, , {
: ,
: timeSpent,
: ..,
});
});
maxScroll = ;
.(, {
scrollPercent = .(
(. / (.. - .)) *
);
(scrollPercent > maxScroll) {
maxScroll = scrollPercent;
([, , , , ].(scrollPercent)) {
(, , {
: ,
: scrollPercent,
: ..,
});
}
}
});
.().( {
link.(, {
(, , {
: ,
: link.,
: ..,
});
});
});
Algolia Analytics Integration
DocSearch Analytics
import docsearch from '@docsearch/js';
docsearch({
appId: 'YOUR_APP_ID',
apiKey: 'YOUR_SEARCH_API_KEY',
indexName: 'YOUR_INDEX_NAME',
container: '#docsearch',
debug: false,
insights: true,
searchParameters: {
analytics: true,
clickAnalytics: true,
enablePersonalization: false,
},
});
Search Analytics API
const algoliasearch = require('algoliasearch');
const analyticsClient = algoliasearch('APP_ID', 'ADMIN_API_KEY');
async function getSearchAnalytics() {
const index = analyticsClient.initIndex('docs');
const topSearches = await analyticsClient.customRequest({
method: 'GET',
path: '/2/searches',
data: {
index: 'docs',
startDate: '2026-01-01',
endDate: '2026-01-24',
limit: 100,
orderBy: 'searchCount',
},
});
const noResultSearches = await analyticsClient.customRequest({
method: 'GET',
path: '/2/searches/noResults',
data: {
index: 'docs',
startDate: '2026-01-01',
endDate: '2026-01-24',
limit: ,
},
});
clickAnalytics = analyticsClient.({
: ,
: ,
: {
: ,
: ,
: ,
},
});
{
: topSearches.,
: noResultSearches.,
: clickAnalytics,
};
}
Search Gap Analysis
async function analyzeContentGaps(noResultSearches) {
const gaps = [];
for (const search of noResultSearches) {
const category = categorizeQuery(search.search);
gaps.push({
query: search.search,
count: search.count,
category,
suggestedContent: generateContentSuggestion(search.search),
priority: calculatePriority(search.count),
});
}
return gaps.sort((a, b) => b.count - a.count);
}
function categorizeQuery(query) {
const categories = {
api: /api|endpoint|rest|graphql|webhook/i,
authentication: /auth|login|oauth|token|api.?key/i,
integration: /integrate|connect|setup|install/i,
error: /error|fail|issue|problem|not.?work/i,
pricing: /price|cost|plan|billing/i,
};
for (const [category, pattern] of Object.(categories)) {
(pattern.(query)) category;
}
;
}
User Journey Analysis
Journey Tracking
const journey = {
sessionId: generateSessionId(),
startTime: Date.now(),
pages: [],
searches: [],
events: [],
};
function trackPageView(pageUrl, pageTitle) {
journey.pages.push({
url: pageUrl,
title: pageTitle,
timestamp: Date.now(),
timeOnPrevPage: calculateTimeOnPrevPage(),
});
}
function trackSearch(query, results) {
journey.searches.push({
query,
resultsCount: results.length,
timestamp: Date.now(),
clickedResult: null,
});
}
function trackSearchClick(query, resultUrl, position) {
const search = journey.searches.find((s) => s.query === query);
if (search) {
search.clickedResult = { url: resultUrl, position };
}
}
() {
{
: journey..,
: .() - journey.,
: (journey),
: (journey.),
: (journey.),
};
}
Common Journey Patterns
async function getCommonPaths(journeys) {
const pathCounts = {};
journeys.forEach((journey) => {
const path = journey.pages
.map((p) => p.url)
.slice(0, 5)
.join(' -> ');
pathCounts[path] = (pathCounts[path] || 0) + 1;
});
return Object.entries(pathCounts)
.sort((a, b) => b[1] - a[1])
.slice(0, 20)
.map(([path, count]) => ({
path,
count,
percentage: ((count / journeys.length) * 100).toFixed(1),
}));
}
Content Performance Metrics
Engagement Metrics
function calculateEngagementScore(pageMetrics) {
const weights = {
avgTimeOnPage: 0.3,
scrollDepth: 0.2,
codeBlockInteractions: 0.2,
feedbackScore: 0.15,
exitRate: -0.15,
};
return Object.entries(weights).reduce((score, [metric, weight]) => {
return score + normalizeMetric(pageMetrics[metric]) * weight;
}, 0);
}
function generatePageReport(pageUrl) {
return {
url: pageUrl,
metrics: {
pageviews: getPageviews(pageUrl),
uniqueVisitors: getUniqueVisitors(pageUrl),
avgTimeOnPage: getAvgTimeOnPage(pageUrl),
bounceRate: getBounceRate(pageUrl),
exitRate: getExitRate(pageUrl),
scrollDepth: {
'25%': getScrollDepthPercent(pageUrl, 25),
'50%': getScrollDepthPercent(pageUrl, ),
: (pageUrl, ),
: (pageUrl, ),
},
: {
: (pageUrl),
: (pageUrl),
: (pageUrl),
},
: (pageUrl),
},
: (pageMetrics),
: (pageMetrics),
};
}
Content Gap Report
{
"period": "2026-01",
"summary": {
"totalSearches": 45230,
"uniqueSearches": 8432,
"noResultSearches": 1234,
"avgClickThroughRate": 0.68
},
"contentGaps": [
{
"query": "webhook authentication",
"searchCount": 342,
"category": "authentication",
"suggestedContent": {
"type": "guide",
"title": "Webhook Authentication Guide",
"outline": [
"Introduction to webhook security"
Dashboard Configuration
Docusaurus Analytics
module.exports = {
plugins: [
[
'@docusaurus/plugin-google-gtag',
{
trackingID: 'G-XXXXXXXXXX',
anonymizeIP: true,
},
],
],
themeConfig: {
algolia: {
appId: 'YOUR_APP_ID',
apiKey: 'YOUR_SEARCH_API_KEY',
indexName: 'YOUR_INDEX_NAME',
insights: true,
},
},
scripts: [
{
src: '/js/custom-analytics.js',
async: true,
},
],
};
MkDocs Analytics
plugins:
- search:
analytics:
provider: algolia
property: YOUR_INDEX_NAME
extra:
analytics:
provider: google
property: G-XXXXXXXXXX
feedback:
title: Was this page helpful?
ratings:
- icon: material/emoticon-happy-outline
name: This page was helpful
data: 1
note: Thanks for your feedback!
- icon: material/emoticon-sad-outline
name: This page could be improved
data: 0
note: Thanks! Help us improve by using the
Workflow
- Configure analytics - Set up GA4 and/or Algolia
- Implement tracking - Add custom event tracking
- Collect data - Gather usage metrics
- Analyze patterns - Identify trends and gaps
- Generate reports - Create actionable insights
- Optimize content - Improve based on data
Dependencies
{
"dependencies": {
"algoliasearch": "^4.0.0",
"@docsearch/js": "^3.0.0"
},
"devDependencies": {
"@google-analytics/data": "^4.0.0"
}
}
Best Practices Applied
- Track meaningful events, not just pageviews
- Analyze search queries for content gaps
- Measure engagement beyond time on page
- Create actionable insights from data
- Respect user privacy (GDPR compliance)
- Focus on documentation ROI
References
Target Processes
- docs-audit.js
- content-strategy.js
- knowledge-base-setup.js
- docs-testing.js