|
| 1 | +# Reflag Svelte SDK |
| 2 | + |
| 3 | +The Reflag Svelte SDK provides a simple and intuitive way to integrate feature flags into your Svelte applications. Built on top of the Reflag browser SDK, it offers reactive stores and utilities that work seamlessly with Svelte's reactivity system. |
| 4 | + |
| 5 | +## Installation |
| 6 | + |
| 7 | +```bash |
| 8 | +npm install @reflag/svelte-sdk |
| 9 | +# or |
| 10 | +yarn add @reflag/svelte-sdk |
| 11 | +# or |
| 12 | +pnpm add @reflag/svelte-sdk |
| 13 | +``` |
| 14 | + |
| 15 | +## Quick Start |
| 16 | + |
| 17 | +### 1. Set up the Provider |
| 18 | + |
| 19 | +First, initialize the Reflag provider at the root of your application: |
| 20 | + |
| 21 | +```javascript |
| 22 | +// main.ts or App.svelte |
| 23 | +import { createReflagProvider } from '@reflag/svelte-sdk'; |
| 24 | + |
| 25 | +// Initialize the provider |
| 26 | +createReflagProvider({ |
| 27 | + apiKey: 'your-api-key', |
| 28 | + user: { |
| 29 | + id: 'user-123', |
| 30 | + |
| 31 | + name: 'John Doe' |
| 32 | + }, |
| 33 | + company: { |
| 34 | + id: 'company-456', |
| 35 | + name: 'Acme Inc' |
| 36 | + } |
| 37 | +}); |
| 38 | +``` |
| 39 | + |
| 40 | +### 2. Use Feature Flags in Components |
| 41 | + |
| 42 | +```svelte |
| 43 | +<script lang="ts"> |
| 44 | + import { useFlag, useTrack } from '@reflag/svelte-sdk'; |
| 45 | +
|
| 46 | + // Get a feature flag |
| 47 | + const huddleFlag = useFlag('huddle'); |
| 48 | + const track = useTrack(); |
| 49 | +
|
| 50 | + function startHuddle() { |
| 51 | + // Track the feature usage |
| 52 | + huddleFlag.track(); |
| 53 | + |
| 54 | + // Your huddle logic here |
| 55 | + console.log('Starting huddle...'); |
| 56 | + } |
| 57 | +</script> |
| 58 | +
|
| 59 | +{#if $huddleFlag.isEnabled} |
| 60 | + <button on:click={startHuddle}> |
| 61 | + {$huddleFlag.config.payload?.buttonText || 'Start Huddle'} |
| 62 | + </button> |
| 63 | +{:else} |
| 64 | + <p>Huddle feature is not available</p> |
| 65 | +{/if} |
| 66 | +``` |
| 67 | + |
| 68 | +## API Reference |
| 69 | + |
| 70 | +### Provider |
| 71 | + |
| 72 | +#### `createReflagProvider(props: ReflagProps)` |
| 73 | + |
| 74 | +Creates and initializes the Reflag provider. This should be called once at the root of your application. |
| 75 | + |
| 76 | +**Parameters:** |
| 77 | +- `props.apiKey` (string): Your Reflag API key |
| 78 | +- `props.user` (object, optional): User context information |
| 79 | +- `props.company` (object, optional): Company context information |
| 80 | +- `props.otherContext` (object, optional): Additional context information |
| 81 | +- `props.debug` (boolean, optional): Enable debug logging |
| 82 | + |
| 83 | +### Stores and Utilities |
| 84 | + |
| 85 | +#### `useFlag(key: string)` |
| 86 | + |
| 87 | +Returns a reactive flag object with the following properties: |
| 88 | + |
| 89 | +- `isEnabled` (Readable<boolean>): Whether the flag is enabled |
| 90 | +- `isLoading` (Readable<boolean>): Whether the flag is currently loading |
| 91 | +- `config` (Readable<object>): The flag's configuration data |
| 92 | +- `track()` (function): Track usage of this flag |
| 93 | +- `requestFeedback(options)` (function): Request feedback for this flag |
| 94 | + |
| 95 | +**Example:** |
| 96 | +```svelte |
| 97 | +<script lang="ts"> |
| 98 | + import { useFlag } from '@reflag/svelte-sdk'; |
| 99 | + |
| 100 | + const myFlag = useFlag('my-feature'); |
| 101 | +</script> |
| 102 | +
|
| 103 | +{#if $myFlag.isLoading} |
| 104 | + <p>Loading...</p> |
| 105 | +{:else if $myFlag.isEnabled} |
| 106 | + <div>Feature is enabled!</div> |
| 107 | + <button on:click={() => myFlag.track()}>Use Feature</button> |
| 108 | +{:else} |
| 109 | + <div>Feature is disabled</div> |
| 110 | +{/if} |
| 111 | +``` |
| 112 | + |
| 113 | +#### `useTrack()` |
| 114 | + |
| 115 | +Returns a function to track custom events. |
| 116 | + |
| 117 | +**Example:** |
| 118 | +```svelte |
| 119 | +<script lang="ts"> |
| 120 | + import { useTrack } from '@reflag/svelte-sdk'; |
| 121 | + |
| 122 | + const track = useTrack(); |
| 123 | + |
| 124 | + function handleClick() { |
| 125 | + track('button_clicked', { buttonName: 'CTA Button' }); |
| 126 | + } |
| 127 | +</script> |
| 128 | +
|
| 129 | +<button on:click={handleClick}>Click me</button> |
| 130 | +``` |
| 131 | + |
| 132 | +#### `useClient()` |
| 133 | + |
| 134 | +Returns a readable store containing the current ReflagClient instance. |
| 135 | + |
| 136 | +**Example:** |
| 137 | +```svelte |
| 138 | +<script lang="ts"> |
| 139 | + import { useClient } from '@reflag/svelte-sdk'; |
| 140 | + |
| 141 | + const client = useClient(); |
| 142 | + |
| 143 | + // Access client methods |
| 144 | + $: if ($client) { |
| 145 | + console.log('Client is ready'); |
| 146 | + } |
| 147 | +</script> |
| 148 | +``` |
| 149 | + |
| 150 | +#### `useIsLoading()` |
| 151 | + |
| 152 | +Returns a readable store indicating whether the SDK is currently loading. |
| 153 | + |
| 154 | +**Example:** |
| 155 | +```svelte |
| 156 | +<script lang="ts"> |
| 157 | + import { useIsLoading } from '@reflag/svelte-sdk'; |
| 158 | + |
| 159 | + const isLoading = useIsLoading(); |
| 160 | +</script> |
| 161 | +
|
| 162 | +{#if $isLoading} |
| 163 | + <div>Loading flags...</div> |
| 164 | +{:else} |
| 165 | + <div>Flags loaded!</div> |
| 166 | +{/if} |
| 167 | +``` |
| 168 | + |
| 169 | +#### `useRequestFeedback()` |
| 170 | + |
| 171 | +Returns a function to request feedback from users. |
| 172 | + |
| 173 | +**Example:** |
| 174 | +```svelte |
| 175 | +<script lang="ts"> |
| 176 | + import { useRequestFeedback } from '@reflag/svelte-sdk'; |
| 177 | + |
| 178 | + const requestFeedback = useRequestFeedback(); |
| 179 | + |
| 180 | + function askForFeedback() { |
| 181 | + requestFeedback({ |
| 182 | + flagKey: 'my-feature', |
| 183 | + title: 'How was your experience?', |
| 184 | + prompt: 'Please let us know how we can improve this feature.' |
| 185 | + }); |
| 186 | + } |
| 187 | +</script> |
| 188 | +
|
| 189 | +<button on:click={askForFeedback}>Give Feedback</button> |
| 190 | +``` |
| 191 | + |
| 192 | +#### `useSendFeedback()` |
| 193 | + |
| 194 | +Returns a function to send feedback programmatically. |
| 195 | + |
| 196 | +#### `useUpdateUser()`, `useUpdateCompany()`, `useUpdateOtherContext()` |
| 197 | + |
| 198 | +Return functions to update context information, which will trigger flag re-evaluation. |
| 199 | + |
| 200 | +**Example:** |
| 201 | +```svelte |
| 202 | +<script lang="ts"> |
| 203 | + import { useUpdateUser } from '@reflag/svelte-sdk'; |
| 204 | + |
| 205 | + const updateUser = useUpdateUser(); |
| 206 | + |
| 207 | + function upgradeUser() { |
| 208 | + updateUser({ plan: 'premium' }); |
| 209 | + } |
| 210 | +</script> |
| 211 | +
|
| 212 | +<button on:click={upgradeUser}>Upgrade to Premium</button> |
| 213 | +``` |
| 214 | + |
| 215 | +## TypeScript Support |
| 216 | + |
| 217 | +The SDK includes full TypeScript support. You can extend the `Flags` interface to get type-safe flag keys: |
| 218 | + |
| 219 | +```typescript |
| 220 | +// types/reflag.d.ts |
| 221 | +declare module '@reflag/svelte-sdk' { |
| 222 | + interface Flags { |
| 223 | + 'huddle': { |
| 224 | + config: { |
| 225 | + payload: { |
| 226 | + buttonText: string; |
| 227 | + maxParticipants: number; |
| 228 | + }; |
| 229 | + }; |
| 230 | + }; |
| 231 | + 'file-uploads': { |
| 232 | + config: { |
| 233 | + payload: { |
| 234 | + maxFileSize: number; |
| 235 | + allowedTypes: string[]; |
| 236 | + }; |
| 237 | + }; |
| 238 | + }; |
| 239 | + } |
| 240 | +} |
| 241 | +``` |
| 242 | + |
| 243 | +Now you'll get full type safety: |
| 244 | + |
| 245 | +```svelte |
| 246 | +<script lang="ts"> |
| 247 | + import { useFlag } from '@reflag/svelte-sdk'; |
| 248 | + |
| 249 | + // TypeScript knows this returns the correct type |
| 250 | + const huddle = useFlag('huddle'); |
| 251 | + |
| 252 | + // TypeScript knows config.payload has buttonText and maxParticipants |
| 253 | + $: buttonText = $huddle.config.payload?.buttonText || 'Start Huddle'; |
| 254 | +</script> |
| 255 | +``` |
| 256 | + |
| 257 | +## Error Handling |
| 258 | + |
| 259 | +The SDK will throw an error if you try to use any of the utilities without first calling `createReflagProvider()`: |
| 260 | + |
| 261 | +```javascript |
| 262 | +// This will throw an error |
| 263 | +const flag = useFlag('my-flag'); // Error: ReflagProvider is missing |
| 264 | +``` |
| 265 | + |
| 266 | +Make sure to call `createReflagProvider()` before using any other SDK functions. |
| 267 | + |
| 268 | +## Development |
| 269 | + |
| 270 | +To run the development example: |
| 271 | + |
| 272 | +```bash |
| 273 | +cd packages/svelte-sdk |
| 274 | +yarn dev |
| 275 | +``` |
| 276 | + |
| 277 | +This will start a development server with a demo application showing the SDK in action. |
| 278 | + |
| 279 | +## Testing |
| 280 | + |
| 281 | +```bash |
| 282 | +yarn test |
| 283 | +``` |
| 284 | + |
| 285 | +## Building |
| 286 | + |
| 287 | +```bash |
| 288 | +yarn build |
| 289 | +``` |
| 290 | + |
| 291 | +## License |
| 292 | + |
| 293 | +MIT |
0 commit comments