mdBook is fantastic for writing docs and handbooks in Markdown. Out of the box, it’s clean and functional—but also a bit… generic.
When I published my new book, Momentum Hacks, I wanted it to feel like part of the Indie10k ecosystem. That meant:
Adding Google Analytics for tracking
Dropping Indie10k’s logo + title right in the sidebar
Ending every chapter with a CTA to join Indie10k
Here’s how I hacked mdBook’s default theme to make that happen.
1. Files to Tweak
Inside your book’s theme directory, you’ll find:
ls theme
head.hbs indie10k.css indie10k.js
head.hbs
→ inject GA, meta, or other<head>
tagsindie10k.css
→ custom styles for sidebar, CTA, etc.indie10k.js
→ DOM scripts to insert branding and signup prompts
2. Adding Google Analytics
Open theme/head.hbs
and drop your GA snippet just before </head>
:
<!-- Google Analytics -->
<script async src="https://www.googletagmanager.com/gtag/js?id=G-XXXXXXX"></script>
<script>
window.dataLayer = window.dataLayer || [];
function gtag(){dataLayer.push(arguments);}
gtag('js', new Date());
gtag('config', 'G-XXXXXXX');
</script>
Done. Now every mdBook page sends pageview events.
3. Branding the Sidebar
In indie10k.js
, I injected a custom header into mdBook’s sidebar.
// Inject Indie10k branding into mdBook sidebar
(function () { function ready(fn) { if (document.readyState !== 'loading') return fn(); document.addEventListener('DOMContentLoaded', fn);
} ready(function () { var sidebar = document.getElementById('sidebar'); if (!sidebar || sidebar.querySelector('.indie10k-header')) return; var header = document.createElement('div');
header.className = 'indie10k-header'; // Logo + Title var link = document.createElement('a');
link.href = '/';
link.setAttribute('aria-label', 'Indie10k Home'); var logo = document.createElement('img');
logo.src = '/logo.png';
logo.alt = 'Indie10k Logo';
logo.className = 'indie10k-logo'; var titleWrap = document.createElement('div');
titleWrap.className = 'indie10k-title'; var name = document.createElement('span');
name.className = 'indie10k-name';
name.textContent = 'Indie10k'; var subtitle = document.createElement('span');
subtitle.className = 'indie10k-subtitle';
subtitle.textContent = 'Momentum Hacks';
titleWrap.appendChild(name);
titleWrap.appendChild(subtitle);
link.appendChild(logo);
link.appendChild(titleWrap);
header.appendChild(link); // Links: Sign In / Sign Up var links = document.createElement('div');
links.className = 'indie10k-links'; var signIn = document.createElement('a');
signIn.href = '/login';
signIn.textContent = 'Sign In'; var signUp = document.createElement('a');
signUp.href = '/register';
signUp.textContent = 'Sign Up';
signUp.className = 'signup';
links.appendChild(signIn);
links.appendChild(signUp);
header.appendChild(links); // Insert at top of sidebar var scrollbox = sidebar.querySelector('.sidebar-scrollbox');
sidebar.insertBefore(header, scrollbox || sidebar.firstChild); // Adjust scroll area offset try { var h = header.getBoundingClientRect().height; if (h && scrollbox) scrollbox.style.top = h + 'px';
} catch (_) {}
});
})();
This puts Indie10k branding at the top of every page.
4. Adding a Call-to-Action
At the bottom of each chapter, I wanted a consistent signup nudge.
// Inject CTA below content
(function () { function ready(fn) { if (document.readyState !== 'loading') return fn(); document.addEventListener('DOMContentLoaded', fn);
} ready(function () { var content = document.querySelector('#content main'); if (!content || document.querySelector('.indie10k-cta')) return; var cta = document.createElement('section');
cta.className = 'indie10k-cta'; var h = document.createElement('h1');
h.textContent = 'Ready to start your indie journey?'; var p = document.createElement('p');
p.textContent = 'Join thousands of developers building their path to $10k'; var a = document.createElement('a');
a.href = '/register';
a.className = 'indie10k-cta-btn';
a.textContent = 'Try Indie10k Free';
cta.appendChild(h);
cta.appendChild(p);
cta.appendChild(a);
content.appendChild(cta);
});
})();
It’s subtle, consistent, and frictionless.
5. Styling It
All of this is supported by indie10k.css
for logos, buttons, and sidebar polish. Keep your CSS scoped with .indie10k-*
classes so it doesn’t break mdBook’s defaults.
Why Bother?
Because your book isn’t just content—it’s an asset. With a little theming:
Readers know it belongs to your brand
You track engagement with GA
You give them a clear next step (sign up, join, buy)
That’s how you turn a static book into a live growth engine.
Live Example
Want to see it in action? Check out my new free book:
👉 Momentum Hacks
It’s a playbook for indie hackers: 30 hacks, 15-minute doses, and one core message:
Momentum beats motivation. Every time.
Top comments (0)