Skip to content

Commit 0b51885

Browse files
nosnibor89robinson-mdRobinson Marquez
authored
feat: add svelte example project and improving SDK docs (#722)
**Requirements** - [x] I have added test coverage for new or changed functionality (no behavior change is mostly example project and docs) - [x] I have followed the repository's [pull request submission guidelines](../blob/main/CONTRIBUTING.md#submitting-pull-requests) - [x] I have validated my changes against all supported platform versions **Related issues** No issue. **Describe the solution you've provided** This pull request introduces a new Svelte example project to demonstrate the usage of `@launchdarkly/svelte-client-sdk`. The README of the example project includes steps to run such application that internally uses the SDK to interact with a boolean flag. Also, this PR adds documentation for `@launchdarkly/svelte-client-sdk` itself with a "Getting Started" session along with more advanced use of the SDK's api. **Describe alternatives you've considered** I don't know what to write here. **Additional context** This is a follow up PR for #632. Where Svelte SDK was introduced. After this, follow up PR for technical debt(upgrade Svelte 5 and improving test coverage ) should be expected --------- Co-authored-by: Robinson Marquez <[email protected]> Co-authored-by: Robinson Marquez <[email protected]>
1 parent c985daa commit 0b51885

File tree

21 files changed

+415
-3
lines changed

21 files changed

+415
-3
lines changed

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
"packages/sdk/react-universal/example",
1818
"packages/sdk/vercel",
1919
"packages/sdk/svelte",
20+
"packages/sdk/svelte/example",
2021
"packages/sdk/akamai-base",
2122
"packages/sdk/akamai-base/example",
2223
"packages/sdk/akamai-edgekv",

packages/sdk/svelte/README.md

Lines changed: 131 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,131 @@
1+
# Launch Darkly Svelte SDK
2+
3+
This is a Svelte library for Launch Darkly. It is a wrapper around the official Launch Darkly JavaScript SDK but with a Svelte-friendly API.
4+
5+
## Table of Contents
6+
7+
- [Getting Started](#getting-started)
8+
- [Advanced Usage](#advanced-usage)
9+
- [Changing user context](#changing-user-context)
10+
- [Getting feature flag values](#getting-feature-flag-values)
11+
- [Getting immediate flag value](#getting-immediate-flag-value)
12+
- [Watching flag value changes](#watching-flag-value-changes)
13+
- [Getting all flag values](#getting-all-flag-values)
14+
15+
## Getting started
16+
17+
First, install the package:
18+
19+
```bash
20+
npm install @launchdarkly/svelte-client-sdk # or use yarn or pnpm
21+
```
22+
23+
Then, initialize the SDK with your client-side ID using the `LDProvider` component:
24+
25+
```svelte
26+
<script>
27+
import { LDProvider } from '@launchdarkly/svelte-client-sdk';
28+
import App from './App.svelte';
29+
</script>
30+
31+
// Use context relevant to your application
32+
const context = {
33+
user: {
34+
key: 'user-key',
35+
},
36+
};
37+
38+
<LDProvider clientID="your-client-side-id" {context}>
39+
<App />
40+
</LDProvider>
41+
```
42+
43+
Now you can use the `LDFlag` component to conditionally render content based on feature flags:
44+
45+
```svelte
46+
<script>
47+
import { LDFlag } from '@launchdarkly/svelte-client-sdk';
48+
</script>
49+
50+
<LDFlag flag={'my-feature-flag'}>
51+
<div slot="on">
52+
<p>this will render if the feature flag is on</p>
53+
</div>
54+
<div slot="off">
55+
<p>this will render if the feature flag is off</p>
56+
</div>
57+
</LDFlag>
58+
```
59+
60+
## Advanced usage
61+
62+
### Changing user context
63+
64+
You can change the user context by using the `identify` function from the `LD` object:
65+
66+
```svelte
67+
<script>
68+
import { LD } from '@launchdarkly/svelte-client-sdk';
69+
70+
function handleLogin() {
71+
LD.identify({ key: 'new-user-key' });
72+
}
73+
</script>
74+
75+
<button on:click={handleLogin}>Login</button>
76+
```
77+
78+
### Getting feature flag values
79+
80+
#### Getting immediate flag value
81+
82+
If you need to get the value of a flag at time of evaluation you can use the `useFlag` function:
83+
84+
```svelte
85+
<script>
86+
import { LD } from '@launchdarkly/svelte-client-sdk';
87+
88+
function handleClick() {
89+
const isFeatureFlagOn = LD.useFlag('my-feature-flag', false);
90+
console.log(isFeatureFlagOn);
91+
}
92+
</script>
93+
94+
<button on:click={handleClick}>Check flag value</button>
95+
```
96+
97+
**Note:** Please note that `useFlag` function will return the current value of the flag at the time of evaluation, which means you won't get notified if the flag value changes. This is useful for cases where you need to get the value of a flag at a specific time like a function call. If you need to get notified when the flag value changes, you should use the `LDFlag` component, the `watch` function or the `flags` object depending on your use case.
98+
99+
#### Watching flag value changes
100+
101+
If you need to get notified when a flag value changes you can use the `watch` function. The `watch` function is an instance of [Svelte Store](https://svelte.dev/docs/svelte-store), which means you can use it with the `$` store subscriber syntax or the `subscribe` method. Here is an example of how to use the `watch` function:
102+
103+
```svelte
104+
<script>
105+
import { LD } from '@launchdarkly/svelte-client-sdk';
106+
107+
$: flagValue = LD.watch('my-feature-flag');
108+
</script>
109+
110+
<p>{$flagValue}</p>
111+
```
112+
113+
#### Getting all flag values
114+
115+
If you need to get all flag values you can use the `flags` object. The `flags` object is an instance of [Svelte Store](https://svelte.dev/docs/svelte-store), which means you can use it with the `$` store subscriber syntax or the `subscribe` method. Here is an example of how to use the `flags` object:
116+
117+
```svelte
118+
<script>
119+
import { LD } from '@launchdarkly/svelte-client-sdk';
120+
121+
$: allFlags = LD.flags;
122+
</script>
123+
124+
{#each Object.keys($allFlags) as flagName}
125+
<p>{flagName}: {$allFlags[flagName]}</p>
126+
{/each}
127+
```
128+
129+
## Credits
130+
131+
- Original code by [Robinson Marquez](https://github.com/nosnibor89)
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
.DS_Store
2+
node_modules
3+
/build
4+
/.svelte-kit
5+
/package
6+
.env
7+
.env.*
8+
!.env.example
9+
10+
# Ignore files for PNPM, NPM and YARN
11+
pnpm-lock.yaml
12+
package-lock.json
13+
yarn.lock
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
/** @type { import("eslint").Linter.Config } */
2+
module.exports = {
3+
root: true,
4+
extends: [
5+
'eslint:recommended',
6+
'plugin:@typescript-eslint/recommended',
7+
'plugin:svelte/recommended',
8+
'prettier'
9+
],
10+
parser: '@typescript-eslint/parser',
11+
plugins: ['@typescript-eslint'],
12+
parserOptions: {
13+
sourceType: 'module',
14+
ecmaVersion: 2020,
15+
extraFileExtensions: ['.svelte']
16+
},
17+
env: {
18+
browser: true,
19+
es2017: true,
20+
node: true
21+
},
22+
overrides: [
23+
{
24+
files: ['*.svelte'],
25+
parser: 'svelte-eslint-parser',
26+
parserOptions: {
27+
parser: '@typescript-eslint/parser'
28+
}
29+
}
30+
]
31+
};
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
.DS_Store
2+
node_modules
3+
/build
4+
/dist
5+
/.svelte-kit
6+
/package
7+
.env
8+
.env.*
9+
!.env.example
10+
vite.config.js.timestamp-*
11+
vite.config.ts.timestamp-*

packages/sdk/svelte/example/.npmrc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
engine-strict=true
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
# Ignore files for PNPM, NPM and YARN
2+
pnpm-lock.yaml
3+
package-lock.json
4+
yarn.lock
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
{
2+
"useTabs": true,
3+
"singleQuote": true,
4+
"trailingComma": "none",
5+
"printWidth": 100,
6+
"plugins": ["prettier-plugin-svelte"],
7+
"overrides": [{ "files": "*.svelte", "options": { "parser": "svelte" } }]
8+
}
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
# LaunchDarkly Svelte SDK Example
2+
3+
This project demonstrates the usage of the `@launchdarkly/svelte-client-sdk`. It showcases how to conditionally render content based on feature flags using the `LDFlag` component.
4+
5+
## Installing Dependencies and Setting Environment Variables
6+
7+
First, install the project dependencies:
8+
9+
```bash
10+
yarn install
11+
```
12+
13+
Next, create a `.env` file in the root of the project and add your LaunchDarkly client-side ID and flag key. You can obtain these from any LaunchDarkly project/environment you choose.
14+
15+
```bash
16+
PUBLIC_LD_CLIENT_ID=your-client-side-id
17+
PUBLIC_LD_FLAG_KEY=your-flag-key
18+
```
19+
20+
Note: The flag specified by `PUBLIC_LD_FLAG_KEY` must be a boolean flag.
21+
22+
## Running the Project
23+
24+
To run the project, use the following command:
25+
26+
```bash
27+
yarn dev
28+
```
29+
30+
This will start the development server. Open your browser and navigate to the provided URL to see the example in action. The box will change its background color based on the value of the feature flag specified by `PUBLIC_LD_FLAG_KEY`.
31+
32+
### Role of `LDProvider`
33+
34+
The `LDProvider` component is used to initialize the LaunchDarkly client and provide the feature flag context to the rest of the application. It requires a `clientID` and a `context` object. The `context` object typically contains information about the user or environment, which LaunchDarkly uses to determine the state of feature flags.
35+
36+
In this example, the `LDProvider` wraps the entire application, ensuring that all child components have access to the feature flag data. The `slot="initializing"` is used to display a loading message while the flags are being fetched.
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
{
2+
"name": "ld-svelte-example",
3+
"version": "0.0.1",
4+
"scripts": {
5+
"dev": "vite dev",
6+
"build": "vite build",
7+
"preview": "vite preview"
8+
},
9+
"exports": {
10+
".": {
11+
"types": "./dist/index.d.ts",
12+
"svelte": "./dist/index.js",
13+
"default": "./dist/index.js"
14+
}
15+
},
16+
"files": [
17+
"dist",
18+
"!dist/**/*.test.*",
19+
"!dist/**/*.spec.*"
20+
],
21+
"svelte": "./dist/index.js",
22+
"types": "./dist/index.d.ts",
23+
"type": "module",
24+
"dependencies": {
25+
"@launchdarkly/svelte-client-sdk": "workspace:^",
26+
"esm-env": "^1.0.0",
27+
"svelte": "^5.4.0"
28+
},
29+
"devDependencies": {
30+
"@sveltejs/adapter-auto": "^3.0.0",
31+
"@sveltejs/kit": "^2.0.0",
32+
"@sveltejs/package": "^2.0.0",
33+
"@sveltejs/vite-plugin-svelte": "^5.0.1",
34+
"@types/eslint": "8.56.0",
35+
"@typescript-eslint/eslint-plugin": "^6.0.0",
36+
"@typescript-eslint/parser": "^6.0.0",
37+
"eslint": "^8.56.0",
38+
"eslint-config-prettier": "^9.1.0",
39+
"eslint-plugin-svelte": "^2.35.1",
40+
"jsdom": "^24.0.0",
41+
"prettier": "^3.1.1",
42+
"prettier-plugin-svelte": "^3.1.2",
43+
"svelte-check": "^3.6.0",
44+
"tslib": "^2.4.1",
45+
"typescript": "^5.0.0",
46+
"vite": "^6.0.2",
47+
"vitest": "^2.1.8"
48+
}
49+
}

0 commit comments

Comments
 (0)