diff --git a/src/components/EventDetailViewer.tsx b/src/components/EventDetailViewer.tsx
index 044b3c9..e3e38ea 100644
--- a/src/components/EventDetailViewer.tsx
+++ b/src/components/EventDetailViewer.tsx
@@ -151,6 +151,14 @@ function SpellTabContent({
// Resolve relays - use explicit relays from spell, or use relay hints from target event
const finalRelays = useMemo(() => {
+ // Don't select relays until filter is resolved (variables substituted)
+ if (!appliedFilter) {
+ console.log(
+ `[EventSpell:${spell.name || spellId}] Waiting for filter resolution before selecting relays`,
+ );
+ return [];
+ }
+
// Use explicit relays from spell if provided
if (parsed?.relays && parsed.relays.length > 0) {
console.log(
@@ -178,7 +186,7 @@ function SpellTabContent({
`[EventSpell:${spell.name || spellId}] Using fallback AGGREGATOR_RELAYS`,
);
return AGGREGATOR_RELAYS;
- }, [parsed?.relays, targetEvent, spell.name, spellId]);
+ }, [appliedFilter, parsed?.relays, targetEvent, spell.name, spellId]);
// Fetch events using the applied filter
// Always call the hook unconditionally (React Rules of Hooks)
@@ -410,9 +418,7 @@ export function EventDetailViewer({ pointer }: EventDetailViewerProps) {
{/* Rendered Content */}
-
0 ? "flex-1 min-h-0" : ""}`}
- >
+
diff --git a/src/components/ProfileViewer.tsx b/src/components/ProfileViewer.tsx
index 3b35b4e..257d65e 100644
--- a/src/components/ProfileViewer.tsx
+++ b/src/components/ProfileViewer.tsx
@@ -233,6 +233,14 @@ function SpellTabContent({
useOutboxRelays(appliedFilter || {}, outboxOptions);
const finalRelays = useMemo(() => {
+ // Don't select relays until filter is resolved (variables substituted)
+ if (!appliedFilter) {
+ console.log(
+ `[SpellTabContent:${spell.name || spellId}] Waiting for filter resolution before selecting relays`,
+ );
+ return [];
+ }
+
// Use explicit relays from spell if provided
if (parsed?.relays && parsed.relays.length > 0) {
console.log(
@@ -256,6 +264,7 @@ function SpellTabContent({
);
return selectedRelays;
}, [
+ appliedFilter,
parsed?.relays,
relaySelectionPhase,
selectedRelays,
@@ -692,9 +701,7 @@ export function ProfileViewer({ pubkey }: ProfileViewerProps) {
{/* Profile Content */}
-
0 ? "flex-1 min-h-0" : ""}`}
- >
+
{!profile && !profileEvent &&
}
{!profile && profileEvent && (
diff --git a/src/components/RelayViewer.tsx b/src/components/RelayViewer.tsx
index f91b8aa..df801af 100644
--- a/src/components/RelayViewer.tsx
+++ b/src/components/RelayViewer.tsx
@@ -135,6 +135,14 @@ function SpellTabContent({
// Resolve relays - for $relay spells, we query FROM the target relay itself
const finalRelays = useMemo(() => {
+ // Don't select relays until filter is resolved (variables substituted)
+ if (!appliedFilter) {
+ console.log(
+ `[RelaySpell:${spell.name || spellId}] Waiting for filter resolution before selecting relays`,
+ );
+ return [];
+ }
+
// Use explicit relays from spell if provided
if (parsed?.relays && parsed.relays.length > 0) {
console.log(
@@ -149,7 +157,7 @@ function SpellTabContent({
targetRelay,
]);
return [targetRelay];
- }, [parsed?.relays, targetRelay, spell.name, spellId]);
+ }, [appliedFilter, parsed?.relays, targetRelay, spell.name, spellId]);
// Fetch events using the applied filter
// Always call the hook unconditionally (React Rules of Hooks)