Security News
PyPI Introduces Digital Attestations to Strengthen Python Package Security
PyPI now supports digital attestations, enhancing security and trust by allowing package maintainers to verify the authenticity of Python packages.
@s-ui/abtesting-optimizely-x
Advanced tools
A React component that renders one single variation according to OptimizelyX's experiment decision.
<OptimizelyExperiment experimentId={100}>
<button variationId={1001} defaultVariation>Original</button>
<button variationId={1002}>Variation #1</button>
<button variationId={1003}>Variation #2</button>
</OptimizelyExperiment>
npm install @s-ui/abtesting-optimizely-x --save
Navigate to: https://app.optimizely.com/v2/ > Edit Experiment > API Names
import OptimizelyXExperiment from '@s-ui/abtesting-optimizely-x'
<OptimizelyXExperiment experimentId={8470306415}>
<button variationId={8463707014} defaultVariation>Original</button>
<button variationId={8480321136}>Variation #1</button>
<button variationId={8462843355}>Variation #2</button>
<button variationId={8468413552}>Variation #3</button>
</OptimizelyXExperiment>
Component will obtain OptimizelyX's decision for given experimentId
and display chosen variation.
If no variation is provided or OptimizelyX API is unavailable, defaultVariation
will be displayed.
If you need to use an empty variation, do not use <Fragment>
component as you will get a lot of warning messages in the console. Instead, use the <EmptyVariation>
component and pass by the experiment's props.
import OptimizelyXExperiment, {EmptyVariation} from '@s-ui/abtesting-optimizely-x'
<OptimizelyXExperiment experimentId={8470306415}>
<EmptyVariation variationId={8463707014} defaultVariation />
<button variationId={8480321136}>Variation #1</button>
</OptimizelyXExperiment>
The following data is set in a plain object to the experiment context.
8470306415
.true
when a decision has been made by optimizely.true
when the chosen variation is the default one.true
when the chosen variation is not the default one.true
when the chosen variation is A.true
when the chosen variation is B.true
when the chosen variation is N.true
when the current component has OptimizelyXExperiment as a parent (direct or not).8463707014
.A
(more about this below).So for a given experiment:
<OptimizelyXExperiment name="myexperiment" experimentId={8470306415}>
<NiceComponent variationId={8463707014} defaultVariation />
<NiceComponent variationId={8480321136} />
</OptimizelyXExperiment>
The experiment context can be consumed at any child level by using the useExperiment
hook:
import {useExperiment} from '@s-ui/abtesting-hooks'
const NiceComponent = () => {
const {isActive, isDefault, isVariation, ...} = useExperiment('myexperiment')
}
IMPORTANT: Note the 'myexperiment'
value passed to name
prop of the component which is also used as an argument in useExperiment
consumer. This is the way for the package to keep a unique internal context instance per experiment in order to avoid undesired overridings when multiple experiment contexts live within the same hierarchy scope. So if you want multiple experiment contexts to coexist just pick different names for them and you will be ok.
You may need to check which variation has been chosen down in the children, specially when the experiment has 3 or more possible variations. For the sake of simplicity, OptimizelyXExperiment will automatically assign an uppercase letter for each variation based on the order of children, but you could override it by using variationName
prop directly into a variation.
<OptimizelyXExperiment name="myexperiment" experimentId={8470306415}>
<TestedComponent variationId={8463707014} defaultVariation />
<TestedComponent variationId={8480321136} />
<TestedComponent variationId={8462843355} variationName="maneko" />
<TestedComponent variationId={8468413552} />
</OptimizelyXExperiment>
Considering the above example, if we look into TestedComponent we can access the chosen variationName
from the experiment context through the useExperiment
hook:
import {useExperiment} from '@s-ui/abtesting-hooks'
const TestedComponent = () => {
const {variationName} = useExperiment('myexperiment')
// if 1st variation is chosen: variationName → "A"
// if 2nd variation is chosen: variationName → "B"
// if 3rd variation is chosen: variationName → "maneko" (overriden)
// if 4th variation is chosen: variationName → "D"
// ...
// if Nth variation is chosen: variationName → Nth letter in alphabet
console.log(variationName)
}
Also, boolean keys are provided for simplicity:
import {useExperiment} from '@s-ui/abtesting-hooks'
const TestedComponent = () => {
const {
isVariationA,
isVariationB,
isVariationManeko,
isVariationD
} = useExperiment('myexperiment')
// consider 'B' variation is chosen by optimizely, then:
console.log(isVariationA) // → false
console.log(isVariationB) // → true
console.log(isVariationManeko) // → false
console.log(isVariationD) // → false
}
While developing in localhost you may need to test different variations:
<OptimizelyXExperiment experimentId={8470306415} forceVariation={8480321136}>
<button variationId={8463707014} defaultVariation>Cats</button>
<button variationId={8480321136}>Dogs</button>
</OptimizelyXExperiment>
In the above example, "Dogs" variation will be always displayed. You can also use variation name instead:
<OptimizelyXExperiment experimentId={8470306415} forceVariation="B">
<button variationId={8463707014} defaultVariation>Cats</button>
<button variationId={8480321136}>Dogs</button>
</OptimizelyXExperiment>
NOTE: Since this prop is meant to be used in development environment only, forceVariation
is just ignored in production as a preventive measure.
This prop is similar to forceVariation
prop, but it simulates an actual activation, so default variation is displayed first and then it gets swapped by the passed variation after X milliseconds (the number of milliseconds can be changed via forceActivationDelay
prop). This is the closest behaviour to an actual experiment that you could configure in Optimizely's panel because you get the same "flash" effect. This way you can check that nothing gets broken despite the flash, without the need of actually configuring an experiment in Optimizely's panel.
<OptimizelyXExperiment experimentId={8470306415} forceActivation={8480321136}>
<button variationId={8463707014} defaultVariation>Cats</button>
<button variationId={8480321136}>Dogs</button>
</OptimizelyXExperiment>
In the above example, "Cats" variation will be displayed first, then after a few milliseconds "Dogs" variation will be definitely displayed. You can also use variation name instead:
<OptimizelyXExperiment experimentId={8470306415} forceActivation="B">
<button variationId={8463707014} defaultVariation>Cats</button>
<button variationId={8480321136}>Dogs</button>
</OptimizelyXExperiment>
NOTE: Since this prop is meant to be used in development environment only, forceActivation
is just ignored in production as a preventive measure.
Wanna take a quick look into a variation? You can add forceExperiment
query param to the URL on the address bar, providing experiment name and variation you want to activate as a value:
?forceExperiment=<experiment-name>|<variation-name>
For example, an experiment whose name is myexperiment
with a biggerButton
variation would look like this:
?forceExperiment=myexperiment|biggerButton
Note that this gets stored into the session storage, so the variation will show up through the entire navigation process until the tab gets closed. This is intended to avoid unnecessarily repeating the process of adding the mentioned query param.
This way, UX or other roles can check variations whenever they like without the need of setting up and publishing the AB Test on Optimizely Panel, which is slower, cumbersome and wastes traffic from the plan.
OptimizelyX web API is used to obtain the decision, not the fullstack one. It means that on server side rendering, the default variation will be rendered as Optimizely is not available. Then, when component re-renders on browser, the decided variation will be displayed. So, user may experience some clipping, which could alter test results...
Moreover, depending on how you load Optimizely's snippet, the clipping may also happend in SPA mode (without SSR):
<head>
(recommended by Optimizely itself), no clipping should appear on SPA, as Optimizely will be present on first render.All the props passed to OptimizelyXExperiment component will be automatically set on the experiment context. This is why experimentId is available in the context.
<OptimizelyXExperiment experimentId={8470306415} propX="foo" propY="boo">
<VariationA ...>
<VariationB ...>
<VariationC ...>
</OptimizelyXExperiment>
In the above example, propX and propY will be available in the context too, but if they change they will not be updated in the context due to technical limitations that would cause unnecessary renders and potentially create other issues.
Extra props can certainly be passed to OptimizelyXExperiment in order to get extra data in the experiment context, but keep in mind that they cannot change.
FAQs
Unknown package
The npm package @s-ui/abtesting-optimizely-x receives a total of 306 weekly downloads. As such, @s-ui/abtesting-optimizely-x popularity was classified as not popular.
We found that @s-ui/abtesting-optimizely-x demonstrated a not healthy version release cadence and project activity because the last version was released a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Security News
PyPI now supports digital attestations, enhancing security and trust by allowing package maintainers to verify the authenticity of Python packages.
Security News
GitHub removed 27 malicious pull requests attempting to inject harmful code across multiple open source repositories, in another round of low-effort attacks.
Security News
RubyGems.org has added a new "maintainer" role that allows for publishing new versions of gems. This new permission type is aimed at improving security for gem owners and the service overall.