@cstar.help/react 0.10.1 → 0.10.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -2,10 +2,10 @@
2
2
 
3
3
  React hooks for the [cStar](https://cstar.help) customer support platform. Build custom chat widgets and knowledge base UIs with type-safe, SSR-compatible hooks.
4
4
 
5
- - **React 18+** — hooks with automatic loading states and error handling
6
- - **Three modules** — Chat (real-time messaging), Library (knowledge base), and Community (forum)
7
- - **TypeScript-first** — full type definitions included
8
- - **Tiny** — ~18 KB, tree-shakeable, only peer deps
5
+ - **React 18+**: hooks with automatic loading states and error handling
6
+ - **Three modules**: Chat (real-time messaging), Library (knowledge base), and Community (forum)
7
+ - **TypeScript-first**: full type definitions included
8
+ - **Tiny**: ~18 KB, tree-shakeable, only peer deps
9
9
 
10
10
  ## Install
11
11
 
@@ -82,7 +82,7 @@ function ChatWindow({ ticketId }) {
82
82
  const [text, setText] = useState('');
83
83
 
84
84
  const handleSend = async () => {
85
- await send(text); // optimistic — appears instantly
85
+ await send(text); // optimistic: appears instantly
86
86
  setText('');
87
87
  };
88
88
 
@@ -109,7 +109,7 @@ function ChatWindow({ ticketId }) {
109
109
 
110
110
  ## Knowledge Base
111
111
 
112
- Wrap in `<CStarLibraryProvider>` for public knowledge base access — no auth required.
112
+ Wrap in `<CStarLibraryProvider>` for public knowledge base access. No auth required.
113
113
 
114
114
  ### Setup
115
115
 
@@ -184,7 +184,7 @@ function SearchBar() {
184
184
 
185
185
  ## Community
186
186
 
187
- Wrap in `<CStarCommunityProvider>` for public community forum access — no auth required.
187
+ Wrap in `<CStarCommunityProvider>` for public community forum access. No auth required.
188
188
 
189
189
  ### Setup
190
190
 
@@ -220,7 +220,7 @@ function CommunityForum() {
220
220
  <ul>
221
221
  {posts.map((post) => (
222
222
  <li key={post.id}>
223
- {post.title} — {post.voteCount} votes
223
+ {post.title} ({post.voteCount} votes)
224
224
  </li>
225
225
  ))}
226
226
  </ul>
@@ -303,11 +303,11 @@ function CommunitySearch() {
303
303
  ## Using with Next.js App Router (RSC)
304
304
 
305
305
  The dashboard provider (`CStarDashboardProvider`) wraps a `CStarClient`,
306
- which is a class instance — and React Server Components can't serialize
306
+ which is a class instance, and React Server Components can't serialize
307
307
  class instances across the server/client boundary. The provider therefore
308
308
  takes one of two prop shapes:
309
309
 
310
- **Recommended — pass a plain config object.** The provider builds (and
310
+ **Recommended: pass a plain config object.** The provider builds (and
311
311
  disposes) the client inside the `'use client'` boundary, so nothing
312
312
  class-shaped crosses the RSC boundary:
313
313
 
@@ -316,11 +316,17 @@ class-shaped crosses the RSC boundary:
316
316
  'use client';
317
317
  import { CStarDashboardProvider } from '@cstar.help/react';
318
318
 
319
- export function Providers({ children }: { children: React.ReactNode }) {
319
+ export function Providers({
320
+ children,
321
+ secretKey
322
+ }: {
323
+ children: React.ReactNode;
324
+ secretKey: string;
325
+ }) {
320
326
  return (
321
327
  <CStarDashboardProvider
322
328
  config={{
323
- apiKey: process.env.NEXT_PUBLIC_CSTAR_PUBLISHABLE_KEY!,
329
+ apiKey: secretKey, // passed down from your server, see below
324
330
  teamId: process.env.NEXT_PUBLIC_CSTAR_TEAM_ID!
325
331
  }}
326
332
  >
@@ -330,12 +336,16 @@ export function Providers({ children }: { children: React.ReactNode }) {
330
336
  }
331
337
  ```
332
338
 
333
- Use the `apiKey` field for a publishable key (`pk_live_*` / `pk_test_*`),
334
- NOT a secret key — the bundle ships to the browser. For server-only flows
335
- (an admin route handler, a server action), construct `CStarClient` with the
336
- secret key inline; never thread it into a provider.
339
+ Every dashboard hook calls team endpoints, and those need a secret key
340
+ (`sk_live_*` / `sk_test_*`): a publishable key gets 403
341
+ `publishable_key_forbidden` on reads and `publishable_key_write` on writes.
342
+ Whatever you pass to the provider reaches the browser, so use it only in a
343
+ trusted environment, such as an internal tool behind your own login where
344
+ everyone who can open the page may hold that key. Use a key scoped to what
345
+ the dashboard needs. For a public site, have the app call your own backend
346
+ (a route handler or server action) that holds a secret-key `CStarClient`.
337
347
 
338
- **Legacy — pass a pre-built client (deprecated).** If you already have a
348
+ **Legacy: pass a pre-built client (deprecated).** If you already have a
339
349
  client instance you want to share, the `client` prop still works, but you
340
350
  have to construct it inside `'use client'` and you take on responsibility
341
351
  for tearing down the realtime subscription:
@@ -346,21 +356,21 @@ import { useMemo } from 'react';
346
356
  import { CStarClient } from '@cstar.help/js';
347
357
  import { CStarDashboardProvider } from '@cstar.help/react';
348
358
 
349
- export function Providers({ children }) {
359
+ export function Providers({ children, secretKey }) {
350
360
  const client = useMemo(
351
361
  () =>
352
362
  new CStarClient({
353
- apiKey: process.env.NEXT_PUBLIC_CSTAR_PUBLISHABLE_KEY!,
363
+ apiKey: secretKey, // trusted environments only, as above
354
364
  teamId: process.env.NEXT_PUBLIC_CSTAR_TEAM_ID!
355
365
  }),
356
- []
366
+ [secretKey]
357
367
  );
358
368
  return <CStarDashboardProvider client={client}>{children}</CStarDashboardProvider>;
359
369
  }
360
370
  ```
361
371
 
362
372
  Either way, mark the file `'use client'`. Server components can sit above
363
- the provider in the tree — only the provider boundary needs to be a client
373
+ the provider in the tree. Only the provider boundary needs to be a client
364
374
  component.
365
375
 
366
376
  ## Requirements
package/dist/index.cjs CHANGED
@@ -760,7 +760,7 @@ function CStarDashboardProvider({
760
760
  }) {
761
761
  if (!config && !providedClient) {
762
762
  throw new Error(
763
- "CStarDashboardProvider requires either a `config` prop (`{ apiKey, teamId }` \u2014 recommended) or a `client` prop (a pre-built CStarClient instance, deprecated). See https://cstar.help/developers/sdk/react#dashboard"
763
+ "CStarDashboardProvider requires either a `config` prop (`{ apiKey, teamId }`, recommended) or a `client` prop (a pre-built CStarClient instance, deprecated). See https://cstar.help/developers/sdk/react#dashboard"
764
764
  );
765
765
  }
766
766
  const client = (0, import_react17.useMemo)(() => {
package/dist/index.d.cts CHANGED
@@ -359,7 +359,11 @@ interface CStarDashboardProviderProps {
359
359
  * provider builds the `CStarClient` internally so this prop can be passed
360
360
  * across the React Server Components boundary without tripping the
361
361
  * "Classes or null prototypes are not supported" runtime error.
362
- * Config is visible to the browser: use only a publishable key here.
362
+ * Every dashboard hook calls team endpoints, which need a secret key
363
+ * (a publishable key gets 403 publishable_key_forbidden). Config reaches
364
+ * the browser, so use the provider only where everyone who loads the page
365
+ * may hold that key (an internal tool behind your own login, a desktop
366
+ * app). On a public site, call your own backend instead.
363
367
  *
364
368
  * Either `config` or `client` is required.
365
369
  */
@@ -378,17 +382,18 @@ interface CStarDashboardProviderProps {
378
382
  /**
379
383
  * Provides a `CStarClient` to dashboard hooks.
380
384
  *
381
- * Provider props and bundled clients are visible to the browser. Pass only
382
- * a publishable key; supported operations are limited by that key's permissions.
383
- * Run privileged dashboard reads and mutations through your authenticated
384
- * backend, where a secret-key `CStarClient` stays on the server.
385
+ * Every hook calls team endpoints, which need a secret key: publishable keys
386
+ * get 403 publishable_key_forbidden on reads and publishable_key_write on
387
+ * writes. Provider props and bundled clients are visible to the browser, so
388
+ * use the provider only in a trusted environment (an internal tool behind
389
+ * your own login, a desktop app), with a secret key scoped to what the
390
+ * dashboard needs. For anything public, have the app call your own backend,
391
+ * where a secret-key `CStarClient` stays on the server.
385
392
  *
386
393
  * ```tsx
387
- * // app/providers.tsx
394
+ * // app/providers.tsx (an internal tool behind your own login)
388
395
  * 'use client';
389
- * <CStarDashboardProvider
390
- * config={{ apiKey: process.env.NEXT_PUBLIC_CSTAR_PUBLISHABLE_KEY!, teamId }}
391
- * >
396
+ * <CStarDashboardProvider config={{ apiKey: secretKeyFromYourServer, teamId }}>
392
397
  * <TicketList />
393
398
  * </CStarDashboardProvider>
394
399
  * ```
package/dist/index.d.ts CHANGED
@@ -359,7 +359,11 @@ interface CStarDashboardProviderProps {
359
359
  * provider builds the `CStarClient` internally so this prop can be passed
360
360
  * across the React Server Components boundary without tripping the
361
361
  * "Classes or null prototypes are not supported" runtime error.
362
- * Config is visible to the browser: use only a publishable key here.
362
+ * Every dashboard hook calls team endpoints, which need a secret key
363
+ * (a publishable key gets 403 publishable_key_forbidden). Config reaches
364
+ * the browser, so use the provider only where everyone who loads the page
365
+ * may hold that key (an internal tool behind your own login, a desktop
366
+ * app). On a public site, call your own backend instead.
363
367
  *
364
368
  * Either `config` or `client` is required.
365
369
  */
@@ -378,17 +382,18 @@ interface CStarDashboardProviderProps {
378
382
  /**
379
383
  * Provides a `CStarClient` to dashboard hooks.
380
384
  *
381
- * Provider props and bundled clients are visible to the browser. Pass only
382
- * a publishable key; supported operations are limited by that key's permissions.
383
- * Run privileged dashboard reads and mutations through your authenticated
384
- * backend, where a secret-key `CStarClient` stays on the server.
385
+ * Every hook calls team endpoints, which need a secret key: publishable keys
386
+ * get 403 publishable_key_forbidden on reads and publishable_key_write on
387
+ * writes. Provider props and bundled clients are visible to the browser, so
388
+ * use the provider only in a trusted environment (an internal tool behind
389
+ * your own login, a desktop app), with a secret key scoped to what the
390
+ * dashboard needs. For anything public, have the app call your own backend,
391
+ * where a secret-key `CStarClient` stays on the server.
385
392
  *
386
393
  * ```tsx
387
- * // app/providers.tsx
394
+ * // app/providers.tsx (an internal tool behind your own login)
388
395
  * 'use client';
389
- * <CStarDashboardProvider
390
- * config={{ apiKey: process.env.NEXT_PUBLIC_CSTAR_PUBLISHABLE_KEY!, teamId }}
391
- * >
396
+ * <CStarDashboardProvider config={{ apiKey: secretKeyFromYourServer, teamId }}>
392
397
  * <TicketList />
393
398
  * </CStarDashboardProvider>
394
399
  * ```
package/dist/index.js CHANGED
@@ -705,7 +705,7 @@ function CStarDashboardProvider({
705
705
  }) {
706
706
  if (!config && !providedClient) {
707
707
  throw new Error(
708
- "CStarDashboardProvider requires either a `config` prop (`{ apiKey, teamId }` \u2014 recommended) or a `client` prop (a pre-built CStarClient instance, deprecated). See https://cstar.help/developers/sdk/react#dashboard"
708
+ "CStarDashboardProvider requires either a `config` prop (`{ apiKey, teamId }`, recommended) or a `client` prop (a pre-built CStarClient instance, deprecated). See https://cstar.help/developers/sdk/react#dashboard"
709
709
  );
710
710
  }
711
711
  const client = useMemo(() => {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cstar.help/react",
3
- "version": "0.10.1",
3
+ "version": "0.10.2",
4
4
  "description": "React hooks for the cStar customer support platform",
5
5
  "type": "module",
6
6
  "main": "./dist/index.cjs",
@@ -30,12 +30,12 @@
30
30
  },
31
31
  "peerDependencies": {
32
32
  "react": ">=18.0.0",
33
- "@cstar.help/js": ">=0.15.0"
33
+ "@cstar.help/js": "^0.18.2"
34
34
  },
35
35
  "devDependencies": {
36
36
  "react": "^18.3.1",
37
37
  "react-dom": "^18.3.1",
38
- "@cstar.help/js": "^0.17.0",
38
+ "@cstar.help/js": "^0.18.2",
39
39
  "@testing-library/react": "^16.1.0",
40
40
  "@types/react": "^18.3.0",
41
41
  "@types/react-dom": "^18.3.0",