<?xml version="1.0" encoding="utf-8"?><feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en"><generator uri="https://jekyllrb.com/" version="3.10.0">Jekyll</generator><link href="https://jblueprint.dev/feed.xml" rel="self" type="application/atom+xml" /><link href="https://jblueprint.dev/" rel="alternate" type="text/html" hreflang="en" /><updated>2026-05-09T15:39:13+00:00</updated><id>https://jblueprint.dev/feed.xml</id><title type="html">jblueprint.dev</title><subtitle>A bilingual Jekyll blog about software engineering, tools, and ideas. Written in English and Spanish.</subtitle><entry xml:lang="es"><title type="html">Cómo crear un blog con Spec Driven Design</title><link href="https://jblueprint.dev/jekyll/speckit/2026/05/08/como-crear-un-blog-con-spec-driven-design.html" rel="alternate" type="text/html" title="Cómo crear un blog con Spec Driven Design" /><published>2026-05-08T10:00:00+00:00</published><updated>2026-05-08T10:00:00+00:00</updated><id>https://jblueprint.dev/jekyll/speckit/2026/05/08/como-crear-un-blog-con-spec-driven-design-es</id><content type="html" xml:base="https://jblueprint.dev/jekyll/speckit/2026/05/08/como-crear-un-blog-con-spec-driven-design.html"><![CDATA[<p>Crear un blog desde cero es una cosa. Crearlo <em>bien</em> con una metodología clara y trazable es otra.</p>

<p>En este post, te guiaré a través del viaje real de implementación de <strong>jblueprint.dev</strong> usando un flujo de trabajo de <strong>Spec Driven Design</strong> con <a href="https://github.com/speckit/speckit">Speckit</a>—un framework que te ayuda a moverte desde ideas de features hasta código funcional y validado de forma estructurada.</p>

<h2 id="por-qué-spec-driven-design">¿Por qué Spec Driven Design?</h2>

<p>Antes de tocar una sola línea de código, dedicamos tiempo a:</p>
<ol>
  <li><strong>Definir qué queríamos construir</strong> (especificación).</li>
  <li><strong>Aclarar ambigüedades</strong> con decisiones de producto (clarificación).</li>
  <li><strong>Planificar el enfoque técnico</strong> (planificación de implementación).</li>
  <li><strong>Dividir el trabajo en tareas ordenadas</strong> (generación de tareas).</li>
  <li><strong>Ejecutar con validación</strong> (implementación).</li>
</ol>

<p>Este enfoque reduce el retrabajo, asegura claridad y crea un <strong>registro vivo de decisiones</strong> que puedes explicar más tarde. Perfecto para un blog donde quieres documentar tu razonamiento.</p>

<h2 id="contexto-del-proyecto">Contexto del Proyecto</h2>

<ul>
  <li><strong>Proyecto</strong>: <code class="language-plaintext highlighter-rouge">jblueprint.dev</code></li>
  <li><strong>Stack</strong>: Jekyll</li>
  <li><strong>Objetivo</strong>: Agregar soporte multilingüe (español e inglés)</li>
  <li><strong>Plugin i18n</strong>: <a href="https://polyglot.untra.io/es/">jekyll-polyglot</a></li>
</ul>

<h3 id="reglas-fundamentales">Reglas Fundamentales</h3>

<ol>
  <li><strong>Implementación solo en inglés</strong>: Todo el código y comentarios están en inglés para mantenibilidad.</li>
  <li><strong>Cumplimiento Jekyll-first</strong>: Sigue las convenciones oficiales de Jekyll y documentación.</li>
  <li><strong>Validación de build</strong>: Cada cambio que afecte el sitio requiere verificación local con <code class="language-plaintext highlighter-rouge">bundle exec jekyll build</code>.</li>
</ol>

<h2 id="el-flujo-de-trabajo-en-5-pasos">El Flujo de Trabajo en 5 Pasos</h2>

<h3 id="paso-0-fundación">Paso 0: Fundación</h3>

<p>Detectamos que el repositorio ya tenía estructura Speckit (directorio <code class="language-plaintext highlighter-rouge">.specify/</code>) y creamos una <strong>constitución de proyecto</strong> que formalizó nuestros principios:</p>
<ul>
  <li>Implementación solo en inglés</li>
  <li>Cumplimiento Jekyll-first en decisiones técnicas</li>
  <li>Validación de build para cambios que afecten la salida del sitio</li>
</ul>

<p>Esta constitución guiaría cada decisión adelante.</p>

<h3 id="paso-1-especificación-y-clarificación">Paso 1: Especificación y Clarificación</h3>

<p>Usando <code class="language-plaintext highlighter-rouge">speckit.specify</code>, creamos la primera especificación de feature: <strong>“Add Multilingual Support (Spanish and English)”</strong>.</p>

<p>La especificación definió:</p>
<ul>
  <li><strong>Historias de usuario</strong>: Leer en idioma preferido, cambiar idioma sin perder contexto, mantener contenido bilingüe confiablemente.</li>
  <li><strong>Requisitos funcionales</strong>: Estrategia de URLs, cambio de idioma, comportamiento de fallback, SEO.</li>
  <li><strong>Criterios de éxito</strong>: 100% de páginas principales accesibles en ambos idiomas, 95% cambios de idioma exitosos, cero enlaces rotos.</li>
</ul>

<p>Luego, usando <code class="language-plaintext highlighter-rouge">speckit.clarify</code>, resolvimos las <strong>5 decisiones de producto más críticas</strong>:</p>

<ol>
  <li><strong>Estrategia de URLs</strong>: Idioma por defecto sin prefijo (<code class="language-plaintext highlighter-rouge">/...</code>); español con prefijo (<code class="language-plaintext highlighter-rouge">/es/...</code>).</li>
  <li><strong>Prefijos de locale no soportados</strong>: Redirigir con HTTP <code class="language-plaintext highlighter-rouge">301</code> al equivalente de idioma por defecto.</li>
  <li><strong>Traducciones faltantes</strong>: Redirigir con HTTP <code class="language-plaintext highlighter-rouge">302</code> + mostrar mensaje de retroalimentación.</li>
  <li><strong>Persistencia de preferencia de idioma</strong>: Solo en sesión (se reinicia en nueva sesión del navegador).</li>
  <li><strong>Discoverabilidad SEO</strong>: Requerir etiquetas <code class="language-plaintext highlighter-rouge">hreflang</code> recíprocas y <code class="language-plaintext highlighter-rouge">x-default</code> en páginas bilingües.</li>
</ol>

<p><strong>Resultado</strong>: Una especificación completamente aclarada, lista para planificación técnica.</p>

<h3 id="paso-2-planificación-de-implementación">Paso 2: Planificación de Implementación</h3>

<p>Usando <code class="language-plaintext highlighter-rouge">speckit.plan</code>, generamos artefactos de diseño:</p>
<ul>
  <li><code class="language-plaintext highlighter-rouge">plan.md</code> — Estrategia general y fases</li>
  <li><code class="language-plaintext highlighter-rouge">research.md</code> — Análisis técnico profundo y detalles del plugin Polyglot</li>
  <li><code class="language-plaintext highlighter-rouge">data-model.md</code> — Estructuras de datos de localización</li>
  <li><code class="language-plaintext highlighter-rouge">contracts/multilingual-routing-contract.md</code> — Reglas detalladas de URL y redirección</li>
  <li><code class="language-plaintext highlighter-rouge">quickstart.md</code> — Checklist de validación para desarrolladores</li>
</ul>

<p>Todos los artefactos reforzaron comentarios en inglés y pensamiento Jekyll-first.</p>

<p><strong>Resultado</strong>: Un blueprint técnico completo, testeable e implementable.</p>

<h3 id="paso-3-generación-de-tareas">Paso 3: Generación de Tareas</h3>

<p>Usando <code class="language-plaintext highlighter-rouge">speckit.tasks</code>, convertimos el plan en un <strong>backlog ordenado de 33 tareas accionables</strong>:</p>

<ul>
  <li><strong>Fase 1 (Setup)</strong>: Instalar <code class="language-plaintext highlighter-rouge">jekyll-polyglot</code>, configurar <code class="language-plaintext highlighter-rouge">Gemfile</code>, crear registro de locales.</li>
  <li><strong>Fase 2 (Fundacional)</strong>: Configurar <code class="language-plaintext highlighter-rouge">_config.yml</code>, crear layouts e includes multilingües, conectar cambio de idioma y SEO.</li>
  <li><strong>Fase 3 (Historia de Usuario 1)</strong>: Crear contenido bilingüe (<code class="language-plaintext highlighter-rouge">index</code>, <code class="language-plaintext highlighter-rouge">about</code>, posts) y validar rutas.</li>
  <li><strong>Fase 4 (Historia de Usuario 2)</strong>: Implementar selector de idioma con fallback y retroalimentación.</li>
  <li><strong>Fase 5 (Historia de Usuario 3)</strong>: Documentar flujo de autoría bilingüe.</li>
  <li><strong>Fase 6 (Polish)</strong>: Validación final, procedimientos de rollback, verificaciones SEO.</li>
</ul>

<p>Cada tarea tenía:</p>
<ul>
  <li>Rutas de archivos claras (Jekyll-first)</li>
  <li>Dependencias marcadas</li>
  <li>Pistas de paralelización</li>
  <li>Criterios de prueba independientes</li>
</ul>

<p><strong>Resultado</strong>: Un plan de implementación ordenado y paralelizable.</p>

<h3 id="paso-4-implementación">Paso 4: Implementación</h3>

<p>Usando <code class="language-plaintext highlighter-rouge">speckit.implement</code>, ejecutamos las 33 tareas:</p>

<p><strong>Cambios clave</strong>:</p>
<ul>
  <li>Agregamos <code class="language-plaintext highlighter-rouge">jekyll-polyglot</code> a <code class="language-plaintext highlighter-rouge">Gemfile</code> y ejecutamos <code class="language-plaintext highlighter-rouge">bundle install</code></li>
  <li>Configuramos enrutamiento de locale multilingüe en <code class="language-plaintext highlighter-rouge">_config.yml</code></li>
  <li>Creamos includes compartidos para selector de idioma, etiquetas SEO y retroalimentación de traducción</li>
  <li>Escribimos script de preferencia basado en sesión en <code class="language-plaintext highlighter-rouge">assets/js/language-session.js</code></li>
  <li>Creamos contenido bilingüe: <code class="language-plaintext highlighter-rouge">index.markdown</code>, <code class="language-plaintext highlighter-rouge">about.markdown</code> y bienvenida en inglés y español</li>
  <li>Documentamos reglas de redirección, flujo de contenido y procedimientos de rollback</li>
</ul>

<p><strong>Validación</strong>:</p>
<ul>
  <li><code class="language-plaintext highlighter-rouge">bundle exec jekyll build</code> ejecutado exitosamente</li>
  <li>Sitio generado incluye rutas bilingües: <code class="language-plaintext highlighter-rouge">/index.html</code>, <code class="language-plaintext highlighter-rouge">/es/index.html</code>, etc.</li>
  <li>Etiquetas <code class="language-plaintext highlighter-rouge">hreflang</code> validadas en páginas bilingües</li>
  <li>Sin enlaces internos rotos</li>
</ul>

<p><strong>Resultado</strong>: Un blog Jekyll multilingüe completamente funcional y validado.</p>

<h3 id="paso-5-rollout">Paso 5: Rollout</h3>

<p>Confirmamos todos los cambios con un commit limpio de rama de feature, listo para mergear.</p>

<h2 id="decisiones-clave-tomadas">Decisiones Clave Tomadas</h2>

<table>
  <thead>
    <tr>
      <th>Fecha</th>
      <th>Decisión</th>
      <th>Estado</th>
      <th>Justificación</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>2026-05-08</td>
      <td>Usar framework Speckit</td>
      <td>Aceptada</td>
      <td>Specification-first reduce retrabajo</td>
    </tr>
    <tr>
      <td>2026-05-08</td>
      <td>Plugin Polyglot</td>
      <td>Aceptada</td>
      <td>Plugin nativo Jekyll, bien mantenido</td>
    </tr>
    <tr>
      <td>2026-05-08</td>
      <td>Idioma por defecto sin prefijo</td>
      <td>Aceptada</td>
      <td>URLs más limpias para idioma principal</td>
    </tr>
    <tr>
      <td>2026-05-08</td>
      <td>301 para locales no soportadas</td>
      <td>Aceptada</td>
      <td>Preserva SEO, evita 404s</td>
    </tr>
    <tr>
      <td>2026-05-08</td>
      <td>302 para traducciones faltantes</td>
      <td>Aceptada</td>
      <td>Redirección temporal permite traducción futura</td>
    </tr>
    <tr>
      <td>2026-05-08</td>
      <td>Preferencias solo en sesión</td>
      <td>Aceptada</td>
      <td>Respeta privacidad del usuario, más simple que cookies</td>
    </tr>
    <tr>
      <td>2026-05-08</td>
      <td>hreflang + x-default</td>
      <td>Aceptada</td>
      <td>SEO apropiado y discoverabilidad para contenido bilingüe</td>
    </tr>
    <tr>
      <td>2026-05-08</td>
      <td>Google Analytics</td>
      <td>Diferida</td>
      <td>Planificada para feature futura</td>
    </tr>
  </tbody>
</table>

<h2 id="lo-que-no-hicimos-non-goals">Lo Que No Hicimos (Non-Goals)</h2>

<ul>
  <li>Agregar más de dos idiomas en este release</li>
  <li>Rediseñar el tema sin relación con soporte de idioma</li>
  <li>Reescribir todo el contenido histórico inmediatamente</li>
  <li>Usar sistemas de build o servicios de runtime fuera de Jekyll</li>
</ul>

<p>Mantener el scope ajustado nos permitió entregar rápidamente y validar completamente.</p>

<h2 id="artefactos-clave">Artefactos Clave</h2>

<p>Todo nuestro trabajo está documentado y trazable:</p>
<ul>
  <li><strong>Especificación</strong>: <code class="language-plaintext highlighter-rouge">specs/001-add-multilingual-support/spec.md</code></li>
  <li><strong>Plan</strong>: <code class="language-plaintext highlighter-rouge">specs/001-add-multilingual-support/plan.md</code></li>
  <li><strong>Tareas</strong>: <code class="language-plaintext highlighter-rouge">specs/001-add-multilingual-support/tasks.md</code></li>
  <li><strong>Contratos</strong>: <code class="language-plaintext highlighter-rouge">specs/001-add-multilingual-support/contracts/multilingual-routing-contract.md</code></li>
  <li><strong>Guías Operacionales</strong>: <code class="language-plaintext highlighter-rouge">docs/multilingual-*.md</code> (flujo, redirecciones, rollback)</li>
</ul>

<h2 id="lecciones-aprendidas">Lecciones Aprendidas</h2>

<ol>
  <li>
    <p><strong>Clarificar primero ahorra tiempo de implementación</strong>: Al hacer cinco preguntas de alto impacto <em>antes</em> de codificar, evitamos retrabajo y decisiones conflictivas.</p>
  </li>
  <li>
    <p><strong>El orden de dependencias importa</strong>: Dividir trabajo en fases ordenadas (Setup → Fundacional → Historias de Usuario) hizo la paralelización segura y redujo bloqueadores.</p>
  </li>
  <li>
    <p><strong>Los documentos de especificación son artefactos vivos</strong>: Sirven doble propósito: guía de diseño <em>y</em> contenido de blog futuro.</p>
  </li>
  <li>
    <p><strong>Las convenciones de Jekyll son tu aliada</strong>: Mantenerse fiel a la estructura de Jekyll hizo la implementación directa y mantenible.</p>
  </li>
  <li>
    <p><strong>La validación de build es no-negociable</strong>: Ejecutar <code class="language-plaintext highlighter-rouge">bundle exec jekyll build</code> después de cada cambio mayor detectó issues temprano.</p>
  </li>
</ol>

<h2 id="próximos-pasos">Próximos Pasos</h2>

<ul>
  <li><strong>Monitorear en producción</strong>: Observar problemas de enrutamiento o SEO.</li>
  <li><strong>Recopilar retroalimentación de usuarios</strong>: Ver si la UX del selector de idioma funciona bien.</li>
  <li><strong>Planificar mejoras futuras</strong>: Integración de Google Analytics, idiomas adicionales, herramientas de gestión de traducciones.</li>
</ul>

<h2 id="intenta-tú-mismo">Intenta Tú Mismo</h2>

<p>Si estás construyendo un blog Jekyll y considerando soporte multilingüe, sigue este mismo flujo de trabajo:</p>

<ol>
  <li>Escribe una especificación clara (¿qué problemas estás resolviendo?).</li>
  <li>Aclara decisiones clave con stakeholders.</li>
  <li>Planifica el enfoque técnico (layouts, datos, configs).</li>
  <li>Divide en tareas ordenadas con criterios de prueba.</li>
  <li>Implementa y valida metódicamente.</li>
</ol>

<p>¿El resultado? Una feature bien razonada, trazable y mantenible—más una narrativa que puedes compartir con tu audiencia.</p>

<hr />

<p><strong>Este post es parte de una serie sobre construir y mantener jblueprint.dev usando prácticas modernas de especificación y diseño.</strong></p>]]></content><author><name></name></author><category term="jekyll" /><category term="speckit" /><category term="design" /><summary type="html"><![CDATA[Crear un blog desde cero es una cosa. Crearlo bien con una metodología clara y trazable es otra.]]></summary></entry><entry xml:lang="en"><title type="html">How to Build a Blog Using Spec Driven Design</title><link href="https://jblueprint.dev/jekyll/speckit/2026/05/08/how-to-build-a-blog-with-spec-driven-design.html" rel="alternate" type="text/html" title="How to Build a Blog Using Spec Driven Design" /><published>2026-05-08T10:00:00+00:00</published><updated>2026-05-08T10:00:00+00:00</updated><id>https://jblueprint.dev/jekyll/speckit/2026/05/08/como-crear-un-blog-con-spec-driven-design</id><content type="html" xml:base="https://jblueprint.dev/jekyll/speckit/2026/05/08/how-to-build-a-blog-with-spec-driven-design.html"><![CDATA[<p>Building a blog from scratch is one thing. Building it <em>well</em> with a clear, traceable methodology is another.</p>

<p>In this post, I’ll walk you through the real implementation journey of <strong>jblueprint.dev</strong> using a <strong>Spec Driven Design workflow</strong> with <a href="https://github.com/speckit/speckit">Speckit</a>—a framework that helps you move from feature ideas to working, validated code in a structured way.</p>

<h2 id="why-spec-driven-design">Why Spec Driven Design?</h2>

<p>Before touching a single line of code, we took time to:</p>
<ol>
  <li><strong>Define what we wanted to build</strong> (specification).</li>
  <li><strong>Clarify ambiguities</strong> with product decisions (clarification).</li>
  <li><strong>Plan the technical approach</strong> (implementation planning).</li>
  <li><strong>Break work into ordered tasks</strong> (task generation).</li>
  <li><strong>Execute with validation</strong> (implementation).</li>
</ol>

<p>This approach reduces rework, ensures clarity, and creates a <strong>living document trail</strong> of decisions. Perfect for a blog where you want to explain your reasoning later.</p>

<h2 id="project-context">Project Context</h2>

<ul>
  <li><strong>Project</strong>: <code class="language-plaintext highlighter-rouge">jblueprint.dev</code></li>
  <li><strong>Stack</strong>: Jekyll</li>
  <li><strong>Goal</strong>: Add multilingual support (Spanish and English)</li>
  <li><strong>i18n Plugin</strong>: <a href="https://polyglot.untra.io/">jekyll-polyglot</a></li>
</ul>

<h3 id="ground-rules">Ground Rules</h3>

<ol>
  <li><strong>English-only implementation</strong>: All code and code comments are in English for maintainability.</li>
  <li><strong>Jekyll-first compliance</strong>: Follow official Jekyll conventions and documentation.</li>
  <li><strong>Build validation</strong>: Every site-affecting change requires a local <code class="language-plaintext highlighter-rouge">bundle exec jekyll build</code> check.</li>
</ol>

<h2 id="the-workflow-in-5-steps">The Workflow in 5 Steps</h2>

<h3 id="step-0-foundation">Step 0: Foundation</h3>

<p>We detected that the repository already had a Speckit structure (<code class="language-plaintext highlighter-rouge">.specify/</code> directory) and created a <strong>project constitution</strong> that formalized our principles:</p>
<ul>
  <li>English-only implementation artifacts</li>
  <li>Jekyll-first compliance for any technical decisions</li>
  <li>Build validation for changes affecting site output</li>
</ul>

<p>This constitution would guide every decision forward.</p>

<h3 id="step-1-specification--clarification">Step 1: Specification &amp; Clarification</h3>

<p>Using <code class="language-plaintext highlighter-rouge">speckit.specify</code>, we created the first feature spec: <strong>“Add Multilingual Support (Spanish and English)”</strong>.</p>

<p>The spec defined:</p>
<ul>
  <li><strong>User stories</strong>: Reading in preferred language, switching language without losing context, maintaining bilingual content reliably.</li>
  <li><strong>Functional requirements</strong>: URL strategy, language switching, fallback behavior, SEO.</li>
  <li><strong>Success criteria</strong>: 100% of primary pages reachable in both languages, 95% successful language switches, zero broken links.</li>
</ul>

<p>Then, using <code class="language-plaintext highlighter-rouge">speckit.clarify</code>, we resolved the <strong>5 most critical product decisions</strong>:</p>

<ol>
  <li><strong>URL strategy</strong>: Default language no prefix (<code class="language-plaintext highlighter-rouge">/...</code>); Spanish with prefix (<code class="language-plaintext highlighter-rouge">/es/...</code>).</li>
  <li><strong>Unsupported locale prefixes</strong>: Redirect with HTTP <code class="language-plaintext highlighter-rouge">301</code> to default-locale equivalent.</li>
  <li><strong>Missing translations</strong>: Redirect with HTTP <code class="language-plaintext highlighter-rouge">302</code> + show feedback message.</li>
  <li><strong>Language preference persistence</strong>: Session-scoped only (resets in new browser session).</li>
  <li><strong>SEO discoverability</strong>: Require reciprocal <code class="language-plaintext highlighter-rouge">hreflang</code> tags and <code class="language-plaintext highlighter-rouge">x-default</code> on bilingual pages.</li>
</ol>

<p><strong>Outcome</strong>: A fully clarified specification, ready for technical planning.</p>

<h3 id="step-2-implementation-planning">Step 2: Implementation Planning</h3>

<p>Using <code class="language-plaintext highlighter-rouge">speckit.plan</code>, we generated design artifacts:</p>
<ul>
  <li><code class="language-plaintext highlighter-rouge">plan.md</code> — Overall strategy and phasing</li>
  <li><code class="language-plaintext highlighter-rouge">research.md</code> — Technology deep-dives and Polyglot plugin details</li>
  <li><code class="language-plaintext highlighter-rouge">data-model.md</code> — Localization data structures</li>
  <li><code class="language-plaintext highlighter-rouge">contracts/multilingual-routing-contract.md</code> — Detailed URL and redirect rules</li>
  <li><code class="language-plaintext highlighter-rouge">quickstart.md</code> — Validation checklist for developers</li>
</ul>

<p>All artifacts enforced English-only comments and Jekyll-first thinking.</p>

<p><strong>Outcome</strong>: A complete technical blueprint, testable and implementable.</p>

<h3 id="step-3-task-generation">Step 3: Task Generation</h3>

<p>Using <code class="language-plaintext highlighter-rouge">speckit.tasks</code>, we converted the plan into an <strong>ordered backlog of 33 actionable tasks</strong>:</p>

<ul>
  <li><strong>Phase 1 (Setup)</strong>: Install <code class="language-plaintext highlighter-rouge">jekyll-polyglot</code>, configure <code class="language-plaintext highlighter-rouge">Gemfile</code>, create locale registry.</li>
  <li><strong>Phase 2 (Foundational)</strong>: Configure <code class="language-plaintext highlighter-rouge">_config.yml</code>, create multilingual layouts and includes, wire language switching and SEO.</li>
  <li><strong>Phase 3 (User Story 1)</strong>: Create bilingual content (<code class="language-plaintext highlighter-rouge">index</code>, <code class="language-plaintext highlighter-rouge">about</code>, posts) and validate routes.</li>
  <li><strong>Phase 4 (User Story 2)</strong>: Implement language switcher with fallback and feedback.</li>
  <li><strong>Phase 5 (User Story 3)</strong>: Document editorial workflow for bilingual publishing.</li>
  <li><strong>Phase 6 (Polish)</strong>: Final validation, rollback procedures, SEO checks.</li>
</ul>

<p>Each task had:</p>
<ul>
  <li>Clear file paths (Jekyll-first)</li>
  <li>Dependencies marked</li>
  <li>Parallelization hints</li>
  <li>Independent test criteria</li>
</ul>

<p><strong>Outcome</strong>: A dependency-ordered, parallelizable implementation plan.</p>

<h3 id="step-4-implementation">Step 4: Implementation</h3>

<p>Using <code class="language-plaintext highlighter-rouge">speckit.implement</code>, we executed all 33 tasks:</p>

<p><strong>Key changes</strong>:</p>
<ul>
  <li>Added <code class="language-plaintext highlighter-rouge">jekyll-polyglot</code> to <code class="language-plaintext highlighter-rouge">Gemfile</code> and ran <code class="language-plaintext highlighter-rouge">bundle install</code></li>
  <li>Configured multilingual locale routing in <code class="language-plaintext highlighter-rouge">_config.yml</code></li>
  <li>Created shared includes for language switcher, SEO tags, and translation feedback</li>
  <li>Wrote session-based preference script in <code class="language-plaintext highlighter-rouge">assets/js/language-session.js</code></li>
  <li>Created bilingual content: <code class="language-plaintext highlighter-rouge">index.markdown</code>, <code class="language-plaintext highlighter-rouge">about.markdown</code>, and a welcome post in both English and Spanish</li>
  <li>Documented redirect rules, content workflow, and rollback procedures</li>
</ul>

<p><strong>Validation</strong>:</p>
<ul>
  <li><code class="language-plaintext highlighter-rouge">bundle exec jekyll build</code> executed successfully</li>
  <li>Generated site includes bilingual routes: <code class="language-plaintext highlighter-rouge">/index.html</code>, <code class="language-plaintext highlighter-rouge">/es/index.html</code>, etc.</li>
  <li><code class="language-plaintext highlighter-rouge">hreflang</code> tags validated on bilingual pages</li>
  <li>No broken internal links</li>
</ul>

<p><strong>Outcome</strong>: A fully functional, validated multilingual Jekyll blog.</p>

<h3 id="step-5-rollout">Step 5: Rollout</h3>

<p>We committed all changes with a clean feature branch commit, ready to merge.</p>

<h2 id="key-decisions-made">Key Decisions Made</h2>

<table>
  <thead>
    <tr>
      <th>Date</th>
      <th>Decision</th>
      <th>Status</th>
      <th>Rationale</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>2026-05-08</td>
      <td>Use Speckit framework</td>
      <td>Accepted</td>
      <td>Specification-first reduces rework</td>
    </tr>
    <tr>
      <td>2026-05-08</td>
      <td>Polyglot plugin</td>
      <td>Accepted</td>
      <td>Native Jekyll plugin, well-maintained</td>
    </tr>
    <tr>
      <td>2026-05-08</td>
      <td>Default lang no prefix</td>
      <td>Accepted</td>
      <td>Cleaner URLs for primary language</td>
    </tr>
    <tr>
      <td>2026-05-08</td>
      <td>301 for unsupported locales</td>
      <td>Accepted</td>
      <td>Preserves SEO, avoids 404s</td>
    </tr>
    <tr>
      <td>2026-05-08</td>
      <td>302 for missing translations</td>
      <td>Accepted</td>
      <td>Temporary redirect allows future translation</td>
    </tr>
    <tr>
      <td>2026-05-08</td>
      <td>Session-scoped preferences</td>
      <td>Accepted</td>
      <td>Respects user privacy, simpler than cookies</td>
    </tr>
    <tr>
      <td>2026-05-08</td>
      <td>hreflang + x-default</td>
      <td>Accepted</td>
      <td>Proper SEO and discoverability for bilingual content</td>
    </tr>
    <tr>
      <td>2026-05-08</td>
      <td>Google Analytics</td>
      <td>Deferred</td>
      <td>Planned for a future feature</td>
    </tr>
  </tbody>
</table>

<h2 id="what-we-didnt-do-non-goals">What We Didn’t Do (Non-Goals)</h2>

<ul>
  <li>Add more than two languages in this release</li>
  <li>Redesign the theme unrelated to language support</li>
  <li>Rewrite all historical content immediately</li>
  <li>Use non-Jekyll build systems or runtime services</li>
</ul>

<p>Keeping scope tight allowed us to deliver quickly and validate thoroughly.</p>

<h2 id="key-artifacts">Key Artifacts</h2>

<p>All of our work is documented and traceable:</p>
<ul>
  <li><strong>Specification</strong>: <code class="language-plaintext highlighter-rouge">specs/001-add-multilingual-support/spec.md</code></li>
  <li><strong>Plan</strong>: <code class="language-plaintext highlighter-rouge">specs/001-add-multilingual-support/plan.md</code></li>
  <li><strong>Tasks</strong>: <code class="language-plaintext highlighter-rouge">specs/001-add-multilingual-support/tasks.md</code></li>
  <li><strong>Contracts</strong>: <code class="language-plaintext highlighter-rouge">specs/001-add-multilingual-support/contracts/multilingual-routing-contract.md</code></li>
  <li><strong>Operational Guides</strong>: <code class="language-plaintext highlighter-rouge">docs/multilingual-*.md</code> (workflow, redirects, rollback)</li>
</ul>

<h2 id="lessons-learned">Lessons Learned</h2>

<ol>
  <li>
    <p><strong>Clarification upfront saves implementation time</strong>: By asking five high-impact questions <em>before</em> coding, we avoided rework and conflicting decisions.</p>
  </li>
  <li>
    <p><strong>Dependency ordering matters</strong>: Breaking work into ordered phases (Setup → Foundational → User Stories) made parallelization safe and reduced blockers.</p>
  </li>
  <li>
    <p><strong>Specification documents are living artifacts</strong>: They serve dual purpose: design guide <em>and</em> future blog post content.</p>
  </li>
  <li>
    <p><strong>Jekyll conventions are your friend</strong>: Staying true to Jekyll’s structure made the implementation straightforward and maintainable.</p>
  </li>
  <li>
    <p><strong>Build validation is non-negotiable</strong>: Running <code class="language-plaintext highlighter-rouge">bundle exec jekyll build</code> after every major change caught issues early.</p>
  </li>
</ol>

<h2 id="next-steps">Next Steps</h2>

<ul>
  <li><strong>Monitor in production</strong>: Watch for any routing or SEO issues.</li>
  <li><strong>Gather user feedback</strong>: See if the language switcher UX works well.</li>
  <li><strong>Plan future improvements</strong>: Google Analytics integration, additional languages, translation management tools.</li>
</ul>

<h2 id="try-it-yourself">Try It Yourself</h2>

<p>If you’re building a Jekyll blog and considering multilingual support, follow this same workflow:</p>

<ol>
  <li>Write a clear spec (what problems are you solving?).</li>
  <li>Clarify key decisions with stakeholders.</li>
  <li>Plan the technical approach (layouts, data, configs).</li>
  <li>Break into ordered tasks with test criteria.</li>
  <li>Implement and validate methodically.</li>
</ol>

<p>The result? A well-reasoned, traceable, and maintainable feature—plus a narrative you can share with your audience.</p>

<hr />

<p><strong>This post is part of a series on building and maintaining jblueprint.dev using modern specification and design practices.</strong></p>]]></content><author><name></name></author><category term="jekyll" /><category term="speckit" /><category term="design" /><summary type="html"><![CDATA[Building a blog from scratch is one thing. Building it well with a clear, traceable methodology is another.]]></summary></entry><entry xml:lang="es"><title type="html">Instalación de Minimal Mistakes en un blog Jekyll multilenguaje</title><link href="https://jblueprint.dev/jekyll/theme/2026/05/08/instalacion-minimal-mistakes.html" rel="alternate" type="text/html" title="Instalación de Minimal Mistakes en un blog Jekyll multilenguaje" /><published>2026-05-08T00:00:00+00:00</published><updated>2026-05-08T00:00:00+00:00</updated><id>https://jblueprint.dev/jekyll/theme/2026/05/08/instalacion-minimal-mistakes</id><content type="html" xml:base="https://jblueprint.dev/jekyll/theme/2026/05/08/instalacion-minimal-mistakes.html"><![CDATA[<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>]]></content><author><name></name></author><category term="jekyll" /><category term="theme" /><category term="minimal-mistakes" /><summary type="html"><![CDATA[Este post documenta la instalación del tema Minimal Mistakes sobre un blog Jekyll con soporte multilenguaje (en y es) basado en jekyll-polyglot.]]></summary></entry><entry xml:lang="en"><title type="html">Installing Minimal Mistakes on a Bilingual Jekyll Blog</title><link href="https://jblueprint.dev/jekyll/theme/minimal-mistakes/2026/05/08/minimal-mistakes-integration.html" rel="alternate" type="text/html" title="Installing Minimal Mistakes on a Bilingual Jekyll Blog" /><published>2026-05-08T00:00:00+00:00</published><updated>2026-05-08T00:00:00+00:00</updated><id>https://jblueprint.dev/jekyll/theme/minimal-mistakes/2026/05/08/minimal-mistakes-integration</id><content type="html" xml:base="https://jblueprint.dev/jekyll/theme/minimal-mistakes/2026/05/08/minimal-mistakes-integration.html"><![CDATA[<p>This post documents how to migrate a bilingual Jekyll blog from the default <code class="language-plaintext highlighter-rouge">minima</code> theme
to <code class="language-plaintext highlighter-rouge">minimal-mistakes-jekyll</code> while preserving full multilingual routing via <code class="language-plaintext highlighter-rouge">jekyll-polyglot</code>.</p>

<h2 id="gem-installation">Gem Installation</h2>

<p>Replace <code class="language-plaintext highlighter-rouge">minima</code> with <code class="language-plaintext highlighter-rouge">minimal-mistakes-jekyll</code> in your <code class="language-plaintext highlighter-rouge">Gemfile</code>:</p>

<div class="language-ruby highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1"># Remove:</span>
<span class="c1"># gem "minima", "~&gt; 2.5"</span>

<span class="c1"># Add:</span>
<span class="n">gem</span> <span class="s2">"minimal-mistakes-jekyll"</span>
</code></pre></div></div>

<p>Then run:</p>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>bundle <span class="nb">install</span>
</code></pre></div></div>

<h2 id="_configyml-changes"><code class="language-plaintext highlighter-rouge">_config.yml</code> Changes</h2>

<h3 id="switch-the-theme-key">Switch the theme key</h3>

<div class="language-yaml highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1"># Remove:</span>
<span class="c1"># theme: minima</span>

<span class="c1"># Add:</span>
<span class="na">theme</span><span class="pi">:</span> <span class="s">minimal-mistakes-jekyll</span>
<span class="na">minimal_mistakes_skin</span><span class="pi">:</span> <span class="s">default</span>   <span class="c1"># Options: air, aqua, contrast, dark, dirt, mint, neon, plum, sunrise</span>
</code></pre></div></div>

<h3 id="add-mm-site-settings">Add MM site settings</h3>

<div class="language-yaml highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="na">locale</span><span class="pi">:</span> <span class="s">en-US</span>          <span class="c1"># Static BCP47 for MM's internal UI strings — DO NOT use for runtime locale detection</span>
<span class="na">breadcrumbs</span><span class="pi">:</span> <span class="no">false</span>     <span class="c1"># Required: MM breadcrumbs are not Polyglot locale-aware</span>
<span class="na">title</span><span class="pi">:</span> <span class="s">your-site-title</span>
<span class="na">name</span><span class="pi">:</span> <span class="s2">"</span><span class="s">Your</span><span class="nv"> </span><span class="s">Name"</span>
<span class="na">description</span><span class="pi">:</span> <span class="s2">"</span><span class="s">Your</span><span class="nv"> </span><span class="s">site</span><span class="nv"> </span><span class="s">description"</span>
<span class="na">url</span><span class="pi">:</span> <span class="s2">"</span><span class="s">https://your-domain.dev"</span>
<span class="na">baseurl</span><span class="pi">:</span> <span class="s2">"</span><span class="s">"</span>
</code></pre></div></div>

<h3 id="update-exclude_from_localization">Update <code class="language-plaintext highlighter-rouge">exclude_from_localization</code></h3>

<p>Remove the old <code class="language-plaintext highlighter-rouge">minima</code> asset paths and add MM’s generated asset paths:</p>

<div class="language-yaml highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="na">exclude_from_localization</span><span class="pi">:</span>
  <span class="c1"># ... other paths ...</span>
  <span class="c1"># Replace:</span>
  <span class="c1"># - assets/main.css</span>
  <span class="c1"># - assets/main.css.map</span>
  <span class="c1"># - assets/minima-social-icons.svg</span>
  <span class="c1"># With:</span>
  <span class="pi">-</span> <span class="s">assets/css/main.scss</span>
  <span class="pi">-</span> <span class="s">assets/css/main.css</span>
  <span class="pi">-</span> <span class="s">assets/js/main.min.js</span>
</code></pre></div></div>

<p>Also add <code class="language-plaintext highlighter-rouge">specs/</code> to Jekyll’s <code class="language-plaintext highlighter-rouge">exclude:</code> list if you have spec markdown files containing
MM-specific Liquid tags (<code class="language-plaintext highlighter-rouge">include_cached</code>) in code blocks — otherwise Jekyll will error
when processing those files under minima:</p>

<div class="language-yaml highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="na">exclude</span><span class="pi">:</span>
  <span class="pi">-</span> <span class="s">specs/</span>
  <span class="c1"># ... other paths ...</span>
</code></pre></div></div>

<h2 id="layout-override-strategy">Layout Override Strategy</h2>

<p>Minimal Mistakes provides built-in layouts that extend its <code class="language-plaintext highlighter-rouge">default.html</code> root layout.
To inject the language switcher and hreflang metadata into every page, two files are added:</p>

<h3 id="_includesheadcustomhtml-new"><code class="language-plaintext highlighter-rouge">_includes/head/custom.html</code> (new)</h3>

<p>MM’s documented extension point for project-level <code class="language-plaintext highlighter-rouge">&lt;head&gt;</code> additions. This file is
automatically included by MM’s <code class="language-plaintext highlighter-rouge">head.html</code> include:</p>

<p>```html<link rel="alternate" hreflang="en" href="/jekyll/theme/minimal-mistakes/2026/05/08/minimal-mistakes-integration.html" /></p>
<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" />
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>
### `_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
---
---&lt;!doctype html&gt;
&lt;html lang="en" class="no-js"&gt;
  &lt;head&gt;
    
&lt;meta charset="utf-8"&gt;


&lt;!-- begin _includes/seo.html --&gt;&lt;title&gt;Installing Minimal Mistakes on a Bilingual Jekyll Blog - jblueprint.dev&lt;/title&gt;
&lt;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."&gt;



&lt;meta property="og:type" content="article"&gt;
&lt;meta property="og:locale" content="en_US"&gt;
&lt;meta property="og:site_name" content="jblueprint.dev"&gt;
&lt;meta property="og:title" content="Installing Minimal Mistakes on a Bilingual Jekyll Blog"&gt;
&lt;meta property="og:url" content="https://jblueprint.dev/jekyll/theme/minimal-mistakes/2026/05/08/minimal-mistakes-integration.html"&gt;


  &lt;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."&gt;









  &lt;meta property="article:published_time" content="2026-05-08T00:00:00+00:00"&gt;






&lt;link rel="canonical" href="https://jblueprint.dev/jekyll/theme/minimal-mistakes/2026/05/08/minimal-mistakes-integration.html"&gt;












&lt;!-- end _includes/seo.html --&gt;



  &lt;link href="/feed.xml" type="application/atom+xml" rel="alternate" title="jblueprint.dev Feed"&gt;
&lt;meta name="viewport" content="width=device-width, initial-scale=1.0"&gt;

&lt;script&gt;
  document.documentElement.className = document.documentElement.className.replace(/\bno-js\b/g, '') + ' js ';
  
&lt;/script&gt;

&lt;!-- For all browsers --&gt;
&lt;link rel="stylesheet" href="/assets/css/main.css"&gt;
&lt;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'"&gt;
&lt;noscript&gt;&lt;link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@fortawesome/fontawesome-free@latest/css/all.min.css"&gt;&lt;/noscript&gt;



    &lt;link rel="alternate" hreflang="en" href="/jekyll/theme/minimal-mistakes/2026/05/08/minimal-mistakes-integration.html"&gt;
  &lt;link rel="alternate" hreflang="es" href="/es/jekyll/theme/minimal-mistakes/2026/05/08/minimal-mistakes-integration.html"&gt;
  &lt;link rel="alternate" hreflang="x-default" href="/jekyll/theme/minimal-mistakes/2026/05/08/minimal-mistakes-integration.html"&gt;
  &lt;/head&gt;
  &lt;body class="layout--post..."&gt;
    
&lt;nav class="skip-links" aria-label="Skip links"&gt;
  &lt;ul&gt;
    &lt;li&gt;&lt;a href="#site-nav" class="screen-reader-shortcut"&gt;Skip to primary navigation&lt;/a&gt;&lt;/li&gt;
    &lt;li&gt;&lt;a href="#main" class="screen-reader-shortcut"&gt;Skip to content&lt;/a&gt;&lt;/li&gt;
    &lt;li&gt;&lt;a href="#footer" class="screen-reader-shortcut"&gt;Skip to footer&lt;/a&gt;&lt;/li&gt;
  &lt;/ul&gt;
&lt;/nav&gt;

    &lt;div class="masthead"&gt;
  &lt;div class="masthead__inner-wrap"&gt;
    &lt;div class="masthead__menu"&gt;
      &lt;nav id="site-nav" class="greedy-nav" aria-label="Primary navigation"&gt;
        
        &lt;a class="site-title" href="/"&gt;
          jblueprint.dev
          
        &lt;/a&gt;
        &lt;ul class="visible-links"&gt;&lt;li class="masthead__menu-item"&gt;
              &lt;a
                href="/"
                
                
              &gt;Home&lt;/a&gt;
            &lt;/li&gt;&lt;li class="masthead__menu-item"&gt;
              &lt;a
                href="/posts/"
                
                
              &gt;Posts&lt;/a&gt;
            &lt;/li&gt;&lt;li class="masthead__menu-item"&gt;
              &lt;a
                href="/about/"
                
                
              &gt;About&lt;/a&gt;
            &lt;/li&gt;&lt;/ul&gt;

        
        &lt;button class="search__toggle" type="button"&gt;
          &lt;span class="visually-hidden"&gt;Toggle search&lt;/span&gt;
          &lt;i class="fas fa-search"&gt;&lt;/i&gt;
        &lt;/button&gt;
        

        &lt;!-- Language switcher — EN/ES styled as masthead toggle buttons --&gt;
        &lt;!-- Language toggle — EN | ES integrated into MM masthead nav bar --&gt;
&lt;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&amp;requested=es"
  data-has-equivalent-en="true"
  data-has-equivalent-es="false"
  data-translation-mode="computed"
&gt;
  &lt;a
    href="#"
    lang="en"
    hreflang="en"
    data-language-option="en"
    class="lang-switch__btn is-active"
    aria-current="true"
  &gt;EN&lt;/a&gt;
  &lt;span class="lang-switch__sep" aria-hidden="true"&gt;|&lt;/span&gt;
  &lt;a
    href="#"
    lang="es"
    hreflang="es"
    data-language-option="es"
    class="lang-switch__btn"
    
  &gt;ES&lt;/a&gt;
&lt;/div&gt;


        &lt;button class="greedy-nav__toggle hidden" type="button"&gt;
          &lt;span class="visually-hidden"&gt;Toggle menu&lt;/span&gt;
          &lt;div class="navicon"&gt;&lt;/div&gt;
        &lt;/button&gt;
        &lt;ul class="hidden-links hidden"&gt;&lt;/ul&gt;
      &lt;/nav&gt;
    &lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;



    &lt;div class="language-switcher-wrapper"&gt;
      &lt;!-- Language toggle — EN | ES integrated into MM masthead nav bar --&gt;
&lt;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&amp;requested=es"
  data-has-equivalent-en="true"
  data-has-equivalent-es="false"
  data-translation-mode="computed"
&gt;
  &lt;a
    href="#"
    lang="en"
    hreflang="en"
    data-language-option="en"
    class="lang-switch__btn is-active"
    aria-current="true"
  &gt;EN&lt;/a&gt;
  &lt;span class="lang-switch__sep" aria-hidden="true"&gt;|&lt;/span&gt;
  &lt;a
    href="#"
    lang="es"
    hreflang="es"
    data-language-option="es"
    class="lang-switch__btn"
    
  &gt;ES&lt;/a&gt;
&lt;/div&gt;

      &lt;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."
&gt;
  Translation not available for the selected language.
&lt;/div&gt;


    &lt;/div&gt;

    &lt;div id="main" role="main"&gt;
      







&lt;div id="main" role="main"&gt;
  



  &lt;article class="page h-entry" itemscope itemtype="https://schema.org/CreativeWork"&gt;
    &lt;meta itemprop="headline" content="Instalación de Minimal Mistakes en un blog Jekyll multilenguaje"&gt;
    &lt;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."&gt;
    &lt;meta itemprop="datePublished" content="2026-05-08T00:00:00+00:00"&gt;
    

    &lt;div class="page__inner-wrap"&gt;
      
        &lt;header&gt;
          &lt;h1 id="page-title" class="page__title p-name" itemprop="headline"&gt;
            &lt;a href="https://jblueprint.dev/jekyll/theme/2026/05/08/instalacion-minimal-mistakes.html" itemprop="url"&gt;Instalación de Minimal Mistakes en un blog Jekyll multilenguaje
&lt;/a&gt;
          &lt;/h1&gt;
          



        &lt;/header&gt;
      

      &lt;section class="page__content e-content" itemprop="text"&gt;
        
        &lt;p&gt;Este post documenta la instalación del tema &lt;strong&gt;Minimal Mistakes&lt;/strong&gt; sobre un blog Jekyll con soporte multilenguaje (&lt;code class="language-plaintext highlighter-rouge"&gt;en&lt;/code&gt; y &lt;code class="language-plaintext highlighter-rouge"&gt;es&lt;/code&gt;) basado en &lt;code class="language-plaintext highlighter-rouge"&gt;jekyll-polyglot&lt;/code&gt;.&lt;/p&gt;

&lt;h2 id="objetivo"&gt;Objetivo&lt;/h2&gt;

&lt;ul&gt;
  &lt;li&gt;Integrar Minimal Mistakes como tema principal.&lt;/li&gt;
  &lt;li&gt;Mantener compatibilidad con el enrutado actual multilenguaje.&lt;/li&gt;
  &lt;li&gt;Conservar el selector de idioma y el comportamiento de fallback existente.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id="estado-actual"&gt;Estado actual&lt;/h2&gt;

&lt;ul&gt;
  &lt;li&gt;La especificación de esta feature está en &lt;code class="language-plaintext highlighter-rouge"&gt;specs/002-add-minimal-mistakes-theme/spec.md&lt;/code&gt;.&lt;/li&gt;
  &lt;li&gt;La fase de clarificación ya incluye requisitos para:
    &lt;ul&gt;
      &lt;li&gt;compatibilidad con rutas &lt;code class="language-plaintext highlighter-rouge"&gt;default&lt;/code&gt; y &lt;code class="language-plaintext highlighter-rouge"&gt;/es/&lt;/code&gt;,&lt;/li&gt;
      &lt;li&gt;documentación de la instalación,&lt;/li&gt;
      &lt;li&gt;organización temporal de &lt;code class="language-plaintext highlighter-rouge"&gt;_posts&lt;/code&gt; en carpetas por mes y día.&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id="próximos-pasos"&gt;Próximos pasos&lt;/h2&gt;

&lt;ol&gt;
  &lt;li&gt;Ejecutar &lt;code class="language-plaintext highlighter-rouge"&gt;speckit.plan&lt;/code&gt; para diseñar la migración de tema.&lt;/li&gt;
  &lt;li&gt;Generar tareas con &lt;code class="language-plaintext highlighter-rouge"&gt;speckit.tasks&lt;/code&gt;.&lt;/li&gt;
  &lt;li&gt;Implementar la migración validando build y rutas bilingües.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Iremos actualizando este post conforme avance la implementación.&lt;/p&gt;


        
      &lt;/section&gt;

      &lt;footer class="page__meta"&gt;
        
        

  

  


        


  &lt;p class="page__date"&gt;&lt;strong&gt;&lt;i class="fas fa-fw fa-calendar-alt" aria-hidden="true"&gt;&lt;/i&gt; Updated:&lt;/strong&gt; &lt;time class="dt-published" datetime="2026-05-08T00:00:00+00:00"&gt;May 8, 2026&lt;/time&gt;&lt;/p&gt;


      &lt;/footer&gt;

      

      

  &lt;nav class="pagination" aria-label="Post pagination"&gt;
    
      &lt;a href="#" class="pagination--pager disabled"&gt;Previous&lt;/a&gt;
    
    
      &lt;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"&gt;Next&lt;/a&gt;
    
  &lt;/nav&gt;


    &lt;/div&gt;

    
  &lt;/article&gt;

  
  
&lt;/div&gt;

    &lt;/div&gt;

    &lt;div id="footer" class="page__footer"&gt;
      &lt;footer&gt;
        &lt;!-- start custom footer snippets --&gt;

&lt;!-- end custom footer snippets --&gt;
        


&lt;div class="page__footer-follow"&gt;
  &lt;ul class="social-icons"&gt;
    

    

    
      &lt;li&gt;&lt;a href="/feed.xml"&gt;&lt;i class="fas fa-fw fa-square-rss" aria-hidden="true"&gt;&lt;/i&gt; Feed&lt;/a&gt;&lt;/li&gt;
    
  &lt;/ul&gt;
&lt;/div&gt;


&lt;div class="page__footer-copyright"&gt;&amp;copy; 2026 &lt;a href="https://jblueprint.dev"&gt;jblueprint.dev&lt;/a&gt;. Powered by &lt;a href="https://jekyllrb.com" rel="nofollow"&gt;Jekyll&lt;/a&gt; &amp;amp; &lt;a href="https://mademistakes.com/work/jekyll-themes/minimal-mistakes/" rel="nofollow"&gt;Minimal Mistakes&lt;/a&gt;.&lt;/div&gt;

      &lt;/footer&gt;
    &lt;/div&gt;

    

  &lt;script src="/assets/js/main.min.js"&gt;&lt;/script&gt;





&lt;script src="/assets/js/lunr/lunr.min.js"&gt;&lt;/script&gt;
&lt;script src="/assets/js/lunr/lunr-store.js"&gt;&lt;/script&gt;
&lt;script src="/assets/js/lunr/lunr-en.js"&gt;&lt;/script&gt;








    &lt;script src="/assets/js/language-session.js" defer&gt;&lt;/script&gt;
  &lt;/body&gt;
&lt;/html&gt;
</code></pre></div></div>

<h3 id="_layoutshomehtml-override-for-bilingual-post-listing"><code class="language-plaintext highlighter-rouge">_layouts/home.html</code> (override for bilingual post listing)</h3>

<p>MM ships a <code class="language-plaintext highlighter-rouge">home</code> layout, but it does not filter posts by locale. Override it to filter
<code class="language-plaintext highlighter-rouge">site.posts</code> by <code class="language-plaintext highlighter-rouge">site.active_lang</code> (the Polyglot runtime locale):</p>

<div class="language-html highlighter-rouge"><div class="highlight"><pre class="highlight"><code>---
layout: default
---
<span class="nt">&lt;div</span> <span class="na">class=</span><span class="s">"home"</span><span class="nt">&gt;&lt;h2</span> <span class="na">class=</span><span class="s">"post-list-heading"</span><span class="nt">&gt;</span>Posts<span class="nt">&lt;/h2&gt;</span>
    <span class="nt">&lt;ul</span> <span class="na">class=</span><span class="s">"post-list"</span><span class="nt">&gt;&lt;li&gt;</span>
          <span class="nt">&lt;span</span> <span class="na">class=</span><span class="s">"post-meta"</span><span class="nt">&gt;</span>May 8, 2026<span class="nt">&lt;/span&gt;</span>
          <span class="nt">&lt;h3&gt;</span>
            <span class="nt">&lt;a</span> <span class="na">class=</span><span class="s">"post-link"</span> <span class="na">href=</span><span class="s">"/jekyll/speckit/2026/05/08/how-to-build-a-blog-with-spec-driven-design.html"</span><span class="nt">&gt;</span>
              How to Build a Blog Using Spec Driven Design
            <span class="nt">&lt;/a&gt;</span>
          <span class="nt">&lt;/h3&gt;</span>
        <span class="nt">&lt;/li&gt;&lt;li&gt;</span>
          <span class="nt">&lt;span</span> <span class="na">class=</span><span class="s">"post-meta"</span><span class="nt">&gt;</span>May 8, 2026<span class="nt">&lt;/span&gt;</span>
          <span class="nt">&lt;h3&gt;</span>
            <span class="nt">&lt;a</span> <span class="na">class=</span><span class="s">"post-link"</span> <span class="na">href=</span><span class="s">"/jekyll/speckit/2026/05/08/como-crear-un-blog-con-spec-driven-design.html"</span><span class="nt">&gt;</span>
              Cómo crear un blog con Spec Driven Design
            <span class="nt">&lt;/a&gt;</span>
          <span class="nt">&lt;/h3&gt;</span>
        <span class="nt">&lt;/li&gt;&lt;li&gt;</span>
          <span class="nt">&lt;span</span> <span class="na">class=</span><span class="s">"post-meta"</span><span class="nt">&gt;</span>May 8, 2026<span class="nt">&lt;/span&gt;</span>
          <span class="nt">&lt;h3&gt;</span>
            <span class="nt">&lt;a</span> <span class="na">class=</span><span class="s">"post-link"</span> <span class="na">href=</span><span class="s">"/jekyll/theme/minimal-mistakes/2026/05/08/minimal-mistakes-integration.html"</span><span class="nt">&gt;</span>
              Installing Minimal Mistakes on a Bilingual Jekyll Blog
            <span class="nt">&lt;/a&gt;</span>
          <span class="nt">&lt;/h3&gt;</span>
        <span class="nt">&lt;/li&gt;&lt;li&gt;</span>
          <span class="nt">&lt;span</span> <span class="na">class=</span><span class="s">"post-meta"</span><span class="nt">&gt;</span>May 8, 2026<span class="nt">&lt;/span&gt;</span>
          <span class="nt">&lt;h3&gt;</span>
            <span class="nt">&lt;a</span> <span class="na">class=</span><span class="s">"post-link"</span> <span class="na">href=</span><span class="s">"/jekyll/theme/2026/05/08/instalacion-minimal-mistakes.html"</span><span class="nt">&gt;</span>
              Instalación de Minimal Mistakes en un blog Jekyll multilenguaje
            <span class="nt">&lt;/a&gt;</span>
          <span class="nt">&lt;/h3&gt;</span>
        <span class="nt">&lt;/li&gt;&lt;/ul&gt;&lt;/div&gt;</span>
</code></pre></div></div>

<h3 id="bridge-layouts-for-standard-jekyll-front-matter">Bridge layouts for standard Jekyll front matter</h3>

<p>MM uses <code class="language-plaintext highlighter-rouge">layout: single</code> for posts and pages, not <code class="language-plaintext highlighter-rouge">layout: post</code> / <code class="language-plaintext highlighter-rouge">layout: page</code>.
Add thin bridges so existing content continues to work:</p>

<p><strong><code class="language-plaintext highlighter-rouge">_layouts/post.html</code></strong>:</p>
<div class="language-html highlighter-rouge"><div class="highlight"><pre class="highlight"><code>---
layout: single
---
</code></pre></div></div>

<p><strong><code class="language-plaintext highlighter-rouge">_layouts/page.html</code></strong>:</p>
<div class="language-html highlighter-rouge"><div class="highlight"><pre class="highlight"><code>---
layout: single
---
</code></pre></div></div>

<h2 id="language-switcher-preservation">Language Switcher Preservation</h2>

<p>The existing <code class="language-plaintext highlighter-rouge">_includes/language-switcher.html</code>, <code class="language-plaintext highlighter-rouge">_includes/translation-feedback.html</code>,
and <code class="language-plaintext highlighter-rouge">assets/js/language-session.js</code> require no changes. They are injected via the
<code class="language-plaintext highlighter-rouge">_layouts/default.html</code> override and continue to work exactly as before the theme migration.</p>

<h2 id="navigation">Navigation</h2>

<p>Create <code class="language-plaintext highlighter-rouge">_data/navigation.yml</code> for MM’s masthead:</p>

<div class="language-yaml highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="na">main</span><span class="pi">:</span>
  <span class="pi">-</span> <span class="na">title</span><span class="pi">:</span> <span class="s2">"</span><span class="s">Home"</span>
    <span class="na">url</span><span class="pi">:</span> <span class="s">/</span>
  <span class="pi">-</span> <span class="na">title</span><span class="pi">:</span> <span class="s2">"</span><span class="s">About"</span>
    <span class="na">url</span><span class="pi">:</span> <span class="s">/about/</span>
</code></pre></div></div>

<p>Do not embed language-switcher links here — MM navigation is a static key/URL list and
does not evaluate Liquid expressions.</p>

<h2 id="post-directory-convention">Post Directory Convention</h2>

<p>New posts use the <code class="language-plaintext highlighter-rouge">_posts/&lt;year&gt;/&lt;month&gt;/&lt;day&gt;/YYYY-MM-DD-title.md</code> convention.
Jekyll only uses the filename to determine date and slug; the directory structure is
organizational only. Existing posts at other paths are unaffected.</p>

<h2 id="rollback-path">Rollback Path</h2>

<p>To restore <code class="language-plaintext highlighter-rouge">minima</code> without losing multilingual content:</p>

<ol>
  <li><code class="language-plaintext highlighter-rouge">Gemfile</code>: Restore <code class="language-plaintext highlighter-rouge">gem "minima", "~&gt; 2.5"</code>.</li>
  <li><code class="language-plaintext highlighter-rouge">_config.yml</code>: Restore <code class="language-plaintext highlighter-rouge">theme: minima</code>; remove MM-specific keys; restore minima asset exclusions.</li>
  <li>Remove <code class="language-plaintext highlighter-rouge">_layouts/default.html</code>, <code class="language-plaintext highlighter-rouge">_layouts/home.html</code>, <code class="language-plaintext highlighter-rouge">_layouts/post.html</code>, <code class="language-plaintext highlighter-rouge">_layouts/page.html</code>.</li>
  <li>Remove <code class="language-plaintext highlighter-rouge">_includes/head/custom.html</code> and <code class="language-plaintext highlighter-rouge">_data/navigation.yml</code>.</li>
  <li>Run <code class="language-plaintext highlighter-rouge">bundle install &amp;&amp; bundle exec jekyll build</code> to verify.</li>
</ol>

<p>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.</p>]]></content><author><name></name></author><category term="jekyll" /><category term="theme" /><category term="minimal-mistakes" /><summary type="html"><![CDATA[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.]]></summary></entry></feed>