feat: add WebSub support for real-time feed updates
Advertise WebSub hub (websubhub.com) in three discovery layers: - HTML <link rel="hub"> in page head - <atom:link rel="hub"> in RSS feed - "hubs" array in JSON Feed 1.1 Notify hub after each Eleventy build so subscribers receive push updates when new content is published. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -65,6 +65,7 @@
|
|||||||
<link rel="token_endpoint" href="{{ site.url }}/auth/token">
|
<link rel="token_endpoint" href="{{ site.url }}/auth/token">
|
||||||
<link rel="micropub" href="{{ site.url }}/micropub">
|
<link rel="micropub" href="{{ site.url }}/micropub">
|
||||||
<link rel="microsub" href="{{ site.url }}/microsub">
|
<link rel="microsub" href="{{ site.url }}/microsub">
|
||||||
|
<link rel="hub" href="https://websubhub.com/hub">
|
||||||
<link rel="webmention" href="https://webmention.io/{{ site.webmentions.domain }}/webmention">
|
<link rel="webmention" href="https://webmention.io/{{ site.webmentions.domain }}/webmention">
|
||||||
<link rel="pingback" href="https://webmention.io/{{ site.webmentions.domain }}/xmlrpc">
|
<link rel="pingback" href="https://webmention.io/{{ site.webmentions.domain }}/xmlrpc">
|
||||||
|
|
||||||
|
|||||||
@@ -404,8 +404,9 @@ export default function (eleventyConfig) {
|
|||||||
.slice(0, 5);
|
.slice(0, 5);
|
||||||
});
|
});
|
||||||
|
|
||||||
// Pagefind indexing after each build
|
// Pagefind indexing + WebSub hub notification after each build
|
||||||
eleventyConfig.on("eleventy.after", ({ dir, runMode }) => {
|
eleventyConfig.on("eleventy.after", async ({ dir, runMode }) => {
|
||||||
|
// Pagefind indexing
|
||||||
try {
|
try {
|
||||||
console.log(`[pagefind] Indexing ${dir.output} (${runMode})...`);
|
console.log(`[pagefind] Indexing ${dir.output} (${runMode})...`);
|
||||||
execFileSync("npx", ["pagefind", "--site", dir.output, "--glob", "**/*.html"], {
|
execFileSync("npx", ["pagefind", "--site", dir.output, "--glob", "**/*.html"], {
|
||||||
@@ -416,6 +417,25 @@ export default function (eleventyConfig) {
|
|||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.error("[pagefind] Indexing failed:", err.message);
|
console.error("[pagefind] Indexing failed:", err.message);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// WebSub hub notification — notify subscribers of feed updates
|
||||||
|
const hubUrl = "https://websubhub.com/hub";
|
||||||
|
const feedUrls = [
|
||||||
|
`${siteUrl}/feed.xml`,
|
||||||
|
`${siteUrl}/feed.json`,
|
||||||
|
];
|
||||||
|
for (const feedUrl of feedUrls) {
|
||||||
|
try {
|
||||||
|
const res = await fetch(hubUrl, {
|
||||||
|
method: "POST",
|
||||||
|
headers: { "Content-Type": "application/x-www-form-urlencoded" },
|
||||||
|
body: `hub.mode=publish&hub.url=${encodeURIComponent(feedUrl)}`,
|
||||||
|
});
|
||||||
|
console.log(`[websub] Notified hub for ${feedUrl}: ${res.status}`);
|
||||||
|
} catch (err) {
|
||||||
|
console.error(`[websub] Hub notification failed for ${feedUrl}:`, err.message);
|
||||||
|
}
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
|||||||
@@ -7,6 +7,12 @@ eleventyExcludeFromCollections: true
|
|||||||
"title": "{{ site.name }}",
|
"title": "{{ site.name }}",
|
||||||
"home_page_url": "{{ site.url }}/",
|
"home_page_url": "{{ site.url }}/",
|
||||||
"feed_url": "{{ site.url }}/feed.json",
|
"feed_url": "{{ site.url }}/feed.json",
|
||||||
|
"hubs": [
|
||||||
|
{
|
||||||
|
"type": "WebSub",
|
||||||
|
"url": "https://websubhub.com/hub"
|
||||||
|
}
|
||||||
|
],
|
||||||
"description": "{{ site.description }}",
|
"description": "{{ site.description }}",
|
||||||
"language": "{{ site.locale | default('en') }}",
|
"language": "{{ site.locale | default('en') }}",
|
||||||
"authors": [
|
"authors": [
|
||||||
|
|||||||
1
feed.njk
1
feed.njk
@@ -10,6 +10,7 @@ eleventyExcludeFromCollections: true
|
|||||||
<description>{{ site.description }}</description>
|
<description>{{ site.description }}</description>
|
||||||
<language>{{ site.locale | default('en') }}</language>
|
<language>{{ site.locale | default('en') }}</language>
|
||||||
<atom:link href="{{ site.url }}/feed.xml" rel="self" type="application/rss+xml"/>
|
<atom:link href="{{ site.url }}/feed.xml" rel="self" type="application/rss+xml"/>
|
||||||
|
<atom:link href="https://websubhub.com/hub" rel="hub"/>
|
||||||
<lastBuildDate>{{ collections.feed | getNewestCollectionItemDate | dateToRfc822 }}</lastBuildDate>
|
<lastBuildDate>{{ collections.feed | getNewestCollectionItemDate | dateToRfc822 }}</lastBuildDate>
|
||||||
{%- for post in collections.feed %}
|
{%- for post in collections.feed %}
|
||||||
{%- set absolutePostUrl = site.url + post.url %}
|
{%- set absolutePostUrl = site.url + post.url %}
|
||||||
|
|||||||
Reference in New Issue
Block a user