diff --git a/_includes/layouts/base.njk b/_includes/layouts/base.njk index e69de29..5aca338 100644 --- a/_includes/layouts/base.njk +++ b/_includes/layouts/base.njk @@ -0,0 +1,635 @@ + + + + + + + + + + {# OG image resolution handled by og-fix transform in eleventy.config.js + to bypass Eleventy 3.x parallel rendering race condition (#3183). + Template outputs __OG_IMAGE_PLACEHOLDER__ and __TWITTER_CARD_PLACEHOLDER__ + which the transform replaces using the correct slug derived from outputPath. #} + + + + {% if title %}{{ title }} - {% endif %}{{ site.name }} + + {# OpenGraph meta tags #} + {% set ogTitle = title | default(site.name) %} + {% set ogDesc = description | default(content | ogDescription(200)) | default(site.description) %} + {# Normalize photo - could be array for multi-photo posts #} + {% set ogPhoto = photo %} + {% if ogPhoto %} + {% if ogPhoto[0] and (ogPhoto[0] | length) > 10 %} + {% set ogPhoto = ogPhoto[0] %} + {% endif %} + {% endif %} + + + + + + + {% if ogPhoto and ogPhoto != "" and (ogPhoto | length) > 10 %} + + {% elif image and image != "" and (image | length) > 10 %} + + {% else %} + + {% endif %} + + + + + {# Twitter Card meta tags #} + {% set hasExplicitImage = (ogPhoto and ogPhoto != "" and (ogPhoto | length) > 10) or (image and image != "" and (image | length) > 10) %} + + + + {% if ogPhoto and ogPhoto != "" and (ogPhoto | length) > 10 %} + + {% elif image and image != "" and (image | length) > 10 %} + + {% else %} + + {% endif %} + + {# Favicon #} + + + + {# Preload critical fonts — starts download before CSS is parsed #} + + + + + {# Critical CSS — inlined for fast first paint #} + + {# Defer full stylesheet — loads after first paint #} + + + + + + + + + + + {# Alpine.js components — MUST load before Alpine core (Alpine.data() registration via alpine:init) #} + + + + + + + + + + + {# Graceful no-JS fallback: show content that Alpine would normally control #} + + + + + + + {% if site.markdownAgents.enabled and page.url and page.url.startsWith('/articles/') and page.url != '/articles/' %} + + {% endif %} + {% if category and page.url and page.url.startsWith('/categories/') and page.url != '/categories/' %} + + + {% endif %} + + + + + + + + + + {# Fediverse creator meta tag for Mastodon verification #} + {% if site.fediverseCreator %} + + {% endif %} + + {# IndieAuth rel="me" links for identity verification #} + {# Note: Bluesky links use "me atproto" for verification #} + {% for social in site.social %} + + {% endfor %} + + {# Leaflet map — loaded only on pages that set leafletMap: true in front matter #} + {# CSS is synchronous (Leaflet requires CSS before map init); JS is non-deferred (inline init script runs synchronously in body) #} + {% if leafletMap %} + + + + + + {% endif %} + + + + + + +
+ {% if withSidebar and page.url == "/" and homepageConfig and homepageConfig.sections %} + {# Homepage: builder controls its own layout and sidebar #} + {{ content | safe }} + {% elif withSidebar %} +
+
+ {{ content | safe }} +
+ +
+ {% elif withBlogSidebar %} +
+
+ {{ content | safe }} +
+ +
+ {% else %} + {{ content | safe }} + {% endif %} +
+ + + + {# Island architecture - lazy hydration for widgets #} + + {# Relative date display - progressively enhances