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>tags
- indie10k.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)