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">&copy; 2026 <a href="https://jblueprint.dev">jblueprint.dev</a>. Powered by <a href="https://jekyllrb.com" rel="nofollow">Jekyll</a> &amp; <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.

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:

  1. Gemfile: Restore gem "minima", "~> 2.5".
  2. _config.yml: Restore theme: minima; remove MM-specific keys; restore minima asset exclusions.
  3. Remove _layouts/default.html, _layouts/home.html, _layouts/post.html, _layouts/page.html.
  4. Remove _includes/head/custom.html and _data/navigation.yml.
  5. Run bundle install && bundle exec jekyll build to 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.

Updated: