--- 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 (
) } ``` {/* 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([]) const [isLoading, setIsLoading] = useState(true) const [error, setError] = useState(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 (
) } ``` {/* 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([]) const [page, setPage] = useState(1) const [hasMore, setHasMore] = useState(true) const [isLoading, setIsLoading] = useState(true) const [isLoadingMore, setIsLoadingMore] = useState(false) const [error, setError] = useState(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 (
) } ``` The graph automatically loads more documents when 80% of current documents are visible in the viewport. Set `autoLoadOnViewport={false}` for manual control. {/* 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([]) const [searchQuery, setSearchQuery] = useState('') const [highlightedIds, setHighlightedIds] = useState([]) 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 (
{/* Search bar */}
setSearchQuery(e.target.value)} onKeyDown={(e) => e.key === 'Enter' && handleSearch()} placeholder="Search documents..." style={{ flex: 1, padding: '0.5rem', borderRadius: '0.375rem' }} />
{/* Graph */}
) } ``` Highlighting supports both internal document IDs and custom IDs. The graph will automatically match either. {/* 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 (

No memories yet

Start adding content to see your knowledge graph come to life. Documents and their connections will appear here.

) } ``` ## 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, }) ``` Always implement user isolation on the backend. Never trust client-side filtering for security. ## 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 (
) } ``` ## Next Steps Explore all props and types Solve common issues