Skip to content

Commit d847347

Browse files
authored
Merge pull request #129 from techulus/docs/sdks
Add docs for SDK
2 parents a3b8604 + 0a111bc commit d847347

File tree

8 files changed

+586
-12
lines changed

8 files changed

+586
-12
lines changed

apps/docs/content/docs/index.mdx

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,10 @@ title: Welcome!
33
description: changelog made smarter, faster, and user-focused.
44
---
55

6-
Looking to setup our widget?
6+
## Getting Started
77

8-
<Card title="Setup Widget" href="/docs/widget" />
9-
10-
## Want to deep dive?
11-
12-
Dive a little deeper and start exploring our API reference to get an idea of everything that's possible with the API:
13-
14-
<Card title="API Reference" href="/docs/api/page" />
8+
<Cards>
9+
<Card title="Setup Widget" href="/docs/widget" />
10+
<Card title="SDKs" href="/docs/sdk" />
11+
<Card title="API Reference" href="/docs/api/page" />
12+
</Cards>
Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
---
2+
title: Core SDK
3+
description: Framework-agnostic JavaScript SDK for fetching changelog data.
4+
---
5+
6+
## Installation
7+
8+
```bash
9+
npm install @changespage/core
10+
```
11+
12+
## Usage
13+
14+
```typescript
15+
import { createChangesPageClient } from "@changespage/core";
16+
17+
const client = createChangesPageClient({
18+
baseUrl: "https://your-page.changes.page",
19+
});
20+
21+
const { posts, totalCount, hasMore } = await client.getPosts({ limit: 10 });
22+
23+
const latestPost = await client.getLatestPost();
24+
25+
const pinnedPost = await client.getPinnedPost();
26+
```
27+
28+
## API
29+
30+
### `createChangesPageClient(config)`
31+
32+
Creates a client instance.
33+
34+
| Option | Type | Description |
35+
| --------- | -------- | ------------------------ |
36+
| `baseUrl` | `string` | Your changes.page URL |
37+
38+
### Client Methods
39+
40+
#### `getPosts(options?)`
41+
42+
Fetches paginated posts.
43+
44+
| Option | Type | Default | Description |
45+
| -------- | -------- | ------- | -------------------------- |
46+
| `limit` | `number` | 10 | Number of posts (max: 50) |
47+
| `offset` | `number` | 0 | Pagination offset |
48+
49+
Returns `{ posts, totalCount, hasMore }`.
50+
51+
#### `getLatestPost()`
52+
53+
Returns the most recent post or `null`.
54+
55+
#### `getPinnedPost()`
56+
57+
Returns the pinned post or `null`.
58+
59+
### `getTagLabel(tag)`
60+
61+
Converts a tag to display label (e.g., `"fix"``"Fix"`).
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
---
2+
title: SDKs
3+
description: JavaScript and React SDKs for integrating changelogs into your application.
4+
---
5+
6+
We provide official SDKs to help you integrate changelogs directly into your application.
7+
8+
<Cards>
9+
<Card title="Core SDK" href="/docs/sdk/core" />
10+
<Card title="React SDK" href="/docs/sdk/react" />
11+
</Cards>
12+
13+
## Next.js Examples
14+
15+
<Cards>
16+
<Card title="App Router" href="/docs/sdk/nextjs-app-router" />
17+
<Card title="Pages Router" href="/docs/sdk/nextjs-pages-router" />
18+
</Cards>
Lines changed: 174 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,174 @@
1+
---
2+
title: Next.js App Router
3+
description: Using the React SDK with Next.js App Router.
4+
---
5+
6+
## Installation
7+
8+
```bash
9+
npm install @changespage/react react-markdown
10+
```
11+
12+
## Server Component with Client Hydration
13+
14+
```tsx title="app/changelog/page.tsx"
15+
import { createChangesPageClient } from "@changespage/react";
16+
import { ChangelogList } from "./changelog-list";
17+
18+
const client = createChangesPageClient({
19+
baseUrl: "https://your-page.changes.page",
20+
});
21+
22+
export default async function ChangelogPage() {
23+
const initialData = await client.getPosts({ limit: 10 });
24+
25+
return <ChangelogList initialData={initialData} />;
26+
}
27+
```
28+
29+
```tsx title="app/changelog/changelog-list.tsx"
30+
"use client";
31+
32+
import { createChangesPageClient, usePosts, getTagLabel } from "@changespage/react";
33+
import Markdown from "react-markdown";
34+
35+
const client = createChangesPageClient({
36+
baseUrl: "https://your-page.changes.page",
37+
});
38+
39+
export function ChangelogList({ initialData }: { initialData: Awaited<ReturnType<typeof client.getPosts>> }) {
40+
const { posts, hasMore, loading, loadMore } = usePosts({
41+
client,
42+
initialData,
43+
});
44+
45+
return (
46+
<div>
47+
{posts.map((post) => (
48+
<article key={post.id}>
49+
<div>
50+
{post.tags.map((tag) => (
51+
<span key={tag}>{getTagLabel(tag)}</span>
52+
))}
53+
</div>
54+
<h2>{post.title}</h2>
55+
<Markdown>{post.plain_text_content}</Markdown>
56+
</article>
57+
))}
58+
{hasMore && (
59+
<button type="button" onClick={loadMore} disabled={loading}>
60+
{loading ? "Loading..." : "Load More"}
61+
</button>
62+
)}
63+
</div>
64+
);
65+
}
66+
```
67+
68+
## Client-Only
69+
70+
```tsx title="app/changelog/page.tsx"
71+
"use client";
72+
73+
import { createChangesPageClient, usePosts, getTagLabel } from "@changespage/react";
74+
import Markdown from "react-markdown";
75+
76+
const client = createChangesPageClient({
77+
baseUrl: "https://your-page.changes.page",
78+
});
79+
80+
export default function ChangelogPage() {
81+
const { posts, hasMore, loading, loadMore } = usePosts({ client });
82+
83+
if (loading && posts.length === 0) {
84+
return <div>Loading...</div>;
85+
}
86+
87+
return (
88+
<div>
89+
{posts.map((post) => (
90+
<article key={post.id}>
91+
<div>
92+
{post.tags.map((tag) => (
93+
<span key={tag}>{getTagLabel(tag)}</span>
94+
))}
95+
</div>
96+
<h2>{post.title}</h2>
97+
<Markdown>{post.plain_text_content}</Markdown>
98+
</article>
99+
))}
100+
{hasMore && (
101+
<button type="button" onClick={loadMore} disabled={loading}>
102+
{loading ? "Loading..." : "Load More"}
103+
</button>
104+
)}
105+
</div>
106+
);
107+
}
108+
```
109+
110+
## With Tailwind CSS
111+
112+
```tsx title="app/changelog/page.tsx"
113+
"use client";
114+
115+
import { createChangesPageClient, usePosts, getTagLabel, type PostTag } from "@changespage/react";
116+
import Markdown from "react-markdown";
117+
118+
const client = createChangesPageClient({
119+
baseUrl: "https://your-page.changes.page",
120+
});
121+
122+
const tagColors: Record<PostTag, string> = {
123+
new: "bg-green-100 text-green-800",
124+
fix: "bg-red-100 text-red-800",
125+
improvement: "bg-blue-100 text-blue-800",
126+
announcement: "bg-purple-100 text-purple-800",
127+
alert: "bg-yellow-100 text-yellow-800",
128+
};
129+
130+
export default function ChangelogPage() {
131+
const { posts, hasMore, loading, loadMore } = usePosts({ client });
132+
133+
if (loading && posts.length === 0) {
134+
return (
135+
<div className="flex justify-center py-12">
136+
<div className="h-8 w-8 animate-spin rounded-full border-4 border-gray-200 border-t-gray-800" />
137+
</div>
138+
);
139+
}
140+
141+
return (
142+
<div className="mx-auto max-w-2xl space-y-8 px-4 py-8">
143+
{posts.map((post) => (
144+
<article key={post.id} className="rounded-lg border border-gray-200 p-6">
145+
<div className="mb-3 flex flex-wrap gap-2">
146+
{post.tags.map((tag) => (
147+
<span
148+
key={tag}
149+
className={`rounded-full px-2.5 py-0.5 text-xs font-medium ${tagColors[tag]}`}
150+
>
151+
{getTagLabel(tag)}
152+
</span>
153+
))}
154+
</div>
155+
<h2 className="mb-2 text-xl font-semibold text-gray-900">{post.title}</h2>
156+
<div className="prose prose-sm text-gray-600">
157+
<Markdown>{post.plain_text_content}</Markdown>
158+
</div>
159+
</article>
160+
))}
161+
{hasMore && (
162+
<button
163+
type="button"
164+
onClick={loadMore}
165+
disabled={loading}
166+
className="w-full rounded-lg border border-gray-300 bg-white px-4 py-2 text-sm font-medium text-gray-700 hover:bg-gray-50 disabled:opacity-50"
167+
>
168+
{loading ? "Loading..." : "Load More"}
169+
</button>
170+
)}
171+
</div>
172+
);
173+
}
174+
```

0 commit comments

Comments
 (0)