diff --git a/src/components/pages/HomePage.astro b/src/components/pages/HomePage.astro
index 9da9e1b..6e74f04 100644
--- a/src/components/pages/HomePage.astro
+++ b/src/components/pages/HomePage.astro
@@ -17,7 +17,7 @@ interface EventRow {
linked?: LinkedEvent;
}
import { nlStats } from '../../data/nl-stats';
-import { HOMEPAGE_FEED_URI, HOMEPAGE_FEED_SUBSCRIBE } from '../../data/feed';
+import { feedForScope } from '../../data/feed';
import { getScope, resolveScopeId } from '../../config/scopes';
import { europeStats, statFor } from '../../data/europe-stats';
@@ -92,10 +92,10 @@ if (scopeId === 'nl') {
// site other than .nl must not present them as its own. .nl and the .eu aggregate show them; .be
// shows none until it has its own events.
const showEvents = scopeId === 'nl' || scope.aggregate;
-// The homepage feed is the atproto-nl custom feed (Dutch community + wider atproto conversation).
-// It's NL-specific, so only .nl shows it; other scopes would otherwise display Dutch posts under a
-// "Belgian/Norwegian/European community" heading. Give each scope its own feed to re-enable here.
-const showFeed = scopeId === 'nl';
+// Each national scope has its own custom feed (Dutch/Belgian/Norwegian Atmosphere); the .eu
+// aggregate has none. Show the feed section only where a feed exists, and point it at that feed.
+const homeFeed = feedForScope(scope.cc);
+const showFeed = !!homeFeed;
const calEvents = showEvents ? await getCalendarEvents() : [];
const upcomingRows: EventRow[] = showEvents
? [
@@ -187,8 +187,8 @@ const avatarMembers = members.filter((m) => m.avatar).slice(0, 24);
diff --git a/src/data/feed.ts b/src/data/feed.ts
index dcbe829..6c53f46 100644
--- a/src/data/feed.ts
+++ b/src/data/feed.ts
@@ -1,8 +1,26 @@
-// The homepage feed is a custom Bluesky feed generator (built with attie.ai): posts from
-// community members plus the wider atproto/Eurosky/EU-tech conversation relevant to people
-// building on the protocol in the Netherlands, with off-topic noise filtered out.
-export const HOMEPAGE_FEED_URI =
- 'at://did:plc:45uheisi25szrjvjurfpritx/app.bsky.feed.generator/atproto-nl';
+// Per-scope homepage feed. Each national scope has its own attie.ai custom feed generator in
+// gui.do's repo (Dutch/Belgian/Norwegian Atmosphere): community members plus the wider atproto
+// conversation relevant to that country, off-topic noise filtered out. The .eu aggregate has no
+// feed of its own, so its homepage omits the feed section.
+const FEED_DID = 'did:plc:45uheisi25szrjvjurfpritx'; // gui.do (the feed generators live in this repo)
+const uri = (rkey: string) => `at://${FEED_DID}/app.bsky.feed.generator/${rkey}`;
// Subscribe deeplink on mu.social (same path shape as bsky.app: /profile//feed/).
-export const HOMEPAGE_FEED_SUBSCRIBE = 'https://mu.social/profile/gui.do/feed/atproto-nl';
+const subscribe = (rkey: string) => `https://mu.social/profile/gui.do/feed/${rkey}`;
+
+export interface HomeFeed {
+ uri: string;
+ subscribe: string;
+}
+
+// Keyed by scope cc. Add a scope here once its feed is published.
+const FEEDS: Record = {
+ nl: { uri: uri('atproto-nl'), subscribe: subscribe('atproto-nl') },
+ be: { uri: uri('atproto-be'), subscribe: subscribe('atproto-be') },
+ no: { uri: uri('atproto-no'), subscribe: subscribe('atproto-no') },
+};
+
+/** The homepage feed for a scope, or null when it has none (e.g. the .eu aggregate). */
+export function feedForScope(cc: string): HomeFeed | null {
+ return FEEDS[cc] ?? null;
+}
diff --git a/src/lib/atproto/home.ts b/src/lib/atproto/home.ts
index 2ddd591..2be54ec 100644
--- a/src/lib/atproto/home.ts
+++ b/src/lib/atproto/home.ts
@@ -5,7 +5,7 @@ import { memberDids, beMemberDids, memberListUri, memberBlocklist, COMMUNITY_DID
import { getSelfAssertedMembers } from './member-index';
import { getScope } from '../../config/scopes';
import { matchNlCity } from '../../data/nl-cities';
-import { HOMEPAGE_FEED_URI } from '../../data/feed';
+import { feedForScope } from '../../data/feed';
import type { Profile, FeedPost } from './types';
export interface Member extends Profile {
@@ -59,9 +59,10 @@ async function loadCommunity(): Promise {
sifa: await getSifaInfo(m.did),
}));
- // The homepage feed is a curated custom feed generator (see data/feed.ts): members plus
- // relevant wider atproto/NL conversation, off-topic noise filtered out.
- const feed = await getFeed(HOMEPAGE_FEED_URI, 20);
+ // The homepage feed is this scope's curated custom feed generator (see data/feed.ts): members
+ // plus the wider atproto conversation for that country. The .eu aggregate has none, so no fetch.
+ const homeFeed = feedForScope(scope.cc);
+ const feed = homeFeed ? await getFeed(homeFeed.uri, 20) : [];
// Shuffle members once per build so the /members page order varies between deploys
// (no member is permanently first). Order does not affect stats, the map, or the feed.