@togglely/sdk-react 1.1.10 → 1.2.0

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.
Files changed (2) hide show
  1. package/README.md +163 -83
  2. package/package.json +38 -38
package/README.md CHANGED
@@ -1,8 +1,14 @@
1
- # @togglely/sdk-react
1
+ # Togglely React SDK
2
2
 
3
- React SDK for Togglely - Feature toggles with hooks.
3
+ React hooks and components for [Togglely](https://togglely.io) feature flag management.
4
4
 
5
- No automatic polling - manual refresh or use WebSockets for real-time updates.
5
+ ## Features
6
+
7
+ - 🎣 **React Hooks** - `useToggle`, `useStringToggle`, `useNumberToggle`, `useJSONToggle`
8
+ - 🏗️ **Components** - `FeatureToggle`, `FeatureToggleSwitch` for declarative UI
9
+ - ⚡ **SSR Support** - Works with Next.js, Remix, and other SSR frameworks
10
+ - 💾 **Offline Support** - Built-in offline fallback
11
+ - 🔒 **TypeScript** - Full type safety
6
12
 
7
13
  ## Installation
8
14
 
@@ -10,153 +16,227 @@ No automatic polling - manual refresh or use WebSockets for real-time updates.
10
16
  npm install @togglely/sdk-react
11
17
  ```
12
18
 
13
- ## Usage
14
-
15
- ### Provider
16
-
17
- Wrap your app with `TogglelyProvider`. You can provide an `initialContext` for multi-tenant setups:
19
+ ## Quick Start
18
20
 
19
21
  ```tsx
20
- import { TogglelyProvider } from '@togglely/sdk-react';
22
+ import { TogglelyProvider, useToggle, FeatureToggle } from '@togglely/sdk-react';
21
23
 
22
24
  function App() {
23
25
  return (
24
26
  <TogglelyProvider
25
27
  apiKey="your-api-key"
26
- project="web-app"
28
+ project="my-project"
27
29
  environment="production"
28
- baseUrl="https://your-togglely-instance.com"
29
- initialContext={{
30
- tenantId: 'customer-123',
31
- plan: 'premium'
32
- }}
30
+ baseUrl="https://togglely.io"
33
31
  >
34
- <MyApp />
32
+ <MyComponent />
35
33
  </TogglelyProvider>
36
34
  );
37
35
  }
38
- ```
39
36
 
40
- ### Server Side Rendering (SSR) & Next.js
37
+ function MyComponent() {
38
+ // Using hook
39
+ const isEnabled = useToggle('new-feature', false);
40
+
41
+ return (
42
+ <div>
43
+ {isEnabled && <NewFeature />}
44
+
45
+ {/* Or using component */}
46
+ <FeatureToggle toggle="premium-feature" fallback={<FreeVersion />}>
47
+ <PremiumVersion />
48
+ </FeatureToggle>
49
+ </div>
50
+ );
51
+ }
52
+ ```
41
53
 
42
- For SSR, use `getTogglelyState` to fetch toggles before the page renders:
54
+ ## Provider Configuration
43
55
 
44
56
  ```tsx
45
- // Next.js getServerSideProps example
46
- import { getTogglelyState } from '@togglely/sdk-react';
57
+ <TogglelyProvider
58
+ apiKey="your-api-key"
59
+ project="my-project"
60
+ environment="production"
61
+ baseUrl="https://togglely.io"
62
+ tenantId="brand-a" // For multi-brand projects
63
+ offlineJsonPath="/toggles.json" // Offline fallback
64
+ initialContext={{ userId: '123' }}
65
+ >
66
+ {children}
67
+ </TogglelyProvider>
68
+ ```
47
69
 
48
- export async function getServerSideProps() {
49
- const toggles = await getTogglelyState({
50
- apiKey: process.env.TOGGLELY_API_KEY,
51
- project: 'web-app',
52
- environment: 'production',
53
- baseUrl: 'https://your-togglely-instance.com'
54
- }, {
55
- tenantId: 'customer-123'
56
- });
70
+ ## Hooks
57
71
 
58
- return { props: { initialToggles: toggles } };
59
- }
72
+ ### useToggle
60
73
 
61
- // Then pass to Provider to avoid flickering
62
- <TogglelyProvider initialToggles={props.initialToggles} ...>
63
- ```
74
+ Check if a boolean feature is enabled:
64
75
 
65
- ### Hooks
76
+ ```tsx
77
+ const isEnabled = useToggle('new-feature', false);
78
+ ```
66
79
 
67
- #### `useTogglelyClient()`
80
+ ### useStringToggle
68
81
 
69
- Access the core client to update context dynamically:
82
+ Get a string value:
70
83
 
71
84
  ```tsx
72
- function LoginComponent() {
73
- const client = useTogglelyClient();
74
-
75
- const handleLogin = (user) => {
76
- client.setContext({
77
- userId: user.id,
78
- tenantId: user.companyId
79
- });
80
- };
81
- }
85
+ const message = useStringToggle('welcome-message', 'Hello!');
82
86
  ```
83
87
 
84
- #### `useToggle(key, defaultValue)`
88
+ ### useNumberToggle
85
89
 
86
- Check if a boolean feature toggle is enabled:
90
+ Get a number value:
87
91
 
88
92
  ```tsx
89
- function MyComponent() {
90
- const isEnabled = useToggle('new-feature', false);
91
- return isEnabled ? <NewFeature /> : <OldFeature />;
92
- }
93
+ const timeout = useNumberToggle('api-timeout', 5000);
93
94
  ```
94
95
 
95
- #### `useStringToggle(key, defaultValue)`
96
+ ### useJSONToggle
96
97
 
97
- Get a string toggle value:
98
+ Get a JSON value:
98
99
 
99
100
  ```tsx
100
- const message = useStringToggle('welcome-message', 'Hello');
101
+ const config = useJSONToggle('app-config', { theme: 'dark' });
101
102
  ```
102
103
 
103
- #### `useNumberToggle(key, defaultValue)`
104
+ ### useTogglelyClient
104
105
 
105
- Get a number toggle value:
106
+ Access the client directly:
106
107
 
107
108
  ```tsx
108
- const limit = useNumberToggle('max-items', 10);
109
+ const client = useTogglelyClient();
110
+ client.setContext({ userId: '123' });
109
111
  ```
110
112
 
111
- #### `useJSONToggle(key, defaultValue)`
113
+ ### useTogglelyState
112
114
 
113
- Get a JSON toggle value:
115
+ Get the current state:
114
116
 
115
117
  ```tsx
116
- const config = useJSONToggle('app-config', { theme: 'light' });
118
+ const { isReady, isOffline, lastError } = useTogglelyState();
117
119
  ```
118
120
 
119
- #### `useToggles()`
121
+ ## Components
120
122
 
121
- Get all toggles:
123
+ ### FeatureToggle
122
124
 
123
125
  ```tsx
124
- const toggles = useToggles();
125
- // toggles = { 'new-feature': { value: true, enabled: true }, ... }
126
+ <FeatureToggle
127
+ toggle="new-feature"
128
+ fallback={<OldVersion />}
129
+ defaultValue={false}
130
+ >
131
+ <NewVersion />
132
+ </FeatureToggle>
126
133
  ```
127
134
 
128
- #### `useTogglelyState()`
129
-
130
- Get the SDK state:
135
+ ### FeatureToggleSwitch
131
136
 
132
137
  ```tsx
133
- const state = useTogglelyState();
134
- // state = { isReady: true, isOffline: false, lastError: null, lastFetch: Date }
138
+ <FeatureToggleSwitch toggle="plan-type" defaultValue="free">
139
+ <FeatureToggleCase when="premium">
140
+ <PremiumFeatures />
141
+ </FeatureToggleCase>
142
+ <FeatureToggleCase when="pro">
143
+ <ProFeatures />
144
+ </FeatureToggleCase>
145
+ <FeatureToggleCase>
146
+ <FreeFeatures />
147
+ </FeatureToggleCase>
148
+ </FeatureToggleSwitch>
135
149
  ```
136
150
 
137
- ### Components
151
+ ## Server-Side Rendering (SSR)
138
152
 
139
- #### `FeatureToggle`
153
+ ### Next.js App Router
140
154
 
141
- Conditionally render content:
155
+ ```tsx
156
+ // app/layout.tsx
157
+ import { TogglelyProvider } from '@togglely/sdk-react';
158
+
159
+ export default async function RootLayout({ children }) {
160
+ // Fetch toggles on server
161
+ const response = await fetch(
162
+ `https://togglely.io/sdk/flags/my-project/production?apiKey=${process.env.TOGGLELY_APIKEY}`
163
+ );
164
+ const initialToggles = await response.json();
165
+
166
+ return (
167
+ <html>
168
+ <body>
169
+ <TogglelyProvider
170
+ apiKey={process.env.TOGGLELY_APIKEY!}
171
+ project="my-project"
172
+ environment="production"
173
+ baseUrl="https://togglely.io"
174
+ initialToggles={initialToggles}
175
+ >
176
+ {children}
177
+ </TogglelyProvider>
178
+ </body>
179
+ </html>
180
+ );
181
+ }
182
+ ```
183
+
184
+ ### Next.js Pages Router
142
185
 
143
186
  ```tsx
144
- import { FeatureToggle } from '@togglely/sdk-react';
187
+ // pages/index.tsx
188
+ import { TogglelyProvider, getTogglelyState } from '@togglely/sdk-react';
145
189
 
146
- <FeatureToggle toggle="new-feature" fallback={<OldFeature />}>
147
- <NewFeature />
148
- </FeatureToggle>
190
+ export async function getServerSideProps() {
191
+ const initialToggles = await getTogglelyState({
192
+ apiKey: process.env.TOGGLELY_APIKEY!,
193
+ project: 'my-project',
194
+ environment: 'production',
195
+ baseUrl: 'https://togglely.io',
196
+ });
197
+
198
+ return { props: { initialToggles } };
199
+ }
200
+
201
+ export default function Page({ initialToggles }) {
202
+ return (
203
+ <TogglelyProvider
204
+ apiKey={process.env.TOGGLELY_APIKEY!}
205
+ project="my-project"
206
+ environment="production"
207
+ baseUrl="https://togglely.io"
208
+ initialToggles={initialToggles}
209
+ >
210
+ <MyComponent />
211
+ </TogglelyProvider>
212
+ );
213
+ }
149
214
  ```
150
215
 
151
- ### SSR Support
216
+ ## Build-Time JSON Generation
217
+
218
+ Generate offline JSON during build:
152
219
 
153
- Pass initial toggles for server-side rendering:
220
+ ```json
221
+ {
222
+ "scripts": {
223
+ "build": "togglely-pull --apiKey=$TOGGLELY_APIKEY --project=my-project --environment=production --output=./public/toggles.json && next build"
224
+ }
225
+ }
226
+ ```
227
+
228
+ Then use in your app:
154
229
 
155
230
  ```tsx
156
231
  <TogglelyProvider
157
232
  apiKey="your-api-key"
233
+ project="my-project"
158
234
  environment="production"
159
- baseUrl="https://your-togglely-instance.com"
160
- initialToggles={{ 'new-feature': true }}
235
+ baseUrl="https://togglely.io"
236
+ offlineJsonPath="/toggles.json"
161
237
  >
162
238
  ```
239
+
240
+ ## License
241
+
242
+ MIT
package/package.json CHANGED
@@ -1,38 +1,38 @@
1
- {
2
- "name": "@togglely/sdk-react",
3
- "version": "1.1.10",
4
- "description": "React SDK for Togglely - Feature toggles with hooks",
5
- "main": "dist/index.js",
6
- "module": "dist/index.esm.js",
7
- "types": "dist/index.d.ts",
8
- "files": [
9
- "dist"
10
- ],
11
- "scripts": {
12
- "build": "tsc && rollup -c",
13
- "test": "jest"
14
- },
15
- "keywords": [
16
- "feature-flags",
17
- "feature-toggles",
18
- "togglely",
19
- "react",
20
- "hooks"
21
- ],
22
- "author": "Togglely",
23
- "license": "MIT",
24
- "peerDependencies": {
25
- "react": "^16.8.0 || ^17.0.0 || ^18.0.0",
26
- "react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0"
27
- },
28
- "dependencies": {
29
- "@togglely/sdk-core": "^1.0.0"
30
- },
31
- "devDependencies": {
32
- "@rollup/plugin-typescript": "^11.1.5",
33
- "@types/react": "^18.2.45",
34
- "rollup": "^4.9.1",
35
- "tslib": "^2.6.2",
36
- "typescript": "^5.3.3"
37
- }
38
- }
1
+ {
2
+ "name": "@togglely/sdk-react",
3
+ "version": "1.2.0",
4
+ "description": "React SDK for Togglely - Feature toggles with hooks",
5
+ "main": "dist/index.js",
6
+ "module": "dist/index.esm.js",
7
+ "types": "dist/index.d.ts",
8
+ "files": [
9
+ "dist"
10
+ ],
11
+ "scripts": {
12
+ "build": "tsc && rollup -c",
13
+ "test": "jest"
14
+ },
15
+ "keywords": [
16
+ "feature-flags",
17
+ "feature-toggles",
18
+ "togglely",
19
+ "react",
20
+ "hooks"
21
+ ],
22
+ "author": "Togglely",
23
+ "license": "MIT",
24
+ "peerDependencies": {
25
+ "react": "^16.8.0 || ^17.0.0 || ^18.0.0",
26
+ "react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0"
27
+ },
28
+ "dependencies": {
29
+ "@togglely/sdk-core": "^1.0.0"
30
+ },
31
+ "devDependencies": {
32
+ "@rollup/plugin-typescript": "^11.1.5",
33
+ "@types/react": "^18.2.45",
34
+ "rollup": "^4.9.1",
35
+ "tslib": "^2.6.2",
36
+ "typescript": "^5.3.3"
37
+ }
38
+ }