Folo Client SDK
The official JavaScript/TypeScript client for Folo - the modern RSS reader. This SDK makes it easy to build applications that interact with Folo's RSS management, reading history, and AI-powered features.
Why Use the Folo SDK?
- Cross-Platform: Works in browsers, Node.js, React Native, and other JavaScript environments
- Type-Safe: Full TypeScript support with auto-completion and error prevention
- Production Ready: Used by Folo's official apps with comprehensive error handling
Installation
pnpm add @follow-app/client-sdk
Quick Start
import { FollowClient } from '@follow-app/client-sdk'
const follow = new FollowClient({
baseURL: 'https://api.follow.is',
credentials: 'include',
})
await follow.subscriptions.create({
url: 'https://example.com/rss',
category: 'Technology',
})
const articles = await follow.entries.list({
read: false,
limit: 20,
})
await follow.entries.batch.read({
entryIds: articles.data.map((entry) => entry.id),
})
Core Features
📰 Feed Management
Subscribe to and manage RSS feeds with ease:
await follow.subscriptions.create({
url: 'https://blog.example.com/rss',
category: 'Tech Blogs',
})
const subscriptions = await follow.subscriptions.get()
await follow.subscriptions.import({ opmlContent })
📖 Reading Experience
Track and manage your reading:
const unread = await follow.entries.list({
read: false,
limit: 50,
})
await follow.entries.batch.read({
entryIds: ['article-1', 'article-2'],
})
await follow.entries.inbox.add({
entryId: 'article-123',
note: 'Read later',
})
🤖 AI-Powered Features
Enhance your reading with AI:
const summary = await follow.ai.summary({
id: 'article-123',
})
const response = await follow.ai.chat({
messages: [
{ role: 'user', content: 'What are the key trends in this article?' },
],
})
const recommendations = await follow.ai.recommendations()
📊 Analytics & Insights
Understand your reading habits:
const stats = await follow.reads.stats()
const feedAnalytics = await follow.feeds.analytics({
feedId: 'feed-123',
})
Setup & Configuration
For Web Applications
import { FollowClient } from '@follow-app/client-sdk'
const follow = new FollowClient({
baseURL: 'https://api.follow.is',
credentials: 'include',
})
For Node.js Applications
import { FollowClient } from '@follow-app/client-sdk'
const follow = new FollowClient({
baseURL: 'https://api.follow.is',
headers: {
Authorization: 'Bearer your-api-token',
},
})
follow.setAuthToken('your-api-token')
For React Native
import { FollowClient } from '@follow-app/client-sdk'
const follow = new FollowClient({
baseURL: 'https://api.follow.is',
credentials: 'include',
headers: {
'User-Agent': 'YourApp/1.0.0',
},
})
Error Handling
The SDK provides clear error handling for common scenarios:
import { FollowAPIError, FollowAuthError } from '@follow-app/client-sdk'
try {
const articles = await follow.entries.list()
} catch (error) {
if (error instanceof FollowAuthError) {
console.log('Authentication required')
redirectToLogin()
} else if (error instanceof FollowAPIError) {
console.log(`Error: ${error.message}`)
showErrorMessage(error.message)
}
}
Specific Error Codes
import { ExceptionCodeMap } from '@follow-app/client-sdk'
try {
await follow.subscriptions.create({ url: 'invalid-url' })
} catch (error) {
if (error.code === ExceptionCodeMap.feed.NOT_FOUND) {
console.log('Feed not found at that URL')
} else if (error.code === ExceptionCodeMap.subscription.ALREADY_EXISTS) {
console.log('You are already subscribed to this feed')
}
}
Common Use Cases
const follow = new FollowClient({
baseURL: 'https://api.follow.is',
credentials: 'include',
})
await follow.subscriptions.create({
url: 'https://blog.openai.com/rss/',
category: 'AI & Technology',
})
const latest = await follow.entries.list({
read: false,
limit: 20,
})
await follow.entries.batch.read({
entryIds: latest.data.map((article) => article.id),
})
Content Curation Tool
await follow.subscriptions.import({ opmlContent })
const techNews = await follow.entries.list({
category: 'Technology',
limit: 100,
read: false,
})
const aiArticles = techNews.data.filter(
(article) =>
article.title.toLowerCase().includes('ai') ||
article.content.toLowerCase().includes('artificial intelligence'),
)
for (const article of aiArticles) {
await follow.entries.inbox.add({
entryId: article.id,
note: 'AI trend research',
})
}
AI-Enhanced Reading App
const recommendations = await follow.ai.chat({
messages: [
{
role: 'user',
content: 'What are the most important articles I should read today?',
},
],
})
const longArticles = await follow.entries.list({
read: false,
limit: 10,
})
for (const article of longArticles.data) {
const summary = await follow.ai.summary({
id: article.id,
})
console.log(`${article.title}\nSummary: ${summary.summary}`)
}
License
MIT License - see LICENSE file for details.
Contributing
We welcome contributions! Please see our contributing guide for details on:
- Setting up the development environment
- Running tests and linting
- Submitting pull requests
- Code style guidelines
Made with ❤️ by the Folo team