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)