@feedlog-ai/react
v0.2.2
Published
React bindings for Feedlog Toolkit Web Components
Maintainers
Readme
@feedlog-ai/react
React bindings for Feedlog Toolkit web components. Auto-generated from Stencil components with full TypeScript support.
Features
- React Components: Native React components with JSX support
- TypeScript Support: Full type safety with TypeScript definitions
- Auto-generated: Generated from Stencil web components for consistency
- Event Handling: React-friendly event handling with proper typing
- Peer Dependencies: React >=17.0.0 and React DOM >=17.0.0
- Tree Shakeable: Only import the components you need
Installation
npm install @feedlog-ai/reactComponents
FeedlogIssuesClient
The main component for displaying GitHub issues with built-in SDK integration.
Props:
apiKey: API key for Feedlog authentication (required)type?: Filter by issue type —'bug'or'enhancement'limit?: Maximum issues per page (1–100)sortBy?:'createdAt'or'updatedAt'endpoint?: Custom API endpointmaxWidth?: Container max width (default:'42rem')paginationType?:'load-more'or'prev-next'(default:'load-more')loadMoreLabel?: Load-more button label (default:'Load More')minSkeletonTime?: Minimum ms for skeleton display (default:250)theme?:'light'or'dark'(default:'light')heading?/subtitle?: Section heading and subtitleemptyStateTitle?/emptyStateMessage?: Empty-state copygetIssueUrl?:(issue: FeedlogIssue) => string | null | undefinedwhengithubIssueLinkis missing
Events:
onFeedlogUpvote: Called when an issue is upvotedonFeedlogError: Called on errors
Usage
import React from 'react';
import { FeedlogIssuesClient } from '@feedlog-ai/react';
function App() {
return (
<div>
<FeedlogIssuesClient
apiKey="your-api-key"
type="bug"
limit={10}
theme="light"
maxWidth="42rem"
onFeedlogUpvote={event => {
console.log('Issue upvoted:', event.detail);
// event.detail contains: { issueId, upvoted, upvoteCount }
}}
onFeedlogError={event => {
console.error('Error occurred:', event.detail);
// event.detail contains: { error, code? }
}}
/>
</div>
);
}
export default App;Server-Side Rendering (SSR)
The components support Server-Side Rendering out of the box. @feedlog-ai/core/ssr-globals and the hook-free @feedlog-ai/react/ssr-components entry ensure Node does not throw on browser-only globals such as self when Stencil bundles load.
Next.js (App Router or Pages Router)
Wrap your next.config.js or next.config.ts with our Next.js SSR helper:
// next.config.ts
import { withFeedlogSSR } from '@feedlog-ai/react/next';
const nextConfig = {
// your existing config
};
export default withFeedlogSSR(nextConfig);App Router — Server Components: The main package (@feedlog-ai/react) uses React hooks (useEffect, useRef) for custom-element registration and props. Do not import it from server components (pages or layouts without "use client"). For SSR-safe Badge, Button, and Card, import from @feedlog-ai/react/ssr-components instead. For interactive or full-featured wrappers (for example FeedlogIssuesClient), use a client boundary: put them in a file marked with "use client" and import from @feedlog-ai/react there.
Vite / Remix
For Vite-based apps (like Remix or standard Vite React), add our Vite SSR plugin:
// vite.config.ts
import { defineConfig } from 'vite';
import { feedlogSSR } from '@feedlog-ai/react/vite';
import react from '@vitejs/plugin-react';
export default defineConfig({
plugins: [react(), feedlogSSR()],
});TanStack Start
TanStack Start is Vite-based, so use the same compiler approach. Add feedlogSSR() to your Vite config after the React plugin:
// vite.config.ts
import { defineConfig } from 'vite';
import tsConfigPaths from 'vite-tsconfig-paths';
import { tanstackStart } from '@tanstack/react-start/plugin/vite';
import viteReact from '@vitejs/plugin-react';
import { feedlogSSR } from '@feedlog-ai/react/start';
export default defineConfig({
server: { port: 3000 },
plugins: [
tsConfigPaths(),
tanstackStart(),
viteReact(), // must come after tanstackStart
feedlogSSR(), // Stencil SSR for Feedlog components
],
});Note: The SSR plugin requires @stencil/ssr, which declares vite@^6.x as a peer dependency. For Vite 7 projects, add this override to your package.json to avoid peer dependency conflicts:
"overrides": {
"@stencil/ssr": {
"vite": "$vite"
}
}Troubleshooting: If you see Expected ">" but found "{" during the SSR build, the Stencil transform may be failing on complex TypeScript generics in files that import from @feedlog-ai/react. Refactor inline generics to type aliases, e.g.:
// Instead of: useState<Record<string, MyType>>(...)
type MyState = Record<string, MyType>
const [state, setState] = useState<MyState>(...)
// Instead of: event: CustomEvent<{ a: string; b: number }>
interface EventDetail { a: string; b: number }
event: CustomEvent<EventDetail>SSR Limitations
The compiler-based SSR (used by Vite, Remix, and Next.js with feedlogSSR / withFeedlogSSR) performs static AST analysis at build time and cannot resolve runtime values. Dynamic props such as apiKey={apiKey} or theme={theme} are serialized as their identifier names instead of actual values, which causes broken API calls and incorrect display.
- SSR-safe components (pre-rendered with Declarative Shadow DOM):
FeedlogBadge,FeedlogButton,FeedlogCard - Excluded from SSR (rendered at request time by React; no pre-rendered DSD):
FeedlogIssuesClient,FeedlogIssueComponent,FeedlogIssues,FeedlogIssuesList— these receive props correctly at runtime but may show a brief empty state before client hydration
This is a documented limitation of Stencil's compiler approach ("Static props only").
Build your own changelog
- Build Feedlog — three tiers (client, composable, core-only) and AI copy-paste blocks
- Top-level client —
FeedlogIssuesClient - Composable + your data —
FeedlogSDK+FeedlogIssues(full SSR, loaders)
Event Handling
import React, { useCallback } from 'react';
import { FeedlogIssuesClient } from '@feedlog-ai/react';
function IssuesComponent() {
const handleUpvote = useCallback((event: CustomEvent) => {
const { issueId, upvoted, upvoteCount } = event.detail;
console.log(`Issue ${issueId} ${upvoted ? 'upvoted' : 'unvoted'}`);
console.log(`New upvote count: ${upvoteCount}`);
}, []);
const handleError = useCallback((event: CustomEvent) => {
const { error, code } = event.detail;
console.error(`Feedlog error (${code}):`, error);
// Handle error in your UI
}, []);
return (
<FeedlogIssuesClient
apiKey="your-api-key"
onFeedlogUpvote={handleUpvote}
onFeedlogError={handleError}
/>
);
}With State Management
import React, { useState, useCallback } from 'react';
import { FeedlogIssuesClient } from '@feedlog-ai/react';
function IssuesWithState() {
const [theme, setTheme] = useState<'light' | 'dark'>('light');
const [error, setError] = useState<string | null>(null);
const handleError = useCallback((event: CustomEvent) => {
setError(event.detail.error);
// Clear error after 5 seconds
setTimeout(() => setError(null), 5000);
}, []);
return (
<div>
{error && <div className="error-banner">Error: {error}</div>}
<FeedlogIssuesClient apiKey="your-api-key" theme={theme} onFeedlogError={handleError} />
</div>
);
}Other Components
The package also includes React bindings for additional UI components:
import {
FeedlogBadge,
FeedlogButton,
FeedlogCard,
FeedlogIssueComponent,
FeedlogIssues,
FeedlogIssuesList,
} from '@feedlog-ai/react';
// Badge component (variants: default | destructive | enhancement | secondary)
<FeedlogBadge variant="enhancement">New</FeedlogBadge>
// Button component (variants: default | outline | ghost | destructive)
<FeedlogButton variant="default" size="lg" onFeedlogClick={handleClick}>
Click me
</FeedlogButton>
// Card component
<FeedlogCard>
<h3>Card Title</h3>
<p>Card content</p>
</FeedlogCard>TypeScript Support
All components are fully typed. Import types from the core package if needed:
import { FeedlogIssue } from '@feedlog-ai/core';
import { FeedlogIssuesClient } from '@feedlog-ai/react';
// Type-safe event handling
const handleUpvote = (
event: CustomEvent<{
issueId: string;
upvoted: boolean;
upvoteCount: number;
}>
) => {
// Fully typed event detail
console.log(event.detail.issueId);
console.log(event.detail.upvoted);
console.log(event.detail.upvoteCount);
};Requirements
- React >= 17.0.0
- React DOM >= 17.0.0
- Modern browsers with Web Components support
Browser Support
Same as the underlying web components:
- Chrome 61+
- Firefox 63+
- Safari 11+
- Edge 79+
Migration from Direct Web Components
If you're migrating from using web components directly:
// Before (direct web component)
<feedlog-issues-client
api-key="key"
onFeedlogUpvote={(e) => console.log(e.detail)}
/>
// After (React component)
<FeedlogIssuesClient
apiKey="key"
onFeedlogUpvote={(e) => console.log(e.detail)}
/>Key differences:
api-key→apiKey(camelCase)- Event handlers follow React conventions
- All props are properly typed
License
MIT
