feat: wrap all widgets and comments in is-land on:visible

Add <is-land on:visible> lazy-loading wrapper to every widget template
and the comments section for consistent deferred rendering. Widgets
that already had it (social-activity, github-repos, blogroll, feedland,
webmentions) are unchanged. Also wraps inline search and custom-html
widgets in all sidebar container files.
This commit is contained in:
Ricardo
2026-02-22 00:31:01 +01:00
parent 791dccf223
commit 1bf6f9358a
17 changed files with 42 additions and 0 deletions
+4
View File
@@ -35,13 +35,16 @@
{% elif widget.type == "recent-comments" %} {% elif widget.type == "recent-comments" %}
{% include "components/widgets/recent-comments.njk" %} {% include "components/widgets/recent-comments.njk" %}
{% elif widget.type == "search" %} {% elif widget.type == "search" %}
<is-land on:visible>
<div class="widget"> <div class="widget">
<h3 class="widget-title">Search</h3> <h3 class="widget-title">Search</h3>
<div id="blog-sidebar-search"></div> <div id="blog-sidebar-search"></div>
<script>initPagefind("#blog-sidebar-search");</script> <script>initPagefind("#blog-sidebar-search");</script>
</div> </div>
</is-land>
{% elif widget.type == "custom-html" %} {% elif widget.type == "custom-html" %}
{% set wConfig = widget.config or {} %} {% set wConfig = widget.config or {} %}
<is-land on:visible>
<div class="widget"> <div class="widget">
{% if wConfig.title %} {% if wConfig.title %}
<h3 class="widget-title">{{ wConfig.title }}</h3> <h3 class="widget-title">{{ wConfig.title }}</h3>
@@ -52,6 +55,7 @@
</div> </div>
{% endif %} {% endif %}
</div> </div>
</is-land>
{% else %} {% else %}
<!-- Unknown widget type: {{ widget.type }} --> <!-- Unknown widget type: {{ widget.type }} -->
{% endif %} {% endif %}
+2
View File
@@ -1,6 +1,7 @@
{# Comments section — shown on post pages before webmentions #} {# Comments section — shown on post pages before webmentions #}
{% set absoluteUrl = site.url + page.url %} {% set absoluteUrl = site.url + page.url %}
<is-land on:visible>
<section class="comments mt-8 pt-8 border-t border-surface-200 dark:border-surface-700" id="comments" <section class="comments mt-8 pt-8 border-t border-surface-200 dark:border-surface-700" id="comments"
x-data="commentsSection('{{ absoluteUrl }}')" x-data="commentsSection('{{ absoluteUrl }}')"
x-init="init()"> x-init="init()">
@@ -92,3 +93,4 @@
</template> </template>
</div> </div>
</section> </section>
</is-land>
+4
View File
@@ -18,16 +18,19 @@
{% elif widget.type == "categories" %} {% elif widget.type == "categories" %}
{% include "components/widgets/categories.njk" %} {% include "components/widgets/categories.njk" %}
{% elif widget.type == "search" %} {% elif widget.type == "search" %}
<is-land on:visible>
<div class="widget"> <div class="widget">
<h3 class="widget-title">Search</h3> <h3 class="widget-title">Search</h3>
<div id="sidebar-search"></div> <div id="sidebar-search"></div>
<script>initPagefind("#sidebar-search");</script> <script>initPagefind("#sidebar-search");</script>
</div> </div>
</is-land>
{% elif widget.type == "webmentions" %} {% elif widget.type == "webmentions" %}
{% include "components/widgets/webmentions.njk" %} {% include "components/widgets/webmentions.njk" %}
{% elif widget.type == "custom-html" %} {% elif widget.type == "custom-html" %}
{# Custom content widget #} {# Custom content widget #}
{% set wConfig = widget.config or {} %} {% set wConfig = widget.config or {} %}
<is-land on:visible>
<div class="widget"> <div class="widget">
{% if wConfig.title %} {% if wConfig.title %}
<h3 class="widget-title">{{ wConfig.title }}</h3> <h3 class="widget-title">{{ wConfig.title }}</h3>
@@ -38,6 +41,7 @@
</div> </div>
{% endif %} {% endif %}
</div> </div>
</is-land>
{% else %} {% else %}
<!-- Unknown widget type: {{ widget.type }} --> <!-- Unknown widget type: {{ widget.type }} -->
{% endif %} {% endif %}
@@ -18,11 +18,13 @@
{% elif widget.type == "categories" %} {% elif widget.type == "categories" %}
{% include "components/widgets/categories.njk" %} {% include "components/widgets/categories.njk" %}
{% elif widget.type == "search" %} {% elif widget.type == "search" %}
<is-land on:visible>
<div class="widget"> <div class="widget">
<h3 class="widget-title">Search</h3> <h3 class="widget-title">Search</h3>
<div id="sidebar-search"></div> <div id="sidebar-search"></div>
<script>initPagefind("#sidebar-search");</script> <script>initPagefind("#sidebar-search");</script>
</div> </div>
</is-land>
{% elif widget.type == "webmentions" %} {% elif widget.type == "webmentions" %}
{% include "components/widgets/webmentions.njk" %} {% include "components/widgets/webmentions.njk" %}
{% elif widget.type == "recent-comments" %} {% elif widget.type == "recent-comments" %}
@@ -30,6 +32,7 @@
{% elif widget.type == "custom-html" %} {% elif widget.type == "custom-html" %}
{# Custom content widget #} {# Custom content widget #}
{% set wConfig = widget.config or {} %} {% set wConfig = widget.config or {} %}
<is-land on:visible>
<div class="widget"> <div class="widget">
{% if wConfig.title %} {% if wConfig.title %}
<h3 class="widget-title">{{ wConfig.title }}</h3> <h3 class="widget-title">{{ wConfig.title }}</h3>
@@ -40,6 +43,7 @@
</div> </div>
{% endif %} {% endif %}
</div> </div>
</is-land>
{% else %} {% else %}
<!-- Unknown widget type: {{ widget.type }} --> <!-- Unknown widget type: {{ widget.type }} -->
{% endif %} {% endif %}
+4
View File
@@ -29,15 +29,18 @@
{% elif widget.type == "recent-comments" %} {% elif widget.type == "recent-comments" %}
{% include "components/widgets/recent-comments.njk" %} {% include "components/widgets/recent-comments.njk" %}
{% elif widget.type == "search" %} {% elif widget.type == "search" %}
<is-land on:visible>
<div class="widget"> <div class="widget">
<h3 class="widget-title">Search</h3> <h3 class="widget-title">Search</h3>
<div id="listing-sidebar-search"></div> <div id="listing-sidebar-search"></div>
<script>initPagefind("#listing-sidebar-search");</script> <script>initPagefind("#listing-sidebar-search");</script>
</div> </div>
</is-land>
{% elif widget.type == "webmentions" %} {% elif widget.type == "webmentions" %}
{% include "components/widgets/webmentions.njk" %} {% include "components/widgets/webmentions.njk" %}
{% elif widget.type == "custom-html" %} {% elif widget.type == "custom-html" %}
{% set wConfig = widget.config or {} %} {% set wConfig = widget.config or {} %}
<is-land on:visible>
<div class="widget"> <div class="widget">
{% if wConfig.title %} {% if wConfig.title %}
<h3 class="widget-title">{{ wConfig.title }}</h3> <h3 class="widget-title">{{ wConfig.title }}</h3>
@@ -48,6 +51,7 @@
</div> </div>
{% endif %} {% endif %}
</div> </div>
</is-land>
{% else %} {% else %}
<!-- Unknown widget type: {{ widget.type }} --> <!-- Unknown widget type: {{ widget.type }} -->
{% endif %} {% endif %}
@@ -1,4 +1,5 @@
{# Author Compact Card - h-card microformat (compact version for blog sidebars) #} {# Author Compact Card - h-card microformat (compact version for blog sidebars) #}
<is-land on:visible>
<div class="widget"> <div class="widget">
<div class="h-card p-author flex items-center gap-3"> <div class="h-card p-author flex items-center gap-3">
{# Hidden u-photo for reliable microformat parsing #} {# Hidden u-photo for reliable microformat parsing #}
@@ -26,3 +27,4 @@
{% if site.author.email %}<data class="u-email hidden" value="{{ site.author.email }}"></data>{% endif %} {% if site.author.email %}<data class="u-email hidden" value="{{ site.author.email }}"></data>{% endif %}
{% if site.author.org %}<data class="p-org hidden" value="{{ site.author.org }}"></data>{% endif %} {% if site.author.org %}<data class="p-org hidden" value="{{ site.author.org }}"></data>{% endif %}
</div> </div>
</is-land>
@@ -1,4 +1,6 @@
{# Author Card Widget - includes the canonical h-card component #} {# Author Card Widget - includes the canonical h-card component #}
<is-land on:visible>
<div class="widget"> <div class="widget">
{% include "components/h-card.njk" %} {% include "components/h-card.njk" %}
</div> </div>
</is-land>
@@ -1,5 +1,6 @@
{# Categories/Tags Widget #} {# Categories/Tags Widget #}
{% if categories and categories.length %} {% if categories and categories.length %}
<is-land on:visible>
<div class="widget"> <div class="widget">
<h3 class="widget-title">Categories</h3> <h3 class="widget-title">Categories</h3>
<div class="flex flex-wrap gap-2"> <div class="flex flex-wrap gap-2">
@@ -10,4 +11,5 @@
{% endfor %} {% endfor %}
</div> </div>
</div> </div>
</is-land>
{% endif %} {% endif %}
@@ -1,6 +1,7 @@
{# Listening Widget — combined Funkwhale + Last.fm recent tracks #} {# Listening Widget — combined Funkwhale + Last.fm recent tracks #}
{% set hasListening = (funkwhaleActivity and (funkwhaleActivity.nowPlaying or funkwhaleActivity.listenings.length)) or (lastfmActivity and (lastfmActivity.nowPlaying or lastfmActivity.scrobbles.length)) %} {% set hasListening = (funkwhaleActivity and (funkwhaleActivity.nowPlaying or funkwhaleActivity.listenings.length)) or (lastfmActivity and (lastfmActivity.nowPlaying or lastfmActivity.scrobbles.length)) %}
{% if hasListening %} {% if hasListening %}
<is-land on:visible>
<div class="widget"> <div class="widget">
<h3 class="widget-title flex items-center gap-2"> <h3 class="widget-title flex items-center gap-2">
<svg class="w-5 h-5 text-purple-500" fill="none" stroke="currentColor" viewBox="0 0 24 24"> <svg class="w-5 h-5 text-purple-500" fill="none" stroke="currentColor" viewBox="0 0 24 24">
@@ -110,4 +111,5 @@
<svg class="w-3 h-3" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 5l7 7-7 7"/></svg> <svg class="w-3 h-3" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 5l7 7-7 7"/></svg>
</a> </a>
</div> </div>
</is-land>
{% endif %} {% endif %}
@@ -1,5 +1,6 @@
{# Categories for This Post #} {# Categories for This Post #}
{% if category %} {% if category %}
<is-land on:visible>
<div class="widget"> <div class="widget">
<h3 class="widget-title">Categories</h3> <h3 class="widget-title">Categories</h3>
<div class="flex flex-wrap gap-2"> <div class="flex flex-wrap gap-2">
@@ -16,4 +17,5 @@
{% endif %} {% endif %}
</div> </div>
</div> </div>
</is-land>
{% endif %} {% endif %}
@@ -4,6 +4,7 @@
{% set _nextPost = collections.posts | nextInCollection(page) %} {% set _nextPost = collections.posts | nextInCollection(page) %}
{% if _prevPost or _nextPost %} {% if _prevPost or _nextPost %}
<is-land on:visible>
<div class="widget"> <div class="widget">
<h3 class="widget-title">More Posts</h3> <h3 class="widget-title">More Posts</h3>
<div class="space-y-3"> <div class="space-y-3">
@@ -61,4 +62,5 @@
{% endif %} {% endif %}
</div> </div>
</div> </div>
</is-land>
{% endif %} {% endif %}
@@ -1,5 +1,6 @@
{# Recent Comments Widget — sidebar #} {# Recent Comments Widget — sidebar #}
{% if recentComments and recentComments.length %} {% if recentComments and recentComments.length %}
<is-land on:visible>
<div class="widget"> <div class="widget">
<h3 class="widget-title">Recent Comments</h3> <h3 class="widget-title">Recent Comments</h3>
<ul class="space-y-3"> <ul class="space-y-3">
@@ -22,4 +23,5 @@
{% endfor %} {% endfor %}
</ul> </ul>
</div> </div>
</is-land>
{% endif %} {% endif %}
@@ -1,6 +1,7 @@
{# Recent Posts Widget — type-aware, for blog/post sidebars #} {# Recent Posts Widget — type-aware, for blog/post sidebars #}
{# Uses collections.posts directly (all post types, not just recentPosts collection) #} {# Uses collections.posts directly (all post types, not just recentPosts collection) #}
{% if collections.posts %} {% if collections.posts %}
<is-land on:visible>
<div class="widget"> <div class="widget">
<h3 class="widget-title">Recent Posts</h3> <h3 class="widget-title">Recent Posts</h3>
<ul class="space-y-3"> <ul class="space-y-3">
@@ -80,4 +81,5 @@
View all posts View all posts
</a> </a>
</div> </div>
</is-land>
{% endif %} {% endif %}
@@ -1,5 +1,6 @@
{# Recent Posts Widget (sidebar) - compact type-aware list #} {# Recent Posts Widget (sidebar) - compact type-aware list #}
{% if recentPosts and recentPosts.length %} {% if recentPosts and recentPosts.length %}
<is-land on:visible>
<div class="widget"> <div class="widget">
<h3 class="widget-title">Recent Posts</h3> <h3 class="widget-title">Recent Posts</h3>
<ul class="space-y-3"> <ul class="space-y-3">
@@ -87,4 +88,5 @@
View all posts View all posts
</a> </a>
</div> </div>
</is-land>
{% endif %} {% endif %}
+2
View File
@@ -1,4 +1,5 @@
{# Share Widget #} {# Share Widget #}
<is-land on:visible>
<div class="widget"> <div class="widget">
<h3 class="widget-title">Share</h3> <h3 class="widget-title">Share</h3>
<div class="flex gap-2"> <div class="flex gap-2">
@@ -22,3 +23,4 @@
</a> </a>
</div> </div>
</div> </div>
</is-land>
@@ -1,4 +1,5 @@
{# Subscribe Widget #} {# Subscribe Widget #}
<is-land on:visible>
<div class="widget"> <div class="widget">
<h3 class="widget-title">Subscribe</h3> <h3 class="widget-title">Subscribe</h3>
<div class="space-y-2"> <div class="space-y-2">
@@ -16,3 +17,4 @@
</a> </a>
</div> </div>
</div> </div>
</is-land>
+2
View File
@@ -1,5 +1,6 @@
{# Table of Contents Widget (for articles with headings) #} {# Table of Contents Widget (for articles with headings) #}
{% if toc and toc.length %} {% if toc and toc.length %}
<is-land on:visible>
<div class="widget"> <div class="widget">
<h3 class="widget-title">Contents</h3> <h3 class="widget-title">Contents</h3>
<nav class="toc"> <nav class="toc">
@@ -14,4 +15,5 @@
</ul> </ul>
</nav> </nav>
</div> </div>
</is-land>
{% endif %} {% endif %}