npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@douglas.onsite.experimentation/douglas-ab-testing-toolkit

v4.0.0

Published

DOUGLAS A/B Testing Toolkit

Readme

DOUGLAS A/B Testing Toolkit

Öffentliche Doku – keine internen URLs, Keys oder personenbezogenen Daten hier einfügen.

Inhalt

Detaillierte Signaturen und Parameter: JSDoc in douglas-toolkit.js. Nicht jedes Export ist unten einzeln ausgeschrieben (siehe API overview).

Getting started

This toolkit is designed to help you creating A/B tests. Have fun using it!

Questions or feedback? Max Vith [email protected] Kristina Bekher [email protected]

Install

Scoped package name (siehe package.json):

npm install @douglas.onsite.experimentation/douglas-ab-testing-toolkit
yarn add @douglas.onsite.experimentation/douglas-ab-testing-toolkit
import { elem, qs } from '@douglas.onsite.experimentation/douglas-ab-testing-toolkit';

Usage Example

import { elem } from '@douglas.onsite.experimentation/douglas-ab-testing-toolkit';

elem('#example', (example) => {
    // do something...
});

Bundle size (production)

  • Tree-Shaking: Immer benannte Imports nutzen (import { qs, elem } from '…'), kein import * as toolkit. Das Paket ist mit "sideEffects": false markiert, damit Bundler ungenutzte Exports entfernen können.
  • Minify: Experiment-Build mit esbuild / Terser / swc minifizieren; optional drop_console oder nur Debug-Logs streichen, wenn ihr in Prod keine Logs braucht.
  • Kameleoon-Rohscript: Wird das Toolkit ohne Bundler komplett eingebunden, gibt es kein Tree-Shaking – dann zählt die gesamte Datei. Dann: eigenes kleines Bundle nur mit den genutzten Imports bauen und eine minifizierte Datei in Kameleoon legen.
  • Aufteilen (optional): Nur nötig, wenn ihr weiterhin das volle Monolit-Script ohne Bundler ausliefern müsst und trotzdem kleiner werden wollt – dann z. B. thematische Entry-Files + package.json exports.
  • console.error: Wenn ihr bei drop_console alle console.* entfernt, betrifft das ggf. auch Fehlerausgaben aus logError – ggf. nur log/info/debug strippen.

Testing

Im Paketroot (nur für Entwicklung des Toolkits, nicht im npm-Tarball enthalten):

npm install
npm run test        # Watch
npm run test:run    # CI / einmalig

Tests liegen unter tests/. Lokale Fixtures mit sensiblen Daten: *.local.json (siehe tests/fixtures/README.md und .gitignore).

Best practices

  • Imports: Benannte Imports, kein import * – nutzt Tree-Shaking (sideEffects: false).
  • Globals: Viele Helfer nutzen window (z. B. OE_TOOLKIT, OE_METRICS, System, Kameleoon) – vor Aufruf prüfen, ob die Umgebung (Shop + Kameleoon) passt.
  • share / exec: Global JS registriert mit share, Varianten-JS ruft exec(name, params); ausstehende Aufrufe werden in einer Queue gehalten und nach share bzw. exec() ohne Name abgearbeitet.
  • Keine Secrets in Experiment-Code oder öffentlicher Doku; Ziel-IDs und URLs möglichst generisch halten.

API overview

Alle folgenden Symbole werden aus douglas-toolkit.js exportiert:

| Bereich | Exports | |--------|---------| | DOM / Warten | qs, qsa, elem, elemSync, addClass, removeClass, hasClass, toggleClass, addPrefix, removePrefix, setMutationObserver, setClickEvent, setAccessabilityEvents | | Globals / Queue | share, exec, asyncSave | | Kameleoon / Daten | pushMetric, pushData | | Observer (Toolkit) | addTask, removeTask, updateConfig | | Shop / URL | getState, getProdId, getProduct, getProducts, getPage, goTo, pageChange, pushHistory | | Storage / Cookies | getCookie, setCookie, getStore, setStore | | UI / Media | getWidth, isMobile, scrollTo, inViewport, isElementInViewport, setPreload, loadLibrary, addStyleToBody | | Sonstiges | hotjar |

logError ist nicht exportiert (intern für asyncSave u. a.).

Helper Functions

elem

The elem function is using document.querySelector() internally.

The elem function continuously checks for the presence of DOM elements matching a specified CSS selector or evaluates a custom condition provided as a function. It executes a callback when the condition is met or times out after 10 seconds.

Parameters

  • selector (string | function): A CSS selector string to query elements from the DOM. Alternatively, a function that evaluates to true when the desired condition is met.
  • callback (function): A function called when either:
    • Matching elements are found, and the result is passed as an argument.
    • The timeout of 10 seconds is reached without finding any elements or satisfying the condition, in which case false is passed to the callback.

Behavior

  1. If selector is a string, it is converted into a function that queries elements using qsa(selector).
  2. The function iteratively checks for the presence of elements or evaluates the condition every 33 milliseconds.
  3. If elements are found or the condition returns a truthy value, the callback is invoked with the result.
  4. If no elements are found within the 10-second window, the callback is called with false.

Usage Example

elem('.my-class', elements => {
    if (elements) {
        console.log('Found elements:', elements);
    } else {
        console.log('No elements found within the timeout period.');
    }
});

Using a Custom Condition

elem(() => document.querySelector('#special-element') !== null, result => {
    if (result) {
        console.log('Special element is now available.');
    } else {
        console.log('Element not found within the timeout period.');
    }
});

Notes

  • The timeout period is hard-coded to 10 seconds.
  • The polling interval is 33 milliseconds.

elemSync

elemSync is an asynchronous function that waits for DOM elements to be available by utilizing a provided elem function. It returns a Promise that resolves with the elements matching the specified CSS selector.

Parameters

  • selector (string): A CSS selector used to query the desired DOM elements.

Return Value

  • Returns a Promise that resolves to: elements: The elements found by the elem function, based on the provided selector.

Usage Example

(async () => {

    const elements = await elemSync(".my-class");
    if(!elements) return;

    console.log('Elements found:', elements);
})();
elemSync('.my-class').then(elements => {
    if (elements) {
        console.log('Elements found:', elements);
    } else {
        console.log('No elements found.');
    }
});

Assumptions

The function assumes that elem is a pre-existing function that accepts a CSS selector and a callback, providing matched elements asynchronously.

Notes

  • Über elem wird bei Timeout false an den Callback übergeben; elemSync resolved entsprechend mit false.

share

Registriert eine benannte Funktion auf window.OE_TOOLKIT, typischerweise im Global Script (Kameleoon). Danach werden wartende exec-Einträge für bereits vorhandene Handler aus der Queue ausgeführt.

Parameters

  • name (string): Schlüssel auf window.OE_TOOLKIT.
  • func (function): Aufzurufende Implementierung.

Usage Example

share('myExperimentInit', (config) => {
    // …
});

Rückgabewert: window.OE_TOOLKIT.

exec

Ruft window.OE_TOOLKIT[name](params) auf, oder queued den Aufruf, bis share die Funktion registriert hat. exec() ohne Namen leert die Queue für alle Einträge, deren Handler bereits existieren.

Parameters

  • name (string, optional): Handler-Name.
  • params (any): Wird an den Handler übergeben.

Notes

  • Mehrfaches exec(name, …) vor share: nur ein Queue-Eintrag pro name; letzter params gewinnt.
  • Nach erfolgreichem direkten exec werden Queue-Einträge für diesen Namen entfernt.

Usage Example

exec('myExperimentInit', { flag: true });
exec(); // Queue flushen, falls Handler schon registriert sind

asyncSave

Wrap für async Funktionen: try/catch, Fehler werden intern per console.error (>>> OE_ERROR) geloggt. Standard: Fehler nicht erneut werfen.

Parameters

  • fn (Function): Async-Funktion.
  • prefix (string, optional): Kontext für Logs.
  • options (optional): { rethrow: true } – nach Log den Fehler weiterwerfen.

Usage Example

const safe = asyncSave(async () => { /* … */ }, 'myExperiment', { rethrow: false });
await safe();

pushMetric

You can use the pushMetric function for sending goals (unique and multiple).

The pushMetric function logs and optionally tracks unique conversion metrics during A/B testing experiments. It stores metric IDs in a global array (window.OE_METRICS) and provides placeholders for integrating with third-party analytics tools.

Parameters

  • id (string): The identifier for the metric or goal to be tracked.
  • unique (boolean) [optional]: If true, the function ensures the metric is only tracked once by checking if the id is already present in window.OE_METRICS. Defaults to false.

Usage Example

Track a Metric Once

pushMetric('goal_123', true);

Tracks the metric with ID goal_123 only if it hasn’t been tracked before.

Track the Same Metric Multiple Times

pushMetric('goal_123');

Allows repeated tracking of the same metric (mehrfache processConversion-Aufrufe möglich).

Notes

  • Ruft Kameleoon.API.Goals.processConversion(id) auf (Kameleoon muss auf der Seite verfügbar sein).
  • Fehler werden abgefangen und geloggt.
  • window.OE_METRICS merkt sich bereits gesendete IDs (für unique).

pushData

Setzt Custom Data über Kameleoon?.API?.Data?.setCustomData(key, value, options) (optional chaining – ohne Kameleoon keine Wirkung). Details siehe Kameleoon-Doku.

Wrapper Functions

qs

The qs function is just a wrapper for document.querySelector().

The qs function is a utility for selecting a single DOM element using a CSS selector. It simplifies element selection by optionally allowing searches within a specific parent element.

Parameters

  • selector (string): A CSS selector string used to identify the desired element.
  • parent (Element | Document) [Optional]: The element or document context within which the selector will be applied. Defaults to document if not provided.

Return Value

  • Returns the first element within the specified parent that matches the given selector.
  • If no matching element is found, it returns null.

Usage Example

const button = qs('.submit-button');
if (button) {
    button.addEventListener('click', () => console.log('Button clicked!'));
}

Selecting an element within a specific parent container

const container = document.getElementById('form-container');
const inputField = qs('input[name="username"]', container);
if (inputField) {
    inputField.focus();
}

qsa

The qsa function is just a wrapper for document.querySelectorAll().

The qsa function is a utility for selecting multiple DOM elements using a CSS selector. It allows querying within a specific parent element or the entire document.

Parameters

  • selector (string): A CSS selector string used to identify the desired elements.
  • parent (Element | Document) [Optional]: The element or document context within which the selector will be applied. Defaults to document if not provided.

Return Value

  • Returns a NodeList containing all elements that match the given selector within the specified parent context.
  • If no elements match, an empty NodeList is returned.

Usage Example

const buttons = qsa('.button-class');
buttons.forEach(button => {
    button.addEventListener('click', () => console.log('Button clicked!'));
});

Selecting elements within a specific parent container

const container = document.getElementById('nav-container');
const links = qsa('a', container);
links.forEach(link => {
    console.log('Link text:', link.textContent);
});

addClass

The addClass function adds a specified CSS class to a given HTML element if the class is not already present. It ensures that the operation only proceeds when the element and class name are valid.

Parameters

  • element (HTMLElement): The target HTML element to which the class should be added.
  • selector (string): The CSS class name to add to the element.

Return Value

  • Returns true if the class is successfully added.
  • Returns undefined if the operation is not performed due to missing or invalid input.

Usage Example

const button = qs('.my-button');
addClass(button, 'active');

Adds the class active to the element with the class my-button.

removeClass

The removeClass function removes a specified CSS class from an HTML element if the class is present. It ensures that the operation only proceeds when valid input is provided.

Parameters

  • element (HTMLElement): The target HTML element from which the class should be removed.
  • selector (string): The CSS class name to be removed from the element.

Return Value

  • Returns true if the class is successfully removed.
  • Returns undefined if the operation is not performed due to invalid or missing input.

Usage Example

const button = qs('.my-button');
removeClass(button, 'active');

hasClass

The hasClass function checks whether a specified CSS class is present on a given HTML element. It ensures that the input parameters are valid before performing the check.

Parameters

  • element (HTMLElement): The target HTML element to be checked for the specified class.
  • selector (string): The CSS class name to check for.

Return Value

  • Returns true if the element contains the specified class.
  • Returns false if the class is not present or if the input is invalid.

Usage Example

const button = qs('.my-button');
if (hasClass(button, 'active')) {
    console.log('Button is active!');
}

toggleClass

The toggleClass function toggles a specified CSS class on a given HTML element. It ensures that the input parameters are valid before performing the toggle.

Parameters

  • element (HTMLElement): The target HTML element to be checked for the specified class.
  • selector (string): The CSS class name to check for.

Return Value

  • Returns true if the class is now present,
  • Returns false if removed or invalid input.

Usage Example

const button = qs('.my-button');
if (toggleClass(button, 'active')) {
    console.log(hasClass(button, 'active'));
}

addPrefix

The addPrefix function is a utility that applies a CSS class to the root element of a document. It is typically used to add a global modifier or theme-related class for styling purposes.

Parameters

  • selector (string): The name of the CSS class to be added to the element.

Return Value

  • The function does not explicitly return a value but delegates to addClass, whose behavior depends on its implementation.

Usage Example

addPrefix('dark-mode');

After executing this code, the element will look like this if dark-mode is successfully applied:

<html class="dark-mode">

Notes

The function directly modifies the root element (document.documentElement), affecting all styles tied to the specified class.

removePrefix

The removePrefix function removes a specified CSS class from the root element of a document. It is typically used to reset or revert global styles applied to the document.

Parameters

  • selector (string): The name of the CSS class to be removed from the element.

Return Value

  • The function does not explicitly return a value but delegates to removeClass, whose behavior depends on its implementation.

Usage Example

removePrefix('dark-mode');

After executing this code, if the class was previously applied, the element would change as follows:

<html class="">

Notes

The function directly modifies the root element (document.documentElement), affecting all styles tied to the specified class.

setClickEvent

The setClickEvent function adds a click event listener to one or more elements specified by a CSS selector or direct reference. It tracks clicks by either invoking a callback function or pushing a metric event when the element is clicked. It prevents duplicate event bindings by marking elements using a data attribute.

Parameters

  • selector (string | HTMLElement): A CSS selector string or a direct reference to an HTML element to which the click event listener will be added.
  • prefix (string): A unique identifier used as a data attribute (data-[prefix]) to ensure that the click listener is not added multiple times to the same element.
  • callback (function | string): If a function, it is executed when the element is clicked. If a string, it is assumed to be a metric identifier passed to pushMetric() for analytics tracking.

Usage Example

setClickEvent('.btn-submit', 'trackClick', event => {
    console.log('Button clicked!', event.target);
});

Adds a click listener to elements with the class .btn-submit and logs a message when clicked.

setClickEvent('.btn-track', 'metricTrack', 'goal_123');

Tracks a metric with ID goal_123 when any element with the class .btn-track is clicked.

Notes

  • Duplicate Prevention: Ensures event listeners are not added multiple times by using the data-[prefix] attribute.
  • Callback Flexibility: Supports both custom callback functions and analytics tracking.
  • Dependency: Relies on the elem() utility function for element selection. Ensure elem() is available for this function to work correctly.

Observer Functions

addTask

Adds a new task to the DOUGLAS Toolkit observer.

addTask('UX1234', () => {});

removeTask

Removes a task from the DOUGLAS Toolkit observer by name.

removeTask('UX1234');

updateConfig

Updates the observer configuration with a new config object.

updateConfig({attributes: true});

Data Functions

getState

The getState function asynchronously retrieves the application state from a global store object located in window.System. The function returns a promise that resolves to the state if it is successfully retrieved or rejects in case of an error.

Return Value

  • Type: Promise
  • Description: Resolves to the application state retrieved from window.System.store.getState(). If the store is not available, the promise rejects with an error.

Example Usage

getState()
    .then(state => {
        console.log("Application state:", state);
    })
    .catch(error => {
        console.error("Error retrieving state:", error);
    });

getProdId

The getProdId function extracts and returns a product ID from the current URL. It dynamically determines whether the product ID is found in the search query string or the pathname, depending on the presence of a “variant” parameter.

Return Value

  • Type: string
  • Description: Returns the extracted product ID from the URL.

Example Usage

const productId = getProdId();

getProduct

The getProduct function asynchronously retrieves product information by dispatching a request to the global System store using the product ID derived from the current page’s URL or from a provided ID. It returns a promise that resolves with the product data or rejects if the product is not found or if an error occurs during the data retrieval process.

Parameters

  • productId (string, optional): The product ID to fetch. If omitted, the function will use getProdId() to extract the ID from the current page URL.

Return Value

  • Type: Promise
  • Description: Resolves with the product data retrieved from the API. If the product is not found or an error occurs, the promise rejects.

Example Usage

getProduct()
    .then(product => {
        console.log("Product retrieved:", product);
    })
    .catch(error => {
        console.error("Error retrieving product:", error.message);
    });

getProduct('12345')
    .then(product => {
        console.log("Product retrieved by ID:", product);
    });

getProducts

The getProducts function retrieves product data from the store's cached search results. If the variations parameter is set to true, it will fetch detailed product information for each product in the list by calling getProduct for each product code, and return an array of detailed product objects. Otherwise, it returns the cached product list from the store.

Parameters

  • variations (boolean, optional): If true, fetches detailed product data for each product in the list. Defaults to false.

Return Value

  • Type: Promise<any[]>
  • Description: Resolves with an array of product objects. If variations is true, each object is a detailed product; otherwise, each object is from the cached search result.

Example Usage

// Get cached product list from the store
getProducts()
    .then(products => {
        console.log("Cached products:", products);
    })
    .catch(error => {
        console.error("Error retrieving products:", error.message);
    });

// Get detailed product data for each product in the list
getProducts(true)
    .then(productsWithDetails => {
        console.log("Detailed products:", productsWithDetails);
    });

Util Functions

scrollTo

The scrollTo function smoothly scrolls the page to a specified vertical position (pixel) over a given duration (duration). It uses an easing function (easeInOutQuad) to create a smooth scrolling animation.

Parameters

  • pixel (number): The target vertical scroll position (in pixels) to scroll to. This value can be any integer representing the desired scroll position from the top of the page.
  • duration (number): The duration (in milliseconds) over which the scroll animation should take place. This determines how quickly the page will scroll to the specified position.

Easing Function (easeInOutQuad)

The easing function Math.easeInOutQuad provides a smooth, non-linear transition, starting slowly, accelerating in the middle, and then decelerating towards the end. This creates a more natural, visually pleasing scroll animation.

Usage Example

const scrollToPosition = 2000;
const scrollSpeed = 500;

scrollTo(scrollToPosition, scrollSpeed);

Notes

  • The scroll position is updated for both document.documentElement and document.body to ensure compatibility across different browsers and document structures.
  • The function creates a smooth scroll effect using the easeInOutQuad easing method.
  • The scroll occurs asynchronously, with a timeout of 20ms between each update to the scroll position (increment).
  • To stop or interrupt the scroll, you would need to add external logic to cancel the timeouts or animations.

Potential Improvements

If you need to ensure better performance, consider using requestAnimationFrame instead of setTimeout, which can optimize the animation for smoother performance, especially on devices with lower processing power.

inViewport

Note: If you are using an SPA framework or library and your element is suddenly no longer observed, an adjustment to the function may be necessary. I have marked a TODO here, which you can activate as required.

The inViewport function is used to monitor an HTML element’s visibility in the viewport as the user scrolls. When the element enters or exits the viewport, the provided callback function is invoked. This can be useful for triggering certain actions when an element becomes visible, such as lazy loading content or triggering animations.

Parameters

  • selector (string | HTMLElement):
    • If a string is provided, it should be a CSS selector that will be used to find the element within the document.
    • If an HTMLElement is provided, the function directly uses it to check for visibility.
  • prefix (string): A unique string used as a prefix to avoid duplicate event listeners. It is also used to mark elements with a custom data attribute to track if the element has already been processed.
  • callback (function): A function that will be invoked whenever the visibility status of the element changes (when it enters or exits the viewport). It is passed the current visibility status (true if in the viewport, false if not).

Return Value

The function does not return any value. Instead, it triggers the callback whenever the element enters or exits the viewport.

Usage Example

inViewport('.my-element', 'elementPrefix', status => {
    if (status) {
        console.log('The element is now in the viewport!');
    } else {
        console.log('The element is no longer in the viewport!');
    }
});

This will monitor the visibility of an element with the class .my-element. The callback will log a message when the element enters or exits the viewport.

const myElement = qs('.my-element');
inViewport(myElement, 'elementPrefix', (status) => {
    if (status) {
        console.log('The element is now in the viewport!');
    } else {
        console.log('The element is no longer in the viewport!');
    }
});

This will monitor the visibility of the myElement directly, using the provided HTMLElement.

Notes

  • The function adds an event listener for the scroll event on the window, which may trigger frequently. If performance becomes an issue, consider throttling or debouncing the scroll event handler.
  • This function is particularly useful in Single Page Applications (SPAs) or dynamic content sites, where elements may be loaded dynamically and visibility checks need to be performed after the element is rendered.

isElementInViewport

The isElementInViewport function checks if an HTML element is currently visible within the viewport. It determines whether the element is fully or partially visible, and also checks if the element is positioned below the top of the viewport.

Parameters

  • element (HTMLElement): The target HTML element to check for visibility within the viewport.

Return Value

Returns an object with two properties:

  • below (boolean):
    • true if the element is positioned below the top of the viewport.
    • false if the element is above the top of the viewport.
  • status (boolean):
    • true if the entire element is visible within the viewport (the element’s top, bottom, left, and right edges must all be within the bounds of the viewport).
    • false if any part of the element is outside the viewport.

If the element’s width and height are 0, the function will return undefined since the element is not considered visible.

Usage Example

const element = qs('.my-element');
const visibility = isElementInViewport(element);

if (visibility && visibility.status) {
    console.log('The element is fully visible in the viewport.');
} else {
    console.log('The element is not fully visible in the viewport.');
}

Checks whether an element with the class .my-element is fully visible in the viewport and logs the result.

const element = qs('.my-element');
const visibility = isElementInViewport(element);

if (visibility && visibility.below) {
    console.log('The element is below the top of the viewport.');
} else {
    console.log('The element is above the top of the viewport.');
}

Checks if the element is below the top of the viewport.

Notes

  • Zero Dimensions: If the element has 0 width and 0 height, the function returns undefined as it cannot be considered visible.
  • Edge Boundaries: The status will return false if any edge of the element is outside the viewport (even if only partially).

isMobile

The isMobile function detects if the current user is accessing the website from a mobile device by examining the user agent string of the browser.

Return Value

  • Boolean: true if the user agent string contains “android” or “mobile”, indicating a mobile device, false otherwise.

Usage Example

if (isMobile()) {
    console.log('User is on a mobile device.');
} else {
    console.log('User is on a desktop or non-mobile device.');
}

Notes

  • This function provides a simple check for mobile devices but may not cover all edge cases or device types.
  • It may return true for some tablets or hybrid devices depending on their user agent strings.
  • For more robust device detection, consider using dedicated libraries like Modernizr or Mobile Detect.

getWidth

The getWidth function calculates and returns the maximum width of the current document, accounting for different properties that reflect the document’s width under various scenarios.

Return Value

  • Number: The maximum width of the document in pixels.

Usage Example

const pageWidth = getWidth();
console.log(`The current document width is ${pageWidth}px.`);

Notes

  • This function is useful when needing to adapt UI elements or layouts based on the total document width.
  • It accounts for varying browser implementations and conditions such as scrollbars or borders that might affect width calculations.

setCookie

The setCookie function creates or updates a cookie with a specified name, value, and expiration date. It sets the cookie to be accessible across the entire website by using a path of /.

Parameters

  • cookieName (string): The name of the cookie to be set.
  • cookieValue (string): The value to be assigned to the cookie.
  • expiryDays (number): The number of days until the cookie expires.

Usage Example

// This code creates a cookie named username with the value JohnDoe that will expire in 7 days.

setCookie("username", "JohnDoe", 7);

Notes

  • Cookies set by this function are accessible site-wide (path=/).
  • Ensure cookie names are unique to avoid overwriting existing cookies.

getCookie

JavaScript Cookies

The getCookie function retrieves the value of a specified cookie from the browser’s document.

Parameters

  • cookieName (string): The name of the cookie whose value you want to retrieve.

Return Value

  • String: The value of the specified cookie.
  • Returns an empty string ("") if the cookie does not exist.

Usage Example

document.cookie = "username=JohnDoe";

const username = getCookie("username");
if (username) {
    console.log(`Welcome back, ${username}!`);
} else {
    console.log("No username cookie found.");
}

Notes

  • The function assumes the cookie format follows the standard name=value convention.
  • Special characters in cookie values are handled correctly due to decodeURIComponent().

getStore

The getStore function retrieves data from a specified storage (localStorage or sessionStorage) and optionally returns a specific property of the stored data object. The function handles JSON parsing and gracefully manages errors if the stored data is not in a valid JSON format.

Parameters

  • name (string): The key name under which the data is stored.
  • key (string | null) [optional]: The property to retrieve from the stored object. If omitted or null, the entire object is returned.
  • storage (string) [optional]: The storage type from which to retrieve the data. Options: "localStorage" (default) or "sessionStorage".

Usage Example

const theme = getStore('userSettings', 'theme');
console.log(theme); // Outputs: 'dark'

Without a second parameter as a key, you get the entire data object back

const data = getStore('myExampleObject');

setStore

The setStore function saves or updates an object in client-side storage (localStorage or sessionStorage). It merges the new key-value pair with existing data stored under the specified name key, ensuring structured data persistence across user sessions.

Parameters

  • name (string): The name of the storage key used to save or retrieve the data.
  • key (string): The property name in the object to store or update.
  • value (any): The value associated with the specified key.
  • storage (string) [optional]: Specifies the storage type. Options are: "localStorage" (default) or "sessionStorage"

Usage Example

setStore('userSettings', 'theme', 'dark');

This stores { theme: 'dark' } in localStorage under the key 'userSettings'.

setStore('sessionData', 'isAuthenticated', true, 'sessionStorage');

This stores { isAuthenticated: true } in sessionStorage under the key 'sessionData'.

Notes

  • The function relies on a properly implemented getStore() function to retrieve existing data.
  • Data is stored as JSON strings and should be parsed back into objects when retrieved.
  • Storage Limits: Both localStorage and sessionStorage typically have a 5MB storage limit.
  • Best Practices: Avoid storing sensitive information in client-side storage for security reasons.

setMutationObserver

The setMutationObserver function sets up a MutationObserver on a DOM element matching the given selector. The observer watches for mutations (changes) to the element, and when such changes occur, it triggers the provided callback function. This function returns a promise, resolving once the observer is successfully set, or rejecting if any errors occur.

Parameters

  • selector (string): The CSS selector used to find the target DOM element to observe.
  • prefix (string): A unique identifier used as a data attribute (data-[prefix]) to ensure that the observer is not added multiple times to the same element.
  • callback (function): The callback function to be executed when mutations are detected on the target element.
  • options (object): An optional object specifying which mutations should be observed. The default value is:
    • attributes: Observe changes to the element’s attributes.
    • childList: Observe changes to the child nodes of the element.
    • subtree: Observe changes to the entire subtree of the element.

Return Value

Returns a Promise: Resolves when the mutation observer is successfully set up. Rejects if the provided callback is not a function or if any errors occur during the process.

Usage Example

setMutationObserver('.example', 'experimentPrefix', () => {
   console.log('Mutation detected on the element!');
});

Notes

  • Element Selection: Uses elemSync(selector) to select the element synchronously. If the element is not found, the promise will reject.
  • Observer Activation: The observer is activated only once for each element, as indicated by the data-[prefix] attribute.
  • Error Handling: If the callback is not a function, or if an error occurs while setting up the observer, the promise is rejected with an error message.
  • Mutation Types: By default, the observer listens for changes to attributes, child nodes, and the entire subtree. These can be customized via the options parameter.

getPage

The getPage function determines the current page type based on the URL pathname. It optionally checks if the user is in the checkout process and categorizes the page accordingly. The function supports various page types, including home, product, search, brand, login, cart, and confirmation pages.

Page Type Categories

Page Type | Description | Condition |---|---|---| "home" | Homepage | Path matches regional homepage pattern "pop" | Popular or category page | Path contains "/c/" "pdp" | Product detail page (PDP) | Path contains "/p/" "brand" | Brand-specific page | Path contains "/b/" "search" | Search results page | Path contains "/search" "login" | Login page | Path contains "/login" "cart" | Cart page | Path contains "/cart" "checkout" | Checkout process page (if inCheckout is true) | Path contains "/checkout/" "confirm" | Post-checkout confirmation page | Path contains "/checkout/thankyou" "no-checkout"| Non-checkout page when in checkout mode | Path doesn’t contain "/checkout/"

Usage Example

Determine Page Type

const pageType = getPage();
console.log("Current Page:", pageType); // e.g., "home" or "cart"

Check if in Checkout

const pageType = getPage(true);
console.log("Checkout Page Type:", pageType); // e.g., "checkout" or "no-checkout"

pageChange

The pageChange function monitors changes in the browser’s URL without requiring a full page reload. It listens for changes triggered by pushState, replaceState, and popstate events, ensuring that a callback function is executed whenever the URL changes. This is particularly useful in Single Page Applications (SPAs) where navigation happens dynamically.

Usage Example

pageChange('experimentPrefix', () => {
    console.log('URL changed:', window.location.href);
});
// Example of changing the URL
history.pushState({}, '', '/test');  // Logs: "URL changed: http://www.douglas.de/de/test"

goTo

The goTo function is a utility designed to navigate to a specified URL using the System.history.history.push method, if available. It ensures that navigation attempts do not result in errors if System or its nested properties are undefined.

Usage Example

// Navigating to a new page
const newPage = "/dashboard";
goTo(newPage);

loadLibrary

The loadLibrary function dynamically loads an external JavaScript library from a given URL and ensures it is only loaded once.
If the script is already present in the document, it resolves immediately with the existing script element.

Parameters

  • src (string): The URL of the CDN-hosted library to load.
  • prefix (string): A unique attribute name to prevent multiple initializations of the same script.
  • async (boolean, optional): Whether to load the script asynchronously. Defaults to true.

Returns

  • Promise<HTMLScriptElement>: Resolves with the script element once loaded, or rejects if the loading fails.

Usage Example

// Load Lodash from CDN
loadLibrary('https://cdn.jsdelivr.net/npm/[email protected]/lodash.min.js', 'experimentPrefix')
  .then(() => {
    // Now you can use _
    console.log('Lodash loaded:', typeof _ !== 'undefined');
  })
  .catch(err => {
    console.error('Failed to load library:', err);
  });

addStyleToBody

The addStyleToBody function injects a CSS string into the document head, using a unique prefix as a data attribute to prevent duplicate style insertions.
If a style element with the given prefix already exists, it does nothing. Otherwise, it creates and appends a new style element.

This function is especially useful as a CSS "trick" for A/B testing platforms like Kameleoon, where injected CSS may be removed when the experiment is deactivated, but JavaScript is still executed on the page. By injecting styles dynamically via JavaScript, you can ensure your experiment's styles persist as long as your script runs.

Parameters

  • css (string): The CSS string to be injected.
  • prefix (string): The unique prefix used as a data attribute to identify the style element.

Usage Example

// Inject custom minified styles for an experiment
const css = '.custom-selector{display: none !important;}';
addStyleToBody(css, 'experimentPrefix');

Hotjar

The hotjar function triggers a Hotjar event for tracking user interactions by sending a unique event key to the Hotjar API. The function ensures that each event key is only triggered once per page load by maintaining a list of already transmitted keys.

Parameters

  • key (string): Description: A unique identifier for the Hotjar event to be tracked.

Usage Example

hotjar('your-event-key');

License

Copyright (c) 2025 PARFÜMERIE Douglas GmbH & CO. KG.

Licensed under The MIT License (MIT).

PARFÜMERIE Douglas GmbH & CO. KG