(null)
const [connectingProvider, setConnectingProvider] =
@@ -1493,6 +1498,7 @@ export function IntegrationsView() {
if (!res.ok) throw new Error("Failed to fetch plugins")
return (await res.json()) as { plugins: string[] }
},
+ enabled: !publicMode,
queryKey: ["plugins"],
})
@@ -1507,7 +1513,7 @@ export function IntegrationsView() {
return response.data as Connection[]
},
staleTime: 30 * 1000,
- enabled: hasProProduct,
+ enabled: !publicMode && hasProProduct,
})
const { data: apiKeys = [], refetch: refetchKeys } = useQuery
(
@@ -1524,7 +1530,7 @@ export function IntegrationsView() {
const data = (await res.json()) as { keys?: ListedApiKey[] }
return data.keys ?? []
},
- enabled: !!org?.id,
+ enabled: !publicMode && !!org?.id,
staleTime: 30 * 1000,
},
)
@@ -1678,7 +1684,15 @@ export function IntegrationsView() {
}
}
- const availablePluginIds = pluginsData?.plugins ?? Object.keys(PLUGIN_CATALOG)
+ const redirectToLogin = useCallback(() => {
+ const loginUrl = new URL("/login", window.location.origin)
+ loginUrl.searchParams.set("redirect", window.location.href)
+ window.location.assign(loginUrl.toString())
+ }, [])
+
+ const availablePluginIds = publicMode
+ ? Object.keys(PLUGIN_CATALOG)
+ : (pluginsData?.plugins ?? Object.keys(PLUGIN_CATALOG))
const enabledPluginIds = new Set(
availablePluginIds.filter((id) => PLUGIN_CATALOG[id]),
)
@@ -1714,6 +1728,7 @@ export function IntegrationsView() {
const isItemConnected = useCallback(
(item: Item): boolean => {
+ if (publicMode) return false
if (item.kind === "plugin") {
return activePluginById.has(item.pluginId)
}
@@ -1722,7 +1737,7 @@ export function IntegrationsView() {
}
return false
},
- [activePluginById, connectionsByProvider],
+ [activePluginById, connectionsByProvider, publicMode],
)
const counts = useMemo>(
@@ -1780,6 +1795,10 @@ export function IntegrationsView() {
),
ctaLabel: "Connect",
onCta: () => {
+ if (publicMode) {
+ redirectToLogin()
+ return
+ }
window.open(POKE_RECIPE_URL, "_blank", "noopener,noreferrer")
},
},
@@ -1802,6 +1821,10 @@ export function IntegrationsView() {
docsUrl: "https://supermemory.ai/docs/supermemory-mcp/introduction",
ctaLabel: "Connect",
onCta: () => {
+ if (publicMode) {
+ redirectToLogin()
+ return
+ }
void setMcpClient(null)
setViewMode("mcp")
},
@@ -1831,12 +1854,18 @@ export function IntegrationsView() {
/>
),
docsUrl: "https://supermemory.ai/docs/integrations/claude-code",
- ctaLabel: claudeCodeConnected
- ? "Active"
- : claudeCodeNeedsPro
- ? "Upgrade"
- : "Connect",
+ ctaLabel: publicMode
+ ? "Connect"
+ : claudeCodeConnected
+ ? "Active"
+ : claudeCodeNeedsPro
+ ? "Upgrade"
+ : "Connect",
onCta: () => {
+ if (publicMode) {
+ redirectToLogin()
+ return
+ }
if (claudeCodeConnected) return
if (claudeCodeNeedsPro) {
handleUpgrade()
@@ -1855,6 +1884,10 @@ export function IntegrationsView() {
backdrop: ,
ctaLabel: "Connect",
onCta: () => {
+ if (publicMode) {
+ redirectToLogin()
+ return
+ }
window.open(CHROME_EXTENSION_URL, "_blank", "noopener,noreferrer")
analytics.onboardingChromeExtensionClicked({ source: "integrations" })
},
@@ -1885,6 +1918,19 @@ export function IntegrationsView() {
})
const renderRight = (item: Item): ReactNode => {
+ if (publicMode) {
+ return (
+ {
+ trackCard(item)
+ redirectToLogin()
+ }}
+ >
+ Connect
+
+ )
+ }
+
switch (item.kind) {
case "plugin": {
const activeKey = activePluginById.get(item.pluginId)
@@ -2065,6 +2111,8 @@ export function IntegrationsView() {
}
const renderStatus = (item: Item): ReactNode => {
+ if (publicMode) return null
+
switch (item.kind) {
case "plugin": {
const activeKey = activePluginById.get(item.pluginId)
diff --git a/apps/web/middleware.ts b/apps/web/middleware.ts
index 4715c5710..2094e5aa3 100644
--- a/apps/web/middleware.ts
+++ b/apps/web/middleware.ts
@@ -31,6 +31,11 @@ export default async function proxy(request: Request) {
return NextResponse.next()
}
+ // Integrations index is public in guest mode; actions still require login.
+ if (url.pathname === "/" && url.searchParams.get("view") === "integrations") {
+ return NextResponse.next()
+ }
+
if (url.pathname.startsWith("/api/")) {
if (!sessionCookie) {
console.debug("[MIDDLEWARE] API route without session, returning 401")
From 7418abbe8dd0f1790c6a7c3a809a71fbef92f67a Mon Sep 17 00:00:00 2001
From: ishaanxgupta <124028055+ishaanxgupta@users.noreply.github.com>
Date: Tue, 9 Jun 2026 17:39:35 +0000
Subject: [PATCH 2/3] memory graph loader (#1072)
## Summary
- Replace the memory graph page's top-left package loading indicator with a centered Supermemory loader overlay.
- Reuse the same SuperLoader animation in the graph preview card loading state.
---
.../web/components/memory-graph/graph-card.tsx | 8 +++++++-
.../memory-graph/memory-graph-wrapper.tsx | 18 +++++++++++++++---
2 files changed, 22 insertions(+), 4 deletions(-)
diff --git a/apps/web/components/memory-graph/graph-card.tsx b/apps/web/components/memory-graph/graph-card.tsx
index 0269aab8d..de8bed3d2 100644
--- a/apps/web/components/memory-graph/graph-card.tsx
+++ b/apps/web/components/memory-graph/graph-card.tsx
@@ -4,6 +4,7 @@ import { memo, useMemo } from "react"
import { cn } from "@lib/utils"
import { dmSansClassName } from "@/lib/fonts"
import { Expand } from "lucide-react"
+import { SuperLoader } from "@/components/superloader"
import { useGraphApi } from "./hooks/use-graph-api"
import { useViewMode } from "@/lib/view-mode-context"
@@ -157,7 +158,12 @@ export const GraphCard = memo(
{isLoading ? (
) : documentCount > 0 || memoryCount > 0 ? (
loadMore() : undefined}
+ isLoading={false}
+ isLoadingMore={false}
+ onLoadMore={hasMore && !isLoadingMore ? () => loadMore() : undefined}
hasMore={hasMore}
error={externalError || apiError}
variant={variant}
@@ -70,6 +72,16 @@ export function MemoryGraph({
>
{children}
+ {isInitialLoading && (
+
+
+
+ )}
)
}
From b134716f0e69a8c0e2b0099c734b2d879c7dcdc9 Mon Sep 17 00:00:00 2001
From: MaheshtheDev <38828053+MaheshtheDev@users.noreply.github.com>
Date: Tue, 9 Jun 2026 18:16:36 +0000
Subject: [PATCH 3/3] chore(integrations): update Poke recipe URL to
supermemory.link/poke (#1074)
---
packages/lib/constants.ts | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/packages/lib/constants.ts b/packages/lib/constants.ts
index ab721b399..01439d1e6 100644
--- a/packages/lib/constants.ts
+++ b/packages/lib/constants.ts
@@ -7,7 +7,7 @@ const ADD_MEMORY_SHORTCUT_URL =
const RAYCAST_EXTENSION_URL = "https://www.raycast.com/supermemory/supermemory"
const CHROME_EXTENSION_URL =
"https://chromewebstore.google.com/detail/supermemory/afpgkkipfdpeaflnpoaffkcankadgjfc"
-const POKE_RECIPE_URL = "https://poke.com/r/5tHPbS8gZvA"
+const POKE_RECIPE_URL = "https://supermemory.link/poke"
export {
BIG_DIMENSIONS_NEW,