Installing Minimal Mistakes on a Bilingual Jekyll Blog
This post documents how to migrate a bilingual Jekyll blog from the default minima theme
to minimal-mistakes-jekyll while preserving full multilingual routing via jekyll-polyglot.
Gem Installation
Replace minima with minimal-mistakes-jekyll in your Gemfile:
# Remove:
# gem "minima", "~> 2.5"
# Add:
gem "minimal-mistakes-jekyll"
Then run:
bundle install
_config.yml Changes
Switch the theme key
# Remove:
# theme: minima
# Add:
theme: minimal-mistakes-jekyll
minimal_mistakes_skin: default # Options: air, aqua, contrast, dark, dirt, mint, neon, plum, sunrise
Add MM site settings
locale: en-US # Static BCP47 for MM's internal UI strings — DO NOT use for runtime locale detection
breadcrumbs: false # Required: MM breadcrumbs are not Polyglot locale-aware
title: your-site-title
name: "Your Name"
description: "Your site description"
url: "https://your-domain.dev"
baseurl: ""
Update exclude_from_localization
Remove the old minima asset paths and add MM’s generated asset paths:
exclude_from_localization:
# ... other paths ...
# Replace:
# - assets/main.css
# - assets/main.css.map
# - assets/minima-social-icons.svg
# With:
- assets/css/main.scss
- assets/css/main.css
- assets/js/main.min.js
Also add specs/ to Jekyll’s exclude: list if you have spec markdown files containing
MM-specific Liquid tags (include_cached) in code blocks — otherwise Jekyll will error
when processing those files under minima:
exclude:
- specs/
# ... other paths ...
Layout Override Strategy
Minimal Mistakes provides built-in layouts that extend its default.html root layout.
To inject the language switcher and hreflang metadata into every page, two files are added:
_includes/head/custom.html (new)
MM’s documented extension point for project-level <head> additions. This file is
automatically included by MM’s head.html include:
```html
### `_layouts/default.html` (override)
Override MM's root layout to inject the language switcher after the masthead. All other
MM layouts (`post`, `page`, `archive`, etc.) inherit from `default`, so the switcher
appears everywhere with just this one file:
```html
---
---<!doctype html>
<html lang="en" class="no-js">
<head>
<meta charset="utf-8">
<!-- begin _includes/seo.html --><title>Installing Minimal Mistakes on a Bilingual Jekyll Blog - jblueprint.dev</title>
<meta name="description" content="This post documents how to migrate a bilingual Jekyll blog from the default minima theme to minimal-mistakes-jekyll while preserving full multilingual routing via jekyll-polyglot.">
<meta property="og:type" content="article">
<meta property="og:locale" content="en_US">
<meta property="og:site_name" content="jblueprint.dev">
<meta property="og:title" content="Installing Minimal Mistakes on a Bilingual Jekyll Blog">
<meta property="og:url" content="https://jblueprint.dev/jekyll/theme/minimal-mistakes/2026/05/08/minimal-mistakes-integration.html">
<meta property="og:description" content="This post documents how to migrate a bilingual Jekyll blog from the default minima theme to minimal-mistakes-jekyll while preserving full multilingual routing via jekyll-polyglot.">
<meta property="article:published_time" content="2026-05-08T00:00:00+00:00">
<link rel="canonical" href="https://jblueprint.dev/jekyll/theme/minimal-mistakes/2026/05/08/minimal-mistakes-integration.html">
<!-- end _includes/seo.html -->
<link href="/feed.xml" type="application/atom+xml" rel="alternate" title="jblueprint.dev Feed">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<script>
document.documentElement.className = document.documentElement.className.replace(/\bno-js\b/g, '') + ' js ';
</script>
<!-- For all browsers -->
<link rel="stylesheet" href="/assets/css/main.css">
<link rel="preload" href="https://cdn.jsdelivr.net/npm/@fortawesome/fontawesome-free@latest/css/all.min.css" as="style" onload="this.onload=null;this.rel='stylesheet'">
<noscript><link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@fortawesome/fontawesome-free@latest/css/all.min.css"></noscript>
<link rel="alternate" hreflang="en" href="/jekyll/theme/minimal-mistakes/2026/05/08/minimal-mistakes-integration.html">
<link rel="alternate" hreflang="es" href="/es/jekyll/theme/minimal-mistakes/2026/05/08/minimal-mistakes-integration.html">
<link rel="alternate" hreflang="x-default" href="/jekyll/theme/minimal-mistakes/2026/05/08/minimal-mistakes-integration.html">
</head>
<body class="layout--post...">
<nav class="skip-links" aria-label="Skip links">
<ul>
<li><a href="#site-nav" class="screen-reader-shortcut">Skip to primary navigation</a></li>
<li><a href="#main" class="screen-reader-shortcut">Skip to content</a></li>
<li><a href="#footer" class="screen-reader-shortcut">Skip to footer</a></li>
</ul>
</nav>
<div class="masthead">
<div class="masthead__inner-wrap">
<div class="masthead__menu">
<nav id="site-nav" class="greedy-nav" aria-label="Primary navigation">
<a class="site-title" href="/">
jblueprint.dev
</a>
<ul class="visible-links"><li class="masthead__menu-item">
<a
href="/"
>Home</a>
</li><li class="masthead__menu-item">
<a
href="/posts/"
>Posts</a>
</li><li class="masthead__menu-item">
<a
href="/about/"
>About</a>
</li></ul>
<button class="search__toggle" type="button">
<span class="visually-hidden">Toggle search</span>
<i class="fas fa-search"></i>
</button>
<!-- Language switcher — EN/ES styled as masthead toggle buttons -->
<!-- Language toggle — EN | ES integrated into MM masthead nav bar -->
<div
class="lang-switch"
role="navigation"
aria-label="Language"
data-language-switcher
data-current-lang="en"
data-target-en="/jekyll/theme/minimal-mistakes/2026/05/08/minimal-mistakes-integration.html"
data-target-es="/jekyll/theme/minimal-mistakes/2026/05/08/minimal-mistakes-integration.html?translation=unavailable&requested=es"
data-has-equivalent-en="true"
data-has-equivalent-es="false"
data-translation-mode="computed"
>
<a
href="#"
lang="en"
hreflang="en"
data-language-option="en"
class="lang-switch__btn is-active"
aria-current="true"
>EN</a>
<span class="lang-switch__sep" aria-hidden="true">|</span>
<a
href="#"
lang="es"
hreflang="es"
data-language-option="es"
class="lang-switch__btn"
>ES</a>
</div>
<button class="greedy-nav__toggle hidden" type="button">
<span class="visually-hidden">Toggle menu</span>
<div class="navicon"></div>
</button>
<ul class="hidden-links hidden"></ul>
</nav>
</div>
</div>
</div>
<div class="language-switcher-wrapper">
<!-- Language toggle — EN | ES integrated into MM masthead nav bar -->
<div
class="lang-switch"
role="navigation"
aria-label="Language"
data-language-switcher
data-current-lang="en"
data-target-en="/jekyll/theme/minimal-mistakes/2026/05/08/minimal-mistakes-integration.html"
data-target-es="/jekyll/theme/minimal-mistakes/2026/05/08/minimal-mistakes-integration.html?translation=unavailable&requested=es"
data-has-equivalent-en="true"
data-has-equivalent-es="false"
data-translation-mode="computed"
>
<a
href="#"
lang="en"
hreflang="en"
data-language-option="en"
class="lang-switch__btn is-active"
aria-current="true"
>EN</a>
<span class="lang-switch__sep" aria-hidden="true">|</span>
<a
href="#"
lang="es"
hreflang="es"
data-language-option="es"
class="lang-switch__btn"
>ES</a>
</div>
<div
id="translation-feedback"
class="translation-feedback"
role="status"
aria-live="polite"
hidden
data-message-en="Translation not available for the selected language."
data-message-es="Traducción no disponible para el idioma seleccionado."
>
Translation not available for the selected language.
</div>
</div>
<div id="main" role="main">
<div id="main" role="main">
<article class="page h-entry" itemscope itemtype="https://schema.org/CreativeWork">
<meta itemprop="headline" content="Instalación de Minimal Mistakes en un blog Jekyll multilenguaje">
<meta itemprop="description" content="Este post documenta la instalación del tema Minimal Mistakes sobre un blog Jekyll con soporte multilenguaje (en y es) basado en jekyll-polyglot.">
<meta itemprop="datePublished" content="2026-05-08T00:00:00+00:00">
<div class="page__inner-wrap">
<header>
<h1 id="page-title" class="page__title p-name" itemprop="headline">
<a href="https://jblueprint.dev/jekyll/theme/2026/05/08/instalacion-minimal-mistakes.html" itemprop="url">Instalación de Minimal Mistakes en un blog Jekyll multilenguaje
</a>
</h1>
</header>
<section class="page__content e-content" itemprop="text">
<p>Este post documenta la instalación del tema <strong>Minimal Mistakes</strong> sobre un blog Jekyll con soporte multilenguaje (<code class="language-plaintext highlighter-rouge">en</code> y <code class="language-plaintext highlighter-rouge">es</code>) basado en <code class="language-plaintext highlighter-rouge">jekyll-polyglot</code>.</p>
<h2 id="objetivo">Objetivo</h2>
<ul>
<li>Integrar Minimal Mistakes como tema principal.</li>
<li>Mantener compatibilidad con el enrutado actual multilenguaje.</li>
<li>Conservar el selector de idioma y el comportamiento de fallback existente.</li>
</ul>
<h2 id="estado-actual">Estado actual</h2>
<ul>
<li>La especificación de esta feature está en <code class="language-plaintext highlighter-rouge">specs/002-add-minimal-mistakes-theme/spec.md</code>.</li>
<li>La fase de clarificación ya incluye requisitos para:
<ul>
<li>compatibilidad con rutas <code class="language-plaintext highlighter-rouge">default</code> y <code class="language-plaintext highlighter-rouge">/es/</code>,</li>
<li>documentación de la instalación,</li>
<li>organización temporal de <code class="language-plaintext highlighter-rouge">_posts</code> en carpetas por mes y día.</li>
</ul>
</li>
</ul>
<h2 id="próximos-pasos">Próximos pasos</h2>
<ol>
<li>Ejecutar <code class="language-plaintext highlighter-rouge">speckit.plan</code> para diseñar la migración de tema.</li>
<li>Generar tareas con <code class="language-plaintext highlighter-rouge">speckit.tasks</code>.</li>
<li>Implementar la migración validando build y rutas bilingües.</li>
</ol>
<p>Iremos actualizando este post conforme avance la implementación.</p>
</section>
<footer class="page__meta">
<p class="page__date"><strong><i class="fas fa-fw fa-calendar-alt" aria-hidden="true"></i> Updated:</strong> <time class="dt-published" datetime="2026-05-08T00:00:00+00:00">May 8, 2026</time></p>
</footer>
<nav class="pagination" aria-label="Post pagination">
<a href="#" class="pagination--pager disabled">Previous</a>
<a href="/jekyll/theme/minimal-mistakes/2026/05/08/minimal-mistakes-integration.html" class="pagination--pager" title="Installing Minimal Mistakes on a Bilingual Jekyll Blog">Next</a>
</nav>
</div>
</article>
</div>
</div>
<div id="footer" class="page__footer">
<footer>
<!-- start custom footer snippets -->
<!-- end custom footer snippets -->
<div class="page__footer-follow">
<ul class="social-icons">
<li><a href="/feed.xml"><i class="fas fa-fw fa-square-rss" aria-hidden="true"></i> Feed</a></li>
</ul>
</div>
<div class="page__footer-copyright">© 2026 <a href="https://jblueprint.dev">jblueprint.dev</a>. Powered by <a href="https://jekyllrb.com" rel="nofollow">Jekyll</a> & <a href="https://mademistakes.com/work/jekyll-themes/minimal-mistakes/" rel="nofollow">Minimal Mistakes</a>.</div>
</footer>
</div>
<script src="/assets/js/main.min.js"></script>
<script src="/assets/js/lunr/lunr.min.js"></script>
<script src="/assets/js/lunr/lunr-store.js"></script>
<script src="/assets/js/lunr/lunr-en.js"></script>
<script src="/assets/js/language-session.js" defer></script>
</body>
</html>
_layouts/home.html (override for bilingual post listing)
MM ships a home layout, but it does not filter posts by locale. Override it to filter
site.posts by site.active_lang (the Polyglot runtime locale):
---
layout: default
---
<div class="home"><h2 class="post-list-heading">Posts</h2>
<ul class="post-list"><li>
<span class="post-meta">May 8, 2026</span>
<h3>
<a class="post-link" href="/jekyll/speckit/2026/05/08/how-to-build-a-blog-with-spec-driven-design.html">
How to Build a Blog Using Spec Driven Design
</a>
</h3>
</li><li>
<span class="post-meta">May 8, 2026</span>
<h3>
<a class="post-link" href="/jekyll/speckit/2026/05/08/como-crear-un-blog-con-spec-driven-design.html">
Cómo crear un blog con Spec Driven Design
</a>
</h3>
</li><li>
<span class="post-meta">May 8, 2026</span>
<h3>
<a class="post-link" href="/jekyll/theme/minimal-mistakes/2026/05/08/minimal-mistakes-integration.html">
Installing Minimal Mistakes on a Bilingual Jekyll Blog
</a>
</h3>
</li><li>
<span class="post-meta">May 8, 2026</span>
<h3>
<a class="post-link" href="/jekyll/theme/2026/05/08/instalacion-minimal-mistakes.html">
Instalación de Minimal Mistakes en un blog Jekyll multilenguaje
</a>
</h3>
</li></ul></div>
Bridge layouts for standard Jekyll front matter
MM uses layout: single for posts and pages, not layout: post / layout: page.
Add thin bridges so existing content continues to work:
_layouts/post.html:
---
layout: single
---
_layouts/page.html:
---
layout: single
---
Language Switcher Preservation
The existing _includes/language-switcher.html, _includes/translation-feedback.html,
and assets/js/language-session.js require no changes. They are injected via the
_layouts/default.html override and continue to work exactly as before the theme migration.
Navigation
Create _data/navigation.yml for MM’s masthead:
main:
- title: "Home"
url: /
- title: "About"
url: /about/
Do not embed language-switcher links here — MM navigation is a static key/URL list and does not evaluate Liquid expressions.
Post Directory Convention
New posts use the _posts/<year>/<month>/<day>/YYYY-MM-DD-title.md convention.
Jekyll only uses the filename to determine date and slug; the directory structure is
organizational only. Existing posts at other paths are unaffected.
Rollback Path
To restore minima without losing multilingual content:
Gemfile: Restoregem "minima", "~> 2.5"._config.yml: Restoretheme: minima; remove MM-specific keys; restore minima asset exclusions.- Remove
_layouts/default.html,_layouts/home.html,_layouts/post.html,_layouts/page.html. - Remove
_includes/head/custom.htmland_data/navigation.yml. - Run
bundle install && bundle exec jekyll buildto verify.
All bilingual content files, routing configuration, and multilingual includes are preserved through a rollback — only the visual theme and theme-specific config keys are reverted.