aboutsummaryrefslogtreecommitdiff
path: root/apps
diff options
context:
space:
mode:
Diffstat (limited to 'apps')
-rw-r--r--apps/docs/docs.json13
-rw-r--r--apps/docs/memory-api/sdks/overview.mdx4
-rw-r--r--apps/docs/memory-graph/api-reference.mdx405
-rw-r--r--apps/docs/memory-graph/examples.mdx566
-rw-r--r--apps/docs/memory-graph/installation.mdx141
-rw-r--r--apps/docs/memory-graph/npm.mdx5
-rw-r--r--apps/docs/memory-graph/overview.mdx87
-rw-r--r--apps/docs/memory-graph/quick-start.mdx307
-rw-r--r--apps/docs/memory-graph/troubleshooting.mdx336
9 files changed, 1864 insertions, 0 deletions
diff --git a/apps/docs/docs.json b/apps/docs/docs.json
index aef210a2..95cbd4f0 100644
--- a/apps/docs/docs.json
+++ b/apps/docs/docs.json
@@ -204,6 +204,19 @@
"ai-sdk/infinite-chat",
"ai-sdk/npm"
]
+ },
+ {
+ "group": "Memory Graph",
+ "icon": "network",
+ "pages": [
+ "memory-graph/overview",
+ "memory-graph/installation",
+ "memory-graph/quick-start",
+ "memory-graph/api-reference",
+ "memory-graph/examples",
+ "memory-graph/troubleshooting",
+ "memory-graph/npm"
+ ]
}
]
}
diff --git a/apps/docs/memory-api/sdks/overview.mdx b/apps/docs/memory-api/sdks/overview.mdx
index 84719016..ae85c6aa 100644
--- a/apps/docs/memory-api/sdks/overview.mdx
+++ b/apps/docs/memory-api/sdks/overview.mdx
@@ -18,6 +18,10 @@ title: "Overview"
Use supermemory with the python and javascript OpenAI SDKs
</Card>
+ <Card title="Memory Graph" icon="network" href="/memory-graph/overview">
+ Interactive canvas-based component to visualize your knowledge graph
+ </Card>
+
<Card title="Request more plugins" icon="life-buoy" href="mailto:[email protected]">
We will add support for your favorite SDKs asap.
</Card>
diff --git a/apps/docs/memory-graph/api-reference.mdx b/apps/docs/memory-graph/api-reference.mdx
new file mode 100644
index 00000000..f6dc00c2
--- /dev/null
+++ b/apps/docs/memory-graph/api-reference.mdx
@@ -0,0 +1,405 @@
+---
+title: "API Reference"
+description: "Complete reference for props, types, and configuration options"
+sidebarTitle: "API Reference"
+---
+
+## Component Props
+
+### Core Props
+
+<ParamField path="documents" type="DocumentWithMemories[]" required>
+ Array of documents with their associated memories to display in the graph. This is the primary data source for the visualization.
+
+ ```tsx
+ <MemoryGraph
+ documents={[
+ {
+ id: "doc-1",
+ title: "Meeting Notes",
+ memoryEntries: [
+ {
+ id: "mem-1",
+ documentId: "doc-1",
+ content: "Discussed project roadmap",
+ // ... other memory fields
+ }
+ ]
+ }
+ ]}
+ />
+ ```
+</ParamField>
+
+<ParamField path="isLoading" type="boolean" default="false">
+ Indicates whether the initial data is currently loading. Shows a loading indicator overlay.
+
+ ```tsx
+ <MemoryGraph
+ documents={documents}
+ isLoading={true}
+ />
+ ```
+</ParamField>
+
+<ParamField path="error" type="Error | null" default="null">
+ Error object to display if data fetching fails. Shows an error state with the error message.
+
+ ```tsx
+ <MemoryGraph
+ documents={documents}
+ error={new Error('Failed to load graph data')}
+ />
+ ```
+</ParamField>
+
+<ParamField path="children" type="ReactNode">
+ Content to display when no documents are available. Useful for custom empty states.
+
+ ```tsx
+ <MemoryGraph documents={[]}>
+ <div>
+ <h2>No memories yet</h2>
+ <button>Add Memory</button>
+ </div>
+ </MemoryGraph>
+ ```
+</ParamField>
+
+### Display Props
+
+<ParamField path="variant" type="'console' | 'consumer'" default="'console'">
+ Visual variant that determines the default zoom level and UI layout.
+
+ - **console**: Full dashboard view (zoom: 0.8, spaces selector shown, legend bottom-right)
+ - **consumer**: Embedded widget view (zoom: 0.5, spaces selector hidden, legend top-right)
+
+ ```tsx
+ {/* Full dashboard */}
+ <MemoryGraph documents={documents} variant="console" />
+
+ {/* Embedded widget */}
+ <MemoryGraph documents={documents} variant="consumer" />
+ ```
+</ParamField>
+
+<ParamField path="showSpacesSelector" type="boolean" default="Based on variant">
+ Controls visibility of the spaces/container filter dropdown. Defaults to `true` for console variant, `false` for consumer variant.
+
+ ```tsx
+ {/* Force show on consumer variant */}
+ <MemoryGraph
+ documents={documents}
+ variant="consumer"
+ showSpacesSelector={true}
+ />
+ ```
+</ParamField>
+
+<ParamField path="legendId" type="string">
+ Custom ID for the legend element. Useful for DOM targeting or testing.
+
+ ```tsx
+ <MemoryGraph
+ documents={documents}
+ legendId="my-custom-legend"
+ />
+ ```
+</ParamField>
+
+### Highlighting Props
+
+<ParamField path="highlightDocumentIds" type="string[]" default="[]">
+ Array of document IDs to highlight in the graph. Supports both internal IDs and custom IDs. Perfect for showing search results or filtered content.
+
+ ```tsx
+ <MemoryGraph
+ documents={documents}
+ highlightDocumentIds={['doc-123', 'custom-id-456']}
+ />
+ ```
+</ParamField>
+
+<ParamField path="highlightsVisible" type="boolean" default="true">
+ Controls whether highlights are currently visible. Useful for toggling highlights on/off.
+
+ ```tsx
+ const [showHighlights, setShowHighlights] = useState(true)
+
+ <MemoryGraph
+ documents={documents}
+ highlightDocumentIds={searchResults}
+ highlightsVisible={showHighlights}
+ />
+ ```
+</ParamField>
+
+### Pagination Props
+
+For large datasets, implement pagination to load documents incrementally:
+
+<ParamField path="isLoadingMore" type="boolean" default="false">
+ Indicates whether additional data is being loaded. Shows a loading indicator without blocking interactions.
+
+ ```tsx
+ <MemoryGraph
+ documents={documents}
+ isLoadingMore={true}
+ />
+ ```
+</ParamField>
+
+<ParamField path="hasMore" type="boolean" default="false">
+ Indicates whether more documents are available to load.
+
+ ```tsx
+ <MemoryGraph
+ documents={documents}
+ hasMore={page < totalPages}
+ />
+ ```
+</ParamField>
+
+<ParamField path="totalLoaded" type="number" default="documents.length">
+ Total number of documents currently loaded. Displayed in the loading indicator.
+
+ ```tsx
+ <MemoryGraph
+ documents={documents}
+ totalLoaded={documents.length}
+ />
+ ```
+</ParamField>
+
+<ParamField path="loadMoreDocuments" type="() => Promise<void>">
+ Async callback function to load more documents. Called automatically when user scrolls near the viewport edge.
+
+ ```tsx
+ const loadMore = async () => {
+ const nextPage = await fetchNextPage()
+ setDocuments(prev => [...prev, ...nextPage])
+ }
+
+ <MemoryGraph
+ documents={documents}
+ hasMore={true}
+ loadMoreDocuments={loadMore}
+ />
+ ```
+</ParamField>
+
+### Advanced Props
+
+<ParamField path="occludedRightPx" type="number" default="0">
+ Number of pixels occluded on the right side (e.g., by a chat panel). Used to adjust auto-fit calculations.
+
+ ```tsx
+ {/* Account for 400px chat panel on the right */}
+ <MemoryGraph
+ documents={documents}
+ occludedRightPx={400}
+ />
+ ```
+</ParamField>
+
+<ParamField path="autoLoadOnViewport" type="boolean" default="true">
+ Enable automatic loading when 80% of documents are visible in viewport. Set to `false` for manual pagination control.
+
+ ```tsx
+ <MemoryGraph
+ documents={documents}
+ hasMore={true}
+ loadMoreDocuments={loadMore}
+ autoLoadOnViewport={false}
+ />
+ ```
+</ParamField>
+
+<ParamField path="themeClassName" type="string">
+ Custom theme class name for styling overrides. Use with Vanilla Extract theme system.
+
+ ```tsx
+ import { customTheme } from './my-theme.css'
+
+ <MemoryGraph
+ documents={documents}
+ themeClassName={customTheme}
+ />
+ ```
+</ParamField>
+
+## TypeScript Types
+
+### Core Data Types
+
+```typescript
+interface DocumentWithMemories {
+ id: string
+ customId?: string | null
+ title?: string
+ content?: string
+ summary?: string
+ url?: string
+ summaryEmbedding?: number[] // For similarity calculations
+ memoryEntries: MemoryEntry[]
+ createdAt: string
+ updatedAt: string
+ userId?: string
+ spaceId?: string
+ spaceContainerTag?: string
+}
+
+interface MemoryEntry {
+ id: string
+ documentId: string
+ content: string | null
+ embedding?: number[]
+ spaceContainerTag?: string
+ spaceId?: string
+ updatesMemoryId?: string | null
+ relation?: 'updates' | 'extends' | 'derives' | null
+ isForgotten?: boolean
+ isLatest?: boolean
+ forgetAfter?: string | null
+ createdAt: string
+ updatedAt: string
+}
+```
+
+### Graph Types
+
+```typescript
+interface GraphNode {
+ id: string
+ type: 'document' | 'memory'
+ x: number
+ y: number
+ data: DocumentWithMemories | MemoryEntry
+ size: number
+ color: string
+ isHovered: boolean
+ isDragging: boolean
+}
+
+interface GraphEdge {
+ id: string
+ source: string
+ target: string
+ similarity: number // 0-1 for semantic similarity
+ visualProps: {
+ opacity: number
+ thickness: number
+ glow: number
+ pulseDuration: number
+ }
+ color: string
+ edgeType: 'doc-memory' | 'doc-doc' | 'version'
+ relationType?: 'updates' | 'extends' | 'derives'
+}
+```
+
+### Component Props Type
+
+```typescript
+interface MemoryGraphProps {
+ // Core
+ documents: DocumentWithMemories[]
+ isLoading?: boolean
+ error?: Error | null
+ children?: ReactNode
+
+ // Display
+ variant?: 'console' | 'consumer'
+ showSpacesSelector?: boolean
+ legendId?: string
+
+ // Highlighting
+ highlightDocumentIds?: string[]
+ highlightsVisible?: boolean
+
+ // Pagination
+ isLoadingMore?: boolean
+ hasMore?: boolean
+ totalLoaded?: number
+ loadMoreDocuments?: () => Promise<void>
+
+ // Advanced
+ occludedRightPx?: number
+ autoLoadOnViewport?: boolean
+ themeClassName?: string
+}
+```
+
+## Variants Comparison
+
+| Feature | Console | Consumer |
+|---------|---------|----------|
+| **Initial Zoom** | 0.8 (closer view) | 0.5 (wider view) |
+| **Spaces Selector** | Shown by default | Hidden by default |
+| **Legend Position** | Bottom-right | Top-right |
+| **Best For** | Full-page dashboards | Embedded widgets |
+| **Use Cases** | Admin panels, analytics | Sidebars, chat integration |
+
+### Console Variant
+
+```tsx
+<MemoryGraph
+ documents={documents}
+ variant="console"
+ // Spaces selector shown
+ // Legend in bottom-right
+ // Closer initial view
+/>
+```
+
+{/* TODO: Add console variant screenshot */}
+
+### Consumer Variant
+
+```tsx
+<MemoryGraph
+ documents={documents}
+ variant="consumer"
+ // Spaces selector hidden
+ // Legend in top-right
+ // Wider initial view
+/>
+```
+
+{/* TODO: Add consumer variant screenshot */}
+
+## Type Imports
+
+Import all types you need for TypeScript:
+
+```typescript
+import type {
+ // Data types
+ DocumentWithMemories,
+ MemoryEntry,
+ DocumentsResponse,
+
+ // Graph types
+ GraphNode,
+ GraphEdge,
+ MemoryRelation,
+
+ // Component types
+ MemoryGraphProps,
+
+ // Theme types (if customizing)
+ Sprinkles,
+} from '@supermemory/memory-graph'
+```
+
+## Next Steps
+
+<CardGroup cols={2}>
+ <Card title="Examples" icon="code" href="/memory-graph/examples">
+ See real-world implementation patterns
+ </Card>
+
+ <Card title="Troubleshooting" icon="wrench" href="/memory-graph/troubleshooting">
+ Solve common issues
+ </Card>
+</CardGroup>
diff --git a/apps/docs/memory-graph/examples.mdx b/apps/docs/memory-graph/examples.mdx
new file mode 100644
index 00000000..7fa9f578
--- /dev/null
+++ b/apps/docs/memory-graph/examples.mdx
@@ -0,0 +1,566 @@
+---
+title: "Examples"
+description: "Real-world implementation patterns and use cases"
+sidebarTitle: "Examples"
+---
+
+Explore production-ready examples for common use cases and integration patterns.
+
+## Basic Example
+
+Simple implementation with static data - perfect for testing and learning:
+
+```tsx BasicGraph.tsx
+'use client'
+
+import { MemoryGraph } from '@supermemory/memory-graph'
+import type { DocumentWithMemories } from '@supermemory/memory-graph'
+
+// Sample data for testing
+const sampleDocuments: DocumentWithMemories[] = [
+ {
+ id: "doc-1",
+ title: "Project Roadmap",
+ content: "Q1 goals and milestones",
+ summary: "Planning for Q1 2024",
+ memoryEntries: [
+ {
+ id: "mem-1",
+ documentId: "doc-1",
+ content: "Launch new feature by end of Q1",
+ createdAt: new Date().toISOString(),
+ updatedAt: new Date().toISOString(),
+ }
+ ],
+ createdAt: new Date().toISOString(),
+ updatedAt: new Date().toISOString(),
+ }
+]
+
+export default function BasicGraph() {
+ return (
+ <div style={{ width: '100%', height: '600px' }}>
+ <MemoryGraph documents={sampleDocuments} />
+ </div>
+ )
+}
+```
+
+{/* TODO: Add basic example screenshot */}
+
+## Next.js Integration
+
+### With App Router
+
+Complete example with backend proxy, authentication, and error handling:
+
+```typescript app/api/graph-data/route.ts
+import { NextResponse } from 'next/server'
+import { auth } from '@/lib/auth'
+
+export async function GET() {
+ // Authenticate user
+ const session = await auth()
+ if (!session?.user) {
+ return NextResponse.json(
+ { error: 'Unauthorized' },
+ { status: 401 }
+ )
+ }
+
+ try {
+ const response = await fetch(
+ 'https://api.supermemory.ai/v3/documents/documents',
+ {
+ method: 'POST',
+ headers: {
+ 'Content-Type': 'application/json',
+ 'Authorization': `Bearer ${process.env.SUPERMEMORY_API_KEY}`,
+ },
+ body: JSON.stringify({
+ page: 1,
+ limit: 500,
+ containerTags: [session.user.id], // User isolation
+ sort: 'createdAt',
+ order: 'desc',
+ }),
+ }
+ )
+
+ if (!response.ok) {
+ throw new Error(`Supermemory API error: ${response.statusText}`)
+ }
+
+ const data = await response.json()
+ return NextResponse.json(data)
+ } catch (error) {
+ console.error('Graph data fetch error:', error)
+ return NextResponse.json(
+ { error: 'Failed to fetch graph data' },
+ { status: 500 }
+ )
+ }
+}
+```
+
+```tsx app/graph/page.tsx
+'use client'
+
+import { MemoryGraph } from '@supermemory/memory-graph'
+import { useState, useEffect } from 'react'
+import type { DocumentWithMemories } from '@supermemory/memory-graph'
+
+export default function GraphPage() {
+ const [documents, setDocuments] = useState<DocumentWithMemories[]>([])
+ const [isLoading, setIsLoading] = useState(true)
+ const [error, setError] = useState<Error | null>(null)
+
+ useEffect(() => {
+ fetch('/api/graph-data')
+ .then(async (res) => {
+ if (!res.ok) throw new Error(await res.text())
+ return res.json()
+ })
+ .then((data) => {
+ setDocuments(data.documents)
+ setIsLoading(false)
+ })
+ .catch((err) => {
+ setError(err)
+ setIsLoading(false)
+ })
+ }, [])
+
+ return (
+ <main style={{ height: '100vh' }}>
+ <MemoryGraph
+ documents={documents}
+ isLoading={isLoading}
+ error={error}
+ variant="console"
+ />
+ </main>
+ )
+}
+```
+
+{/* TODO: Add Next.js example screenshot */}
+
+## With Pagination
+
+Implement infinite scroll for large datasets:
+
+```tsx GraphWithPagination.tsx
+'use client'
+
+import { MemoryGraph } from '@supermemory/memory-graph'
+import { useState, useCallback } from 'react'
+import type { DocumentWithMemories } from '@supermemory/memory-graph'
+
+export default function GraphWithPagination() {
+ const [documents, setDocuments] = useState<DocumentWithMemories[]>([])
+ const [page, setPage] = useState(1)
+ const [hasMore, setHasMore] = useState(true)
+ const [isLoading, setIsLoading] = useState(true)
+ const [isLoadingMore, setIsLoadingMore] = useState(false)
+ const [error, setError] = useState<Error | null>(null)
+
+ // Initial load
+ useState(() => {
+ fetchPage(1)
+ }, [])
+
+ const fetchPage = async (pageNum: number) => {
+ try {
+ if (pageNum === 1) {
+ setIsLoading(true)
+ } else {
+ setIsLoadingMore(true)
+ }
+
+ const response = await fetch(
+ `/api/graph-data?page=${pageNum}&limit=100`
+ )
+
+ if (!response.ok) {
+ throw new Error('Failed to fetch documents')
+ }
+
+ const data = await response.json()
+
+ setDocuments(prev =>
+ pageNum === 1 ? data.documents : [...prev, ...data.documents]
+ )
+
+ setHasMore(
+ data.pagination.currentPage < data.pagination.totalPages
+ )
+ setPage(pageNum)
+ } catch (err) {
+ setError(err instanceof Error ? err : new Error('Unknown error'))
+ } finally {
+ setIsLoading(false)
+ setIsLoadingMore(false)
+ }
+ }
+
+ const loadMore = useCallback(async () => {
+ if (!isLoadingMore && hasMore) {
+ await fetchPage(page + 1)
+ }
+ }, [page, isLoadingMore, hasMore])
+
+ return (
+ <div style={{ width: '100%', height: '100vh' }}>
+ <MemoryGraph
+ documents={documents}
+ isLoading={isLoading}
+ isLoadingMore={isLoadingMore}
+ hasMore={hasMore}
+ totalLoaded={documents.length}
+ loadMoreDocuments={loadMore}
+ />
+ </div>
+ )
+}
+```
+
+<Tip>
+The graph automatically loads more documents when 80% of current documents are visible in the viewport. Set `autoLoadOnViewport={false}` for manual control.
+</Tip>
+
+{/* TODO: Add pagination example screenshot */}
+
+## Search Integration with Highlighting
+
+Highlight search results in the graph:
+
+```tsx SearchableGraph.tsx
+'use client'
+
+import { MemoryGraph } from '@supermemory/memory-graph'
+import { useState, useEffect } from 'react'
+import type { DocumentWithMemories } from '@supermemory/memory-graph'
+
+export default function SearchableGraph() {
+ const [documents, setDocuments] = useState<DocumentWithMemories[]>([])
+ const [searchQuery, setSearchQuery] = useState('')
+ const [highlightedIds, setHighlightedIds] = useState<string[]>([])
+ const [showHighlights, setShowHighlights] = useState(true)
+
+ // Fetch all documents
+ useEffect(() => {
+ fetch('/api/graph-data')
+ .then(res => res.json())
+ .then(data => setDocuments(data.documents))
+ }, [])
+
+ // Search and highlight
+ const handleSearch = async () => {
+ if (!searchQuery.trim()) {
+ setHighlightedIds([])
+ return
+ }
+
+ try {
+ const response = await fetch('/api/search', {
+ method: 'POST',
+ headers: { 'Content-Type': 'application/json' },
+ body: JSON.stringify({ query: searchQuery })
+ })
+
+ const results = await response.json()
+
+ // Extract document IDs from search results
+ const docIds = results.documents.map((doc: any) => doc.id)
+ setHighlightedIds(docIds)
+ setShowHighlights(true)
+ } catch (error) {
+ console.error('Search error:', error)
+ }
+ }
+
+ return (
+ <div style={{ height: '100vh', display: 'flex', flexDirection: 'column' }}>
+ {/* Search bar */}
+ <div style={{
+ padding: '1rem',
+ display: 'flex',
+ gap: '0.5rem',
+ borderBottom: '1px solid #e5e7eb'
+ }}>
+ <input
+ type="text"
+ value={searchQuery}
+ onChange={(e) => setSearchQuery(e.target.value)}
+ onKeyDown={(e) => e.key === 'Enter' && handleSearch()}
+ placeholder="Search documents..."
+ style={{ flex: 1, padding: '0.5rem', borderRadius: '0.375rem' }}
+ />
+ <button onClick={handleSearch}>Search</button>
+ <button onClick={() => {
+ setHighlightedIds([])
+ setSearchQuery('')
+ }}>
+ Clear
+ </button>
+ <label>
+ <input
+ type="checkbox"
+ checked={showHighlights}
+ onChange={(e) => setShowHighlights(e.target.checked)}
+ />
+ Show highlights
+ </label>
+ </div>
+
+ {/* Graph */}
+ <div style={{ flex: 1 }}>
+ <MemoryGraph
+ documents={documents}
+ highlightDocumentIds={highlightedIds}
+ highlightsVisible={showHighlights}
+ variant="console"
+ />
+ </div>
+ </div>
+ )
+}
+```
+
+<Note>
+Highlighting supports both internal document IDs and custom IDs. The graph will automatically match either.
+</Note>
+
+{/* TODO: Add search highlighting screenshot */}
+
+## Custom Empty State
+
+Provide a custom UI when no documents exist:
+
+```tsx GraphWithEmpty.tsx
+'use client'
+
+import { MemoryGraph } from '@supermemory/memory-graph'
+import { useState, useEffect } from 'react'
+
+export default function GraphWithEmpty() {
+ const [documents, setDocuments] = useState([])
+
+ return (
+ <div style={{ width: '100%', height: '100vh' }}>
+ <MemoryGraph documents={documents}>
+ <div style={{
+ display: 'flex',
+ flexDirection: 'column',
+ alignItems: 'center',
+ justifyContent: 'center',
+ gap: '2rem',
+ padding: '2rem',
+ textAlign: 'center'
+ }}>
+ <div>
+ <svg
+ width="120"
+ height="120"
+ viewBox="0 0 24 24"
+ fill="none"
+ stroke="currentColor"
+ >
+ <circle cx="12" cy="12" r="10" />
+ <line x1="12" y1="8" x2="12" y2="12" />
+ <line x1="12" y1="16" x2="12.01" y2="16" />
+ </svg>
+ </div>
+
+ <div>
+ <h2 style={{ fontSize: '1.5rem', fontWeight: 600, marginBottom: '0.5rem' }}>
+ No memories yet
+ </h2>
+ <p style={{ color: '#6b7280', maxWidth: '400px' }}>
+ Start adding content to see your knowledge graph come to life.
+ Documents and their connections will appear here.
+ </p>
+ </div>
+
+ <div style={{ display: 'flex', gap: '1rem' }}>
+ <button
+ onClick={() => window.location.href = '/add-memory'}
+ style={{
+ padding: '0.75rem 1.5rem',
+ backgroundColor: '#3b82f6',
+ color: 'white',
+ borderRadius: '0.5rem',
+ border: 'none',
+ cursor: 'pointer'
+ }}
+ >
+ Add Your First Memory
+ </button>
+
+ <button
+ onClick={() => window.location.href = '/docs'}
+ style={{
+ padding: '0.75rem 1.5rem',
+ backgroundColor: 'transparent',
+ border: '1px solid #d1d5db',
+ borderRadius: '0.5rem',
+ cursor: 'pointer'
+ }}
+ >
+ Learn More
+ </button>
+ </div>
+ </div>
+ </MemoryGraph>
+ </div>
+ )
+}
+```
+
+## Backend Patterns
+
+### Express.js
+
+```typescript server.ts
+import express from 'express'
+
+const app = express()
+
+app.get('/api/graph-data', async (req, res) => {
+ // Authenticate user
+ const user = await authenticateRequest(req)
+ if (!user) {
+ return res.status(401).json({ error: 'Unauthorized' })
+ }
+
+ try {
+ const response = await fetch(
+ 'https://api.supermemory.ai/v3/documents/documents',
+ {
+ method: 'POST',
+ headers: {
+ 'Content-Type': 'application/json',
+ 'Authorization': `Bearer ${process.env.SUPERMEMORY_API_KEY}`,
+ },
+ body: JSON.stringify({
+ page: 1,
+ limit: 500,
+ containerTags: [user.id],
+ }),
+ }
+ )
+
+ const data = await response.json()
+ res.json(data)
+ } catch (error) {
+ console.error('Error:', error)
+ res.status(500).json({ error: 'Failed to fetch data' })
+ }
+})
+
+app.listen(3000)
+```
+
+### Cloudflare Workers
+
+```typescript worker.ts
+export default {
+ async fetch(request: Request, env: Env) {
+ // Authenticate
+ const user = await authenticateRequest(request, env)
+ if (!user) {
+ return new Response('Unauthorized', { status: 401 })
+ }
+
+ try {
+ const response = await fetch(
+ 'https://api.supermemory.ai/v3/documents/documents',
+ {
+ method: 'POST',
+ headers: {
+ 'Content-Type': 'application/json',
+ 'Authorization': `Bearer ${env.SUPERMEMORY_API_KEY}`,
+ },
+ body: JSON.stringify({
+ page: 1,
+ limit: 500,
+ containerTags: [user.id],
+ }),
+ }
+ )
+
+ return new Response(await response.text(), {
+ headers: { 'Content-Type': 'application/json' }
+ })
+ } catch (error) {
+ return new Response('Internal Server Error', { status: 500 })
+ }
+ }
+}
+```
+
+### User Isolation with Container Tags
+
+For multi-user applications, always filter documents by user:
+
+```typescript
+// Backend: Filter by user ID
+body: JSON.stringify({
+ containerTags: [user.id], // Only fetch this user's documents
+ page: 1,
+ limit: 500,
+})
+```
+
+<Warning>
+Always implement user isolation on the backend. Never trust client-side filtering for security.
+</Warning>
+
+## React Query Integration
+
+For better data management and caching:
+
+```tsx GraphWithReactQuery.tsx
+'use client'
+
+import { MemoryGraph } from '@supermemory/memory-graph'
+import { useQuery } from '@tanstack/react-query'
+
+export default function GraphWithReactQuery() {
+ const { data, isLoading, error } = useQuery({
+ queryKey: ['graph-data'],
+ queryFn: async () => {
+ const response = await fetch('/api/graph-data')
+ if (!response.ok) {
+ throw new Error('Failed to fetch graph data')
+ }
+ return response.json()
+ },
+ staleTime: 5 * 60 * 1000, // 5 minutes
+ refetchOnWindowFocus: false,
+ })
+
+ return (
+ <div style={{ height: '100vh' }}>
+ <MemoryGraph
+ documents={data?.documents || []}
+ isLoading={isLoading}
+ error={error}
+ />
+ </div>
+ )
+}
+```
+
+## Next Steps
+
+<CardGroup cols={2}>
+ <Card title="API Reference" icon="book" href="/memory-graph/api-reference">
+ Explore all props and types
+ </Card>
+
+ <Card title="Troubleshooting" icon="wrench" href="/memory-graph/troubleshooting">
+ Solve common issues
+ </Card>
+</CardGroup>
diff --git a/apps/docs/memory-graph/installation.mdx b/apps/docs/memory-graph/installation.mdx
new file mode 100644
index 00000000..ffaef93e
--- /dev/null
+++ b/apps/docs/memory-graph/installation.mdx
@@ -0,0 +1,141 @@
+---
+title: "Installation"
+description: "Install and set up the graph visualization component"
+sidebarTitle: "Installation"
+---
+
+## Installation
+
+Install the package using your preferred package manager:
+
+<CodeGroup>
+
+```bash npm
+npm install @supermemory/memory-graph
+```
+
+```bash yarn
+yarn add @supermemory/memory-graph
+```
+
+```bash pnpm
+pnpm add @supermemory/memory-graph
+```
+
+```bash bun
+bun add @supermemory/memory-graph
+```
+
+</CodeGroup>
+
+## Requirements
+
+### Peer Dependencies
+
+The package requires React 18 or higher:
+
+```json
+{
+ "react": "^18.0.0",
+ "react-dom": "^18.0.0"
+}
+```
+
+If you don't have React installed, add it first:
+
+```bash
+npm install react react-dom
+```
+
+### Browser Requirements
+
+The component works in all modern browsers that support:
+- **HTML5 Canvas 2D API**: For rendering the graph
+- **ES2020+**: Modern JavaScript features
+- **Touch Events**: For mobile gesture support (optional)
+
+Supported browsers:
+- Chrome/Edge 90+
+- Firefox 88+
+- Safari 14+
+- Mobile browsers (iOS Safari, Chrome Mobile)
+
+## Setup
+
+### Automatic CSS Injection (Recommended)
+
+The component automatically injects its styles at runtime - no additional setup needed!
+
+```tsx
+import { MemoryGraph } from '@supermemory/memory-graph'
+
+// Styles are automatically injected when the component mounts
+function App() {
+ return <MemoryGraph documents={documents} />
+}
+```
+
+<Note>
+The CSS is embedded in the JavaScript bundle and injected only once, even if you use multiple graph components.
+</Note>
+
+### Manual CSS Import (Alternative)
+
+If you prefer to import CSS manually through your bundler:
+
+```tsx
+import { MemoryGraph } from '@supermemory/memory-graph'
+import '@supermemory/memory-graph/styles.css'
+```
+
+<Warning>
+If you import CSS manually, the automatic injection will be skipped. Only use this if you have specific bundler requirements.
+</Warning>
+
+## Verification
+
+Verify the installation by importing the component and types:
+
+```tsx
+import { MemoryGraph } from '@supermemory/memory-graph'
+import type {
+ DocumentWithMemories,
+ MemoryEntry,
+ MemoryGraphProps
+} from '@supermemory/memory-graph'
+
+// TypeScript will provide full type checking
+const props: MemoryGraphProps = {
+ documents: [],
+ isLoading: false,
+ error: null
+}
+```
+
+<Tip>
+The package exports all types you need for TypeScript. Check the [API Reference](/memory-graph/api-reference) for a complete list.
+</Tip>
+
+## Universal Bundler Support
+
+The package works with all modern bundlers:
+
+- **Vite**: ✅ Works out of the box
+- **webpack**: ✅ Works out of the box
+- **Next.js**: ✅ Supports both App Router and Pages Router
+- **Turbopack**: ✅ Fully compatible
+- **Parcel**: ✅ Works out of the box
+
+No special configuration required for any bundler.
+
+## Next Steps
+
+<CardGroup cols={2}>
+ <Card title="Quick Start" icon="rocket" href="/memory-graph/quick-start">
+ Build your first graph in 5 minutes
+ </Card>
+
+ <Card title="API Reference" icon="book" href="/memory-graph/api-reference">
+ Explore all available props and types
+ </Card>
+</CardGroup>
diff --git a/apps/docs/memory-graph/npm.mdx b/apps/docs/memory-graph/npm.mdx
new file mode 100644
index 00000000..73185178
--- /dev/null
+++ b/apps/docs/memory-graph/npm.mdx
@@ -0,0 +1,5 @@
+---
+title: "NPM link"
+url: "https://www.npmjs.com/package/@supermemory/memory-graph"
+icon: npm
+---
diff --git a/apps/docs/memory-graph/overview.mdx b/apps/docs/memory-graph/overview.mdx
new file mode 100644
index 00000000..430e88f8
--- /dev/null
+++ b/apps/docs/memory-graph/overview.mdx
@@ -0,0 +1,87 @@
+---
+title: "Graph Visualization"
+description: "Interactive canvas-based component for visualizing your memory connections"
+sidebarTitle: "Overview"
+---
+
+[![npm version](https://img.shields.io/npm/v/@supermemory/memory-graph.svg)](https://www.npmjs.com/package/@supermemory/memory-graph)
+
+The `@supermemory/memory-graph` package provides an interactive, high-performance visualization component that transforms your documents and memories into an explorable knowledge graph. Built with React and powered by HTML5 Canvas, it offers smooth interactions and sophisticated rendering optimizations.
+
+{/* TODO: Add graph interaction GIF showing pan, zoom, and node interactions */}
+
+## Key Features
+
+<CardGroup cols={2}>
+ <Card title="High-Performance Rendering" icon="zap">
+ Canvas-based rendering with LOD optimization, viewport culling, and change-based rendering for smooth performance with hundreds of nodes
+ </Card>
+
+ <Card title="Interactive Exploration" icon="move">
+ Pan, zoom, drag nodes, double-click to focus, and navigate with intuitive controls on both desktop and mobile
+ </Card>
+
+ <Card title="Semantic Connections" icon="network">
+ Visualizes relationships between documents based on content similarity and memory version chains
+ </Card>
+
+ <Card title="Zero Configuration" icon="sparkles">
+ Works out of the box with automatic CSS injection - no build configuration or style imports needed
+ </Card>
+
+ <Card title="TypeScript Support" icon="code">
+ Full TypeScript support with comprehensive type definitions for all props and data structures
+ </Card>
+
+ <Card title="Responsive Design" icon="smartphone">
+ Optimized for both desktop and mobile with touch gesture support (pinch-to-zoom, pan)
+ </Card>
+</CardGroup>
+
+## When to Use
+
+The graph visualization component is ideal for:
+
+- **Knowledge Management Dashboards**: Visualize how documents and memories connect
+- **Document Explorers**: Let users navigate through related content visually
+- **Memory Analytics**: Show patterns in how information is structured and related
+- **Search Result Visualization**: Display search results in context of the broader knowledge graph
+
+## Variants
+
+The component offers two visual variants optimized for different use cases:
+
+| Variant | Initial Zoom | Spaces Selector | Legend Position | Best For |
+|---------|-------------|-----------------|-----------------|----------|
+| **Console** | 0.8 (closer) | Shown | Bottom-right | Full-page dashboards, admin panels |
+| **Consumer** | 0.5 (wider) | Hidden | Top-right | Embedded widgets, sidebars |
+
+## Graph Elements
+
+The visualization displays three types of nodes and three types of connections:
+
+**Nodes**:
+- **Documents**: Rendered as rounded rectangles with glassmorphism styling
+- **Memory Entries**: Rendered as hexagons (or circles when zoomed out)
+- **Status Indicators**: Visual markers for forgotten, expiring, and new memories
+
+**Connections**:
+- **Doc-Memory**: Solid thin lines connecting documents to their memory chunks
+- **Doc-Doc**: Dashed lines showing semantic similarity (threshold: 0.725)
+- **Version Chains**: Double-line arrows showing memory evolution (updates/extends/derives)
+
+## Next Steps
+
+<CardGroup cols={3}>
+ <Card title="Installation" icon="download" href="/memory-graph/installation">
+ Install the package and get set up
+ </Card>
+
+ <Card title="Quick Start" icon="rocket" href="/memory-graph/quick-start">
+ Build your first graph in 5 minutes
+ </Card>
+
+ <Card title="Examples" icon="code" href="/memory-graph/examples">
+ Explore real-world implementation patterns
+ </Card>
+</CardGroup>
diff --git a/apps/docs/memory-graph/quick-start.mdx b/apps/docs/memory-graph/quick-start.mdx
new file mode 100644
index 00000000..295f82bf
--- /dev/null
+++ b/apps/docs/memory-graph/quick-start.mdx
@@ -0,0 +1,307 @@
+---
+title: "Quick Start"
+description: "Build your first knowledge graph in 5 minutes"
+sidebarTitle: "Quick Start"
+---
+
+Get your first interactive memory graph up and running in just a few minutes.
+
+<Warning>
+**Security First**: Never expose your Supermemory API key in client-side code. Always use a backend proxy to authenticate requests.
+</Warning>
+
+## Step 1: Create Backend Proxy
+
+Create an API route in your backend that authenticates users and proxies requests to the Supermemory API.
+
+<CodeGroup>
+
+```typescript Next.js App Router
+// app/api/supermemory-graph/route.ts
+import { NextResponse } from 'next/server'
+
+export async function GET(request: Request) {
+ // Add your authentication logic here
+ const user = await getAuthenticatedUser(request)
+ if (!user) {
+ return NextResponse.json(
+ { error: 'Unauthorized' },
+ { status: 401 }
+ )
+ }
+
+ try {
+ const response = await fetch(
+ 'https://api.supermemory.ai/v3/documents/documents',
+ {
+ method: 'POST',
+ headers: {
+ 'Content-Type': 'application/json',
+ 'Authorization': `Bearer ${process.env.SUPERMEMORY_API_KEY}`,
+ },
+ body: JSON.stringify({
+ page: 1,
+ limit: 500,
+ sort: 'createdAt',
+ order: 'desc',
+ // Optional: Filter by user-specific container
+ containerTags: [user.id],
+ }),
+ }
+ )
+
+ if (!response.ok) {
+ throw new Error('Failed to fetch documents')
+ }
+
+ const data = await response.json()
+ return NextResponse.json(data)
+ } catch (error) {
+ console.error('Error fetching graph data:', error)
+ return NextResponse.json(
+ { error: 'Failed to fetch data' },
+ { status: 500 }
+ )
+ }
+}
+```
+
+```typescript Next.js Pages Router
+// pages/api/supermemory-graph.ts
+import type { NextApiRequest, NextApiResponse } from 'next'
+
+export default async function handler(
+ req: NextApiRequest,
+ res: NextApiResponse
+) {
+ // Add your authentication logic here
+ const user = await getAuthenticatedUser(req)
+ if (!user) {
+ return res.status(401).json({ error: 'Unauthorized' })
+ }
+
+ try {
+ const response = await fetch(
+ 'https://api.supermemory.ai/v3/documents/documents',
+ {
+ method: 'POST',
+ headers: {
+ 'Content-Type': 'application/json',
+ 'Authorization': `Bearer ${process.env.SUPERMEMORY_API_KEY}`,
+ },
+ body: JSON.stringify({
+ page: 1,
+ limit: 500,
+ sort: 'createdAt',
+ order: 'desc',
+ containerTags: [user.id],
+ }),
+ }
+ )
+
+ const data = await response.json()
+ res.status(200).json(data)
+ } catch (error) {
+ console.error('Error fetching graph data:', error)
+ res.status(500).json({ error: 'Failed to fetch data' })
+ }
+}
+```
+
+</CodeGroup>
+
+<Tip>
+Use `containerTags` to filter documents by user in multi-user applications. This ensures users only see their own data.
+</Tip>
+
+## Step 2: Create Frontend Component
+
+Create a component that fetches data and renders the graph.
+
+```tsx GraphComponent.tsx
+'use client' // Required for Next.js App Router
+
+import { MemoryGraph } from '@supermemory/memory-graph'
+import { useState, useEffect } from 'react'
+import type { DocumentWithMemories } from '@supermemory/memory-graph'
+
+export default function GraphComponent() {
+ const [documents, setDocuments] = useState<DocumentWithMemories[]>([])
+ const [isLoading, setIsLoading] = useState(true)
+ const [error, setError] = useState<Error | null>(null)
+
+ useEffect(() => {
+ fetch('/api/supermemory-graph')
+ .then(async (res) => {
+ if (!res.ok) {
+ throw new Error('Failed to fetch documents')
+ }
+ return res.json()
+ })
+ .then((data) => {
+ setDocuments(data.documents)
+ setIsLoading(false)
+ })
+ .catch((err) => {
+ setError(err)
+ setIsLoading(false)
+ })
+ }, [])
+
+ return (
+ {/* CRITICAL: Container must have explicit width and height */}
+ <div style={{ width: '100%', height: '100vh' }}>
+ <MemoryGraph
+ documents={documents}
+ isLoading={isLoading}
+ error={error}
+ >
+ {/* Custom empty state when no documents exist */}
+ <div style={{
+ display: 'flex',
+ flexDirection: 'column',
+ alignItems: 'center',
+ justifyContent: 'center',
+ height: '100%',
+ gap: '1rem'
+ }}>
+ <h2>No memories yet</h2>
+ <p>Start adding content to see your knowledge graph</p>
+ </div>
+ </MemoryGraph>
+ </div>
+ )
+}
+```
+
+<Warning>
+**Container Sizing**: The graph component requires its parent container to have explicit width and height. Without this, the canvas will have 0 dimensions and won't render.
+</Warning>
+
+## Step 3: Add to Your Page
+
+Use the component in your page:
+
+<CodeGroup>
+
+```tsx Next.js App Router
+// app/graph/page.tsx
+import GraphComponent from '@/components/GraphComponent'
+
+export default function GraphPage() {
+ return (
+ <main style={{ height: '100vh' }}>
+ <GraphComponent />
+ </main>
+ )
+}
+```
+
+```tsx Next.js Pages Router
+// pages/graph.tsx
+import GraphComponent from '@/components/GraphComponent'
+
+export default function GraphPage() {
+ return (
+ <div style={{ height: '100vh' }}>
+ <GraphComponent />
+ </div>
+ )
+}
+```
+
+```tsx React SPA
+// src/App.tsx
+import GraphComponent from './components/GraphComponent'
+
+function App() {
+ return (
+ <div className="App" style={{ height: '100vh' }}>
+ <GraphComponent />
+ </div>
+ )
+}
+
+export default App
+```
+
+</CodeGroup>
+
+## Complete Example
+
+Here's a complete, production-ready example with proper error handling and loading states:
+
+```tsx
+'use client'
+
+import { MemoryGraph } from '@supermemory/memory-graph'
+import { useState, useEffect } from 'react'
+import type { DocumentWithMemories } from '@supermemory/memory-graph'
+
+export default function GraphDashboard() {
+ const [documents, setDocuments] = useState<DocumentWithMemories[]>([])
+ const [isLoading, setIsLoading] = useState(true)
+ const [error, setError] = useState<Error | null>(null)
+
+ useEffect(() => {
+ const fetchData = async () => {
+ try {
+ const response = await fetch('/api/supermemory-graph')
+
+ if (!response.ok) {
+ throw new Error(`HTTP ${response.status}: ${response.statusText}`)
+ }
+
+ const data = await response.json()
+ setDocuments(data.documents || [])
+ } catch (err) {
+ console.error('Failed to fetch graph data:', err)
+ setError(err instanceof Error ? err : new Error('Unknown error'))
+ } finally {
+ setIsLoading(false)
+ }
+ }
+
+ fetchData()
+ }, [])
+
+ return (
+ <div className="dashboard" style={{
+ width: '100%',
+ height: '100vh',
+ position: 'relative'
+ }}>
+ <MemoryGraph
+ documents={documents}
+ isLoading={isLoading}
+ error={error}
+ variant="console"
+ >
+ <div className="empty-state">
+ <h2>No memories yet</h2>
+ <p>Start adding content to visualize your knowledge graph</p>
+ <button onClick={() => window.location.href = '/add-memory'}>
+ Add Your First Memory
+ </button>
+ </div>
+ </MemoryGraph>
+ </div>
+ )
+}
+```
+
+## Next Steps
+
+<CardGroup cols={3}>
+ <Card title="API Reference" icon="book" href="/memory-graph/api-reference">
+ Explore all props and customization options
+ </Card>
+
+ <Card title="Examples" icon="code" href="/memory-graph/examples">
+ See advanced patterns like pagination and highlighting
+ </Card>
+
+ <Card title="Troubleshooting" icon="wrench" href="/memory-graph/troubleshooting">
+ Solve common issues
+ </Card>
+</CardGroup>
diff --git a/apps/docs/memory-graph/troubleshooting.mdx b/apps/docs/memory-graph/troubleshooting.mdx
new file mode 100644
index 00000000..34533ad2
--- /dev/null
+++ b/apps/docs/memory-graph/troubleshooting.mdx
@@ -0,0 +1,336 @@
+---
+title: "Troubleshooting"
+description: "Common issues and their solutions"
+sidebarTitle: "Troubleshooting"
+---
+
+## Graph Not Rendering
+
+### Container Has No Dimensions
+
+**Problem**: The graph appears blank or shows nothing.
+
+**Cause**: The parent container has no explicit width or height (0x0 dimensions).
+
+**Solution**: Always set explicit dimensions on the container:
+
+```tsx
+{/* ✅ Correct */}
+<div style={{ width: '100%', height: '100vh' }}>
+ <MemoryGraph documents={documents} />
+</div>
+
+{/* ❌ Wrong - no height set */}
+<div style={{ width: '100%' }}>
+ <MemoryGraph documents={documents} />
+</div>
+
+{/* ❌ Wrong - using auto height */}
+<div style={{ width: '100%', height: 'auto' }}>
+ <MemoryGraph documents={documents} />
+</div>
+```
+
+<Tip>
+Use browser DevTools to inspect the container element and verify it has non-zero width and height.
+</Tip>
+
+### CSS Not Loading
+
+**Problem**: Graph renders but has no styling or looks broken.
+
+**Cause**: CSS injection failed or was blocked.
+
+**Solution**:
+
+1. Check browser console for errors
+2. Try manual CSS import:
+
+```tsx
+import '@supermemory/memory-graph/styles.css'
+import { MemoryGraph } from '@supermemory/memory-graph'
+```
+
+3. Verify your bundler supports CSS imports
+
+### No Data Displayed
+
+**Problem**: Loading completes but no nodes appear.
+
+**Diagnosis**:
+
+```tsx
+// Add console logs to debug
+console.log('Documents:', documents)
+console.log('Document count:', documents.length)
+console.log('Has memories:', documents.some(d => d.memoryEntries.length > 0))
+```
+
+**Common Causes**:
+- Empty `documents` array
+- Documents have no `memoryEntries`
+- Data structure doesn't match expected type
+
+**Solution**: Verify your data matches the expected structure:
+
+```typescript
+interface DocumentWithMemories {
+ id: string
+ title?: string
+ memoryEntries: MemoryEntry[] // Must be present
+ // ... other fields
+}
+```
+
+## Performance Issues
+
+### Slow Rendering with Large Datasets
+
+**Problem**: Graph becomes sluggish with 500+ documents.
+
+**Solution**: Implement pagination:
+
+```tsx
+<MemoryGraph
+ documents={documents}
+ hasMore={true}
+ loadMoreDocuments={loadMore}
+ isLoadingMore={isLoadingMore}
+/>
+```
+
+<Note>
+The graph uses viewport culling and Level-of-Detail (LOD) rendering automatically. Performance degradation typically starts around 1000+ nodes.
+</Note>
+
+### High Memory Usage
+
+**Problem**: Browser uses excessive memory.
+
+**Cause**: Too many documents loaded at once.
+
+**Solution**:
+1. Limit initial load to 200-500 documents
+2. Use pagination to load incrementally
+3. Consider filtering by space/container
+
+```typescript
+// Backend: Limit documents
+body: JSON.stringify({
+ page: 1,
+ limit: 200, // Start with smaller limit
+ containerTags: [selectedSpace],
+})
+```
+
+### Laggy Interactions
+
+**Problem**: Pan/zoom feels sluggish.
+
+**Diagnosis**:
+1. Check document count: `documents.length`
+2. Check browser FPS in DevTools Performance tab
+3. Check canvas size (very large canvases are slower)
+
+**Solutions**:
+- Reduce number of visible documents
+- Ensure container isn't larger than viewport
+- Close other resource-intensive tabs
+
+## Data Fetching Errors
+
+### CORS Errors
+
+**Problem**: `Access-Control-Allow-Origin` error in console.
+
+**Cause**: Trying to fetch directly from client to Supermemory API.
+
+**Solution**: Always use a backend proxy:
+
+```tsx
+{/* ❌ Wrong - CORS error */}
+fetch('https://api.supermemory.ai/v3/documents/documents', {
+ headers: { 'Authorization': `Bearer ${apiKey}` } // API key exposed!
+})
+
+{/* ✅ Correct - through your backend */}
+fetch('/api/graph-data') // Your backend proxies the request
+```
+
+<Warning>
+Never call the Supermemory API directly from client code. This exposes your API key and causes CORS errors.
+</Warning>
+
+### 401 Unauthorized
+
+**Problem**: Backend returns 401 error.
+
+**Common Causes**:
+1. API key is missing or invalid
+2. API key not in environment variables
+3. Environment variables not loaded
+
+**Solution**:
+
+```bash
+# .env.local
+SUPERMEMORY_API_KEY=your_api_key_here
+```
+
+```typescript
+// Verify in backend
+console.log('API Key present:', !!process.env.SUPERMEMORY_API_KEY)
+```
+
+### 500 Internal Server Error
+
+**Problem**: Backend returns 500 error.
+
+**Diagnosis**: Check backend logs for details.
+
+**Common Causes**:
+1. Network error reaching Supermemory API
+2. Invalid request body
+3. API key lacks permissions
+
+**Solution**: Add detailed error logging:
+
+```typescript
+try {
+ const response = await fetch('https://api.supermemory.ai/...')
+
+ if (!response.ok) {
+ const error = await response.text()
+ console.error('Supermemory API error:', response.status, error)
+ throw new Error(`API error: ${response.status}`)
+ }
+
+ return await response.json()
+} catch (error) {
+ console.error('Fetch error:', error)
+ throw error
+}
+```
+
+### API Key Exposure Warning
+
+**Problem**: API key visible in Network tab or client code.
+
+**Risk**: Anyone can steal your API key and make unauthorized requests.
+
+**Solution**:
+1. Remove API key from client code immediately
+2. Rotate your API key in Supermemory dashboard
+3. Implement backend proxy (see Quick Start guide)
+
+```tsx
+{/* ❌ NEVER do this */}
+const apiKey = 'sk_123...' // Exposed in source code!
+fetch(url, { headers: { 'Authorization': `Bearer ${apiKey}` }})
+
+{/* ✅ Always use backend proxy */}
+fetch('/api/graph-data') // API key stays on server
+```
+
+## TypeScript Errors
+
+### Type Mismatch
+
+**Problem**: TypeScript errors on `documents` prop.
+
+**Solution**: Import and use the correct type:
+
+```tsx
+import type { DocumentWithMemories } from '@supermemory/memory-graph'
+
+const [documents, setDocuments] = useState<DocumentWithMemories[]>([])
+```
+
+### Missing Type Definitions
+
+**Problem**: TypeScript can't find types.
+
+**Solution**:
+1. Verify package is installed: `npm list @supermemory/memory-graph`
+2. Restart TypeScript server in your IDE
+3. Check `node_modules/@supermemory/memory-graph/dist/index.d.ts` exists
+
+## Browser Compatibility
+
+### Not Working in Safari
+
+**Issue**: Graph doesn't render in Safari.
+
+**Cause**: Older Safari versions lack some Canvas 2D features.
+
+**Solution**: Ensure users are on Safari 14+ or suggest Chrome/Firefox.
+
+### Mobile Touch Gestures Not Working
+
+**Issue**: Can't pinch-to-zoom on mobile.
+
+**Cause**: Browser or container blocking touch events.
+
+**Solution**: Ensure parent has no conflicting touch handlers:
+
+```tsx
+<div
+ style={{ touchAction: 'none' }} // Let graph handle touches
+ onTouchStart={(e) => e.stopPropagation()}
+>
+ <MemoryGraph documents={documents} />
+</div>
+```
+
+### Canvas Appears Blurry
+
+**Issue**: Graph looks pixelated or blurry.
+
+**Cause**: High-DPI displays not being handled correctly.
+
+**Solution**: This should be automatic. If it persists:
+1. Check browser zoom is at 100%
+2. Verify `devicePixelRatio` is being respected
+3. Try different browser
+
+## Build Errors
+
+### Module Not Found
+
+**Error**: `Cannot find module '@supermemory/memory-graph'`
+
+**Solution**:
+1. Reinstall package: `npm install @supermemory/memory-graph`
+2. Clear node_modules: `rm -rf node_modules && npm install`
+3. Check package.json includes the package
+
+### Build Fails with CSS Error
+
+**Error**: `Failed to parse CSS` or similar.
+
+**Cause**: Bundler doesn't support CSS-in-JS.
+
+**Solution**: The package uses automatic CSS injection - no CSS import needed. If you must import CSS:
+
+```tsx
+import '@supermemory/memory-graph/styles.css'
+```
+
+## Still Having Issues?
+
+<CardGroup cols={2}>
+ <Card title="GitHub Issues" icon="github" href="https://github.com/supermemoryai/supermemory/issues">
+ Report bugs or request features
+ </Card>
+
+ <Card title="Support" icon="life-buoy" href="mailto:[email protected]">
+ Contact the Supermemory team
+ </Card>
+</CardGroup>
+
+When reporting issues, please include:
+- Browser and version
+- Package version (`npm list @supermemory/memory-graph`)
+- Framework (Next.js, React, etc.) and version
+- Minimal reproduction code
+- Console errors or screenshots