Skip to content

Commit

Permalink
chore: add Split URL script tag for Web Experimentation (#103)
Browse files Browse the repository at this point in the history
  • Loading branch information
tyiuhc authored Apr 16, 2024
1 parent f34696c commit 9bf433b
Show file tree
Hide file tree
Showing 21 changed files with 1,751 additions and 7 deletions.
1 change: 1 addition & 0 deletions .eslintignore
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
dist/
example/
5 changes: 4 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -23,4 +23,7 @@ dist/
.idea

# For CI to ignore .npmrc file when publishing
.npmrc
.npmrc

# Example Experiment tag script example
packages/experiment-tag/example/
1 change: 1 addition & 0 deletions .prettierignore
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
dist/
example/
*.md
16 changes: 16 additions & 0 deletions packages/experiment-tag/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
# Experiment Web Experimentation Javascript Snippet

## Overview

This is the Web Experimentation SDK for Amplitude Experiment. Currently, only split-URL experiments are supported.

## Generate example

To generate an example snippet with custom flag configurations:
1. Set `apiKey` (your Amplitude Project API key) and `initialFlags` in `example/build_example.js`
2. Run `yarn build` to build minified UMD `experiment-tag.umd.js` and example `script.js`

To test the snippet's behavior on web pages relevant to your experiment, the pages should:
1. Include `script.js`
2. Have the Amplitude Analytics SDK loaded (see [examples](https://github.com/amplitude/Amplitude-TypeScript/tree/main/packages/analytics-browser))

79 changes: 79 additions & 0 deletions packages/experiment-tag/example/build_example.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
const fs = require('fs');
const apiKey = 'a6dd847b9d2f03c816d4f3f8458cdc1d';
const initialFlags = `[
{
"key": "test",
"metadata": {
"deployed": true,
"evaluationMode": "local",
"experimentKey": "exp-1",
"flagType": "experiment",
"flagVersion": 20,
"urlMatch": [
"http://localhost:63342/experiment-js-client/packages/experiment-tag/example/control.html/"
]
},
"segments": [
{
"metadata": {
"segmentName": "All Other Users"
},
"variant": "treatment"
}
],
"variants": {
"control": {
"key": "control",
"payload": [
{
"action": "redirect",
"data": {
"url": "http://localhost:63342/experiment-js-client/packages/experiment-tag/example/control.html"
}
}
],
"value": "control"
},
"off": {
"key": "off",
"metadata": {
"default": true
}
},
"treatment": {
"key": "treatment",
"payload": [
{
"action": "redirect",
"data": {
"url": "http://localhost:63342/experiment-js-client/packages/experiment-tag/example/treatment.html"
}
}
],
"value": "treatment"
}
}
}
]
`.replace(/\n\s*/g, '');

fs.readFile('dist/experiment-tag.umd.js', 'utf8', (err, data) => {
if (err) {
console.error('Error reading file:', err);
return;
}

// Perform string replacements
const modifiedData = data
.replace(/{{DEPLOYMENT_KEY}}/g, apiKey)
.replace(/"{{INITIAL_FLAGS}}"/g, `'${initialFlags}'`);

// Write the modified content to a new file
fs.writeFile('example/script.js', modifiedData, 'utf8', (err) => {
if (err) {
console.error('Error writing file:', err);
return;
}
console.log('File successfully written!');
});
});
47 changes: 47 additions & 0 deletions packages/experiment-tag/example/control.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
<!doctype html>
<html class="no-js" lang="">

<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Original page</title>
<link rel="stylesheet" href="./css/recipe-styles.css">
<script src="script.js"></script>
<script type="text/javascript">
!function(){"use strict";!function(e,t){var r=e.amplitude||{_q:[],_iq:{}};if(r.invoked)e.console&&console.error&&console.error("Amplitude snippet has been loaded.");else{var n=function(e,t){e.prototype[t]=function(){return this._q.push({name:t,args:Array.prototype.slice.call(arguments,0)}),this}},s=function(e,t,r){return function(n){e._q.push({name:t,args:Array.prototype.slice.call(r,0),resolve:n})}},o=function(e,t,r){e._q.push({name:t,args:Array.prototype.slice.call(r,0)})},i=function(e,t,r){e[t]=function(){if(r)return{promise:new Promise(s(e,t,Array.prototype.slice.call(arguments)))};o(e,t,Array.prototype.slice.call(arguments))}},a=function(e){for(var t=0;t<g.length;t++)i(e,g[t],!1);for(var r=0;r<m.length;r++)i(e,m[r],!0)};r.invoked=!0;var c=t.createElement("script");c.type="text/javascript",c.integrity="sha384-wV43EzMsYAnBGrsHb4VUxdN6tB8JXGy0aKDBTy82bYrpd1/hIEkpPFqkzEAkLz8X",c.crossOrigin="anonymous",c.async=!0,c.src="https://cdn.amplitude.com/libs/analytics-browser-2.5.3-min.js.gz",c.onload=function(){e.amplitude.runQueuedFunctions||console.log("[Amplitude] Error: could not load SDK")};var u=t.getElementsByTagName("script")[0];u.parentNode.insertBefore(c,u);for(var p=function(){return this._q=[],this},l=["add","append","clearAll","prepend","set","setOnce","unset","preInsert","postInsert","remove","getUserProperties"],d=0;d<l.length;d++)n(p,l[d]);r.Identify=p;for(var f=function(){return this._q=[],this},v=["getEventProperties","setProductId","setQuantity","setPrice","setRevenue","setRevenueType","setEventProperties"],y=0;y<v.length;y++)n(f,v[y]);r.Revenue=f;var g=["getDeviceId","setDeviceId","getSessionId","setSessionId","getUserId","setUserId","setOptOut","setTransport","reset","extendSession"],m=["init","add","remove","track","logEvent","identify","groupIdentify","setGroup","revenue","flush"];a(r),r.createInstance=function(e){return r._iq[e]={_q:[]},a(r._iq[e]),r._iq[e]},e.amplitude=r}}(window,document)}();
amplitude.init('a6dd847b9d2f03c816d4f3f8458cdc1d')
</script>
</head>
<body>
<article>
<header>
<h1>Original page</h1>
</header>
<section class="ingredients">
<h2>Ingredients</h2>
<ul>
<li>1 cup softened butter</li>
<li>1 cup white sugar</li>
<li>2 cups all-purpose flour</li>
<!-- More ingredients -->
</ul>
</section>
<section class="instructions">
<h2>Instructions</h2>
<ol>
<li>Preheat oven to 350 degrees F (175 degrees C).</li>
<li>Cream together the butter, white sugar,
and brown sugar until smooth.
</li>
<li>Beat in the eggs one at a time,
then stir in the vanilla.
</li>
<!-- More steps -->
</ol>
</section>
</article>
<footer>
<p>Recipe by Grandma's Cookbook</p>
</footer>
</body>
</html>
47 changes: 47 additions & 0 deletions packages/experiment-tag/example/css/recipe-styles.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
/* Basic Reset */
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}

body {
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
line-height: 1.6;
padding: 20px;
background-color: #fff9e8;
}

article {
max-width: 800px;
margin: 20px auto;
padding: 20px;
background: #fff;
border: 1px solid #ddd;
border-radius: 8px;
}

h1, h2 {
color: #5a2c02;
}

.recipe-img {
max-width: 100%;
height: auto;
border-radius: 8px;
}

.ingredients ul, .instructions ol {
margin: 20px 0;
}

.ingredients li, .instructions li {
margin-bottom: 10px;
}

footer {
text-align: center;
margin-top: 20px;
padding-top: 20px;
border-top: 1px solid #ddd;
}
Loading

0 comments on commit 9bf433b

Please sign in to comment.