Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,12 @@ import RubyImport from "!!raw-loader!./ruby/import.rb";

import FlutterImport from "!!raw-loader!./flutter/import.dart";

import DartImport from "!!raw-loader!./dart/import.dart";

import RustImport from "!!raw-loader!./rust/initialize.rs";

import LiquidImport from "!!raw-loader!./liquid/initialize.liquid";

Once the SDK is installed, it can be initialized in your project.

:::info
Expand Down Expand Up @@ -102,9 +108,9 @@ directly into the Provider component, like so:

```jsx
ReactDOM.render(
<ABSmartly context={context}>
<ABsmartly context={context}>
<App />
</ABSmartly>,
</ABsmartly>,
document.getElementById("root")
);
```
Expand Down Expand Up @@ -367,18 +373,170 @@ custom event logger), it can be done as following:

</TabItem>

<TabItem value="flutter" label="Flutter/Dart">
<TabItem value="dart" label="Dart">

<CodeBlock language="dart">{DartImport}</CodeBlock>

**SDK Options**

| Config | Type | Required? | Default | Description |
| :---------------------- | :-------------------------------- | :-------: | :---------: | :---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| endpoint | `String` | &#9989; | `null` | The URL to your API endpoint. Most commonly `"your-company.absmartly.io"` |
| apiKey | `String` | &#9989; | `null` | Your API key which can be found on the Web Console. |
| environment | `String` | &#9989; | `null` | The environment of the platform where the SDK is installed. Environments are created on the Web Console and should match the available environments in your infrastructure. |
| application | `String` | &#9989; | `null` | The name of the application where the SDK is installed. Applications are created on the Web Console and should match the applications where your experiments will be running. |
| retries | `int` | &#10060; | `5` | The number of retries before the SDK stops trying to connect. |
| timeout | `int` | &#10060; | `3000` | An amount of time, in milliseconds, before the SDK will stop trying to connect. |
| contextEventLogger | `ContextEventLogger` | &#10060; | `null` | A callback interface which runs after SDK events. See [Using a Custom Event Logger](#using-a-custom-event-logger) below |

**Advanced Configuration**

For advanced use cases where you need custom HTTP clients or data providers, you can still use the manual configuration approach:

```dart
final clientConfig = ClientConfig()
..setEndpoint("https://your-company.absmartly.io/v1")
..setAPIKey("YOUR-API-KEY")
..setApplication("website")
..setEnvironment("development");

final httpClientConfig = DefaultHTTPClientConfig()
..setMaxRetries(3)
..setConnectTimeout(5000);

final client = Client.create(
clientConfig,
httpClient: DefaultHTTPClient.create(httpClientConfig),
);

final sdkConfig = ABsmartlyConfig.create()
..setClient(client);

final sdk = ABsmartly(sdkConfig);
```

</TabItem>

<TabItem value="flutter" label="Flutter">

<CodeBlock language="dart">{FlutterImport}</CodeBlock>

**SDK Options**

| Config | Type | Required? | Default | Description |
| :---------- | :-------------------------------- | :-------: | :---------: | :---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| endpoint | `string` | &#9989; | `undefined` | The URL to your API endpoint. Most commonly `"your-company.absmartly.io"` |
| apiKey | `string` | &#9989; | `undefined` | Your API key which can be found on the Web Console. |
| environment | `"production"` or `"development"` | &#9989; | `undefined` | The environment of the platform where the SDK is installed. Environments are created on the Web Console and should match the available environments in your infrastructure. |
| application | `string` | &#9989; | `undefined` | The name of the application where the SDK is installed. Applications are created on the Web Console and should match the applications where your experiments will be running. |
| Config | Type | Required? | Default | Description |
| :---------------------- | :-------------------------------- | :-------: | :---------: | :---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| endpoint | `String` | &#9989; | `null` | The URL to your API endpoint. Most commonly `"your-company.absmartly.io"` |
| apiKey | `String` | &#9989; | `null` | Your API key which can be found on the Web Console. |
| environment | `String` | &#9989; | `null` | The environment of the platform where the SDK is installed. Environments are created on the Web Console and should match the available environments in your infrastructure. |
| application | `String` | &#9989; | `null` | The name of the application where the SDK is installed. Applications are created on the Web Console and should match the applications where your experiments will be running. |
| retries | `int` | &#10060; | `5` | The number of retries before the SDK stops trying to connect. |
| timeout | `int` | &#10060; | `3000` | An amount of time, in milliseconds, before the SDK will stop trying to connect. |
| contextEventLogger | `ContextEventLogger` | &#10060; | `null` | A callback interface which runs after SDK events. See [Using a Custom Event Logger](#using-a-custom-event-logger) below |

**Advanced Configuration**

For advanced use cases where you need custom HTTP clients or data providers, you can still use the manual configuration approach:

```dart
final clientConfig = ClientConfig()
..setEndpoint("https://your-company.absmartly.io/v1")
..setAPIKey("YOUR-API-KEY")
..setApplication("website")
..setEnvironment("development");

final httpClientConfig = DefaultHTTPClientConfig()
..setMaxRetries(3)
..setConnectTimeout(5000);

final client = Client.create(
clientConfig,
httpClient: DefaultHTTPClient.create(httpClientConfig),
);

final sdkConfig = ABsmartlyConfig.create()
..setClient(client);

final sdk = ABsmartly(sdkConfig);
```

</TabItem>

<TabItem value="rust" label="Rust">

<CodeBlock language="rust">{RustImport}</CodeBlock>

**SDK Options**

| Config | Type | Required? | Default | Description |
| :---------- | :----------------------------------- | :-------: | :-------------------------------------------------------------------: | :---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| endpoint | `&str` or `String` | &#9989; | `undefined` | The URL to your API endpoint. Most commonly `"your-company.absmartly.io"` |
| api_key | `&str` or `String` | &#9989; | `undefined` | Your API key which can be found on the Web Console. |
| environment | `&str` or `String` | &#9989; | `undefined` | The environment of the platform where the SDK is installed. Environments are created on the Web Console and should match the available environments in your infrastructure. |
| application | `&str` or `String` | &#9989; | `undefined` | The name of the application where the SDK is installed. Applications are created on the Web Console and should match the applications where your experiments will be running. |
| retries | `u32` | &#10060; | `5` | The number of retries before the SDK stops trying to connect. |
| timeout_ms | `u64` | &#10060; | `3000` | An amount of time, in milliseconds, before the SDK will stop trying to connect. |
| agent | `String` | &#10060; | `None` | Custom user agent string for HTTP requests. |

**Builder Pattern**

The Rust SDK supports a fluent builder pattern for optional configuration:

```rust
let config = SDKConfig::new(
"https://your-company.absmartly.io/v1",
"YOUR-API-KEY",
"website",
"development",
)
.with_timeout(5000)
.with_retries(3)
.with_agent("my-app/1.0");

let sdk = ABsmartly::new(config)?;
```

</TabItem>

<TabItem value="liquid" label="Liquid (Shopify)">

<CodeBlock language="liquid">{LiquidImport}</CodeBlock>

**SDK Options**

| Config | Type | Required? | Default | Description |
| :---------- | :----------------------------------- | :-------: | :-------------------------------------------------------------------: | :---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| endpoint | `string` | &#9989; | `undefined` | The URL to your API endpoint. Most commonly `"your-company.absmartly.io"` |
| apiKey | `string` | &#9989; | `undefined` | Your API key which can be found on the Web Console. |
| environment | `"production"` or `"development"` | &#9989; | `undefined` | The environment of the platform where the SDK is installed. Environments are created on the Web Console and should match the available environments in your infrastructure. |
| application | `string` | &#9989; | `undefined` | The name of the application where the SDK is installed. Applications are created on the Web Console and should match the applications where your experiments will be running. |
| units | `object` | &#9989; | `{}` | An object containing unit identifiers (e.g., session_id, customer_id) used for experiment assignment. |

**Server-Side Rendering**

For Shopify Liquid templates, ABsmartly can be integrated server-side to pre-fetch context data:

```liquid
{% comment %}
Render the ABsmartly initialization snippet
This can be used to embed pre-fetched context data
{% endcomment %}
{% render 'absmartly-init',
session_id: request.cookie.session_id,
customer_id: customer.id
%}
```

**Using ABsmartly in Templates**

Once initialized, you can use ABsmartly treatments in your Liquid templates:

```liquid
{% if absmartly.treatment.banner_color == 1 %}
<div class="banner banner-red">Special Offer!</div>
{% else %}
<div class="banner banner-blue">Special Offer!</div>
{% endif %}
```

</TabItem>

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import 'package:absmartly_sdk/absmartly_sdk.dart';

void main() async {
final sdk = ABsmartly.create(
endpoint: 'https://your-company.absmartly.io/v1',
apiKey: 'YOUR-API-KEY',
application: 'website',
environment: 'development',
);
}
Original file line number Diff line number Diff line change
@@ -1,11 +1,8 @@
void main() async{
final ClientConfig clientConfig = ClientConfig()
..setEndpoint("https://your-company.absmartly.io/v1")
..setAPIKey("YOUR API KEY")
..setApplication("website")
..setEnvironment("development");

final ABSmartlyConfig sdkConfig = ABSmartlyConfig.create()
.setClient(Client.create(clientConfig));
final ABSmartly sdk = ABSmartly(sdkConfig);
void main() async {
final sdk = ABsmartly.create(
endpoint: 'https://your-company.absmartly.io/v1',
apiKey: 'YOUR-API-KEY',
application: 'website',
environment: 'development',
);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
{% comment %}
Initialize the ABsmartly SDK in your Shopify theme
Add this to your theme.liquid layout file, typically in the <head> section
{% endcomment %}

<script>
window.absmartlyConfig = {
endpoint: 'https://your-company.absmartly.io/v1',
apiKey: 'YOUR-API-KEY',
application: '{{ shop.name }}',
environment: 'production',
units: {
session_id: '{{ request.cookie.session_id }}',
{% if customer %}customer_id: {{ customer.id }}{% endif %}
}
};
Comment on lines +6 to +16
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Escape Liquid output to keep JS valid and avoid injection.
shop.name, request.cookie.session_id, and customer.id are interpolated without JSON encoding; quotes or special characters can break the script or introduce XSS. Use the json filter to safely serialise values.

Proposed fix
-  window.absmartlyConfig = {
-    endpoint: 'https://your-company.absmartly.io/v1',
-    apiKey: 'YOUR-API-KEY',
-    application: '{{ shop.name }}',
-    environment: 'production',
-    units: {
-      session_id: '{{ request.cookie.session_id }}',
-      {% if customer %}customer_id: {{ customer.id }}{% endif %}
-    }
-  };
+  window.absmartlyConfig = {
+    endpoint: 'https://your-company.absmartly.io/v1',
+    apiKey: 'YOUR-API-KEY',
+    application: {{ shop.name | json }},
+    environment: 'production',
+    units: {
+      session_id: {{ request.cookie.session_id | json }}{% if customer %},
+      customer_id: {{ customer.id | json }}{% endif %}
+    }
+  };
🤖 Prompt for AI Agents
In
`@docs/APIs-and-SDKs/SDK-Documentation/getting-started/import-and-initialize/liquid/initialize.liquid`
around lines 6 - 16, The Liquid template embeds unescaped values into
window.absmartlyConfig (application, units.session_id, units.customer_id) which
can break JS or enable XSS; update the template to JSON-encode those
interpolations using the Liquid json filter (e.g. application: {{ shop.name |
json }}, session_id: {{ request.cookie.session_id | json }}, and customer_id: {{
customer.id | json }}) so the values are safely serialized for inclusion in the
script.

</script>

{% comment %}
Include the ABsmartly client-side SDK
This should be loaded before any code that uses the ABsmartly context
{% endcomment %}
<script src="https://cdn.absmartly.com/absmartly.min.js"></script>

<script>
ABSmartly.createContext(window.absmartlyConfig).then(function(context) {
window.absmartlyContext = context;
});
</script>
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
Absmartly.configure_client do |config|
ABsmartly.configure_client do |config|
config.endpoint = "https://your-company.absmartly.io/v1"
config.api_key = "YOUR-API-KEY"
config.application = "website"
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
use absmartly_sdk::{ABsmartly, SDKConfig};

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let config = SDKConfig::new(
"https://your-company.absmartly.io/v1",
"YOUR-API-KEY",
"website",
"development",
);

let sdk = ABsmartly::new(config)?;

Ok(())
}