Recipe: Conditionally Loading Scripts
Relevant source files
The following files were used as context for generating this wiki page:Conditionally loading scripts based on user consent is a primary feature of the consent-manager library. This is achieved through the DOMConnector module, which provides a declarative, no-code approach to managing DOM elements based on consent preferences. By adding specific data-* attributes to HTML elements, developers can control attributes like a script's src, effectively preventing it from loading until the user grants consent for the required categories.
The DOMConnector works in tandem with the core ConsentManager instance. It listens for consent state changes and automatically updates the DOM to reflect the user's current preferences. This allows for dynamic loading/unloading of scripts or modification of any other element attribute without writing custom JavaScript event listeners for consent updates.
Sources: README.md:83-86, src/modules/DOMConnector.ts
Architecture and Components
The system relies on two main classes: ConsentManager and DOMConnector.
ConsentManager: The core component that manages consent state, categories, and cookie storage. It provides thegrantsobject, which holds the current boolean status for each consent category, and an event system (on,off) to notify other parts of the application about changes.DOMConnector: A module that connects theConsentManager's state to the DOM. It scans the document for elements with adata-consent-managerattribute and modifies them based on the consent grants.
The relationship between these components is illustrated below.
This diagram shows that a DOMConnector instance requires one ConsentManager instance to function.
Sources: src/modules/ConsentManager.ts:69, src/modules/DOMConnector.ts:4
Initialization
To use this feature, you must first instantiate ConsentManager with your configuration, and then pass that instance to a new DOMConnector.
import ConsentManager, { DOMConnector } from 'consent-manager';
// 1. Initialize the core consent manager
const consentManager = new ConsentManager({
version: '2021-01-01',
categories: [
{ id: 'essential', required: true, /* ... */ },
{ id: 'analytics', required: false, /* ... */ }
]
});
// 2. Initialize the DOMConnector with the manager instance
new DOMConnector(consentManager);
Upon initialization, the DOMConnector constructor immediately calls updateDOM() to process all relevant elements on the page and subscribes to the update event from the ConsentManager instance to react to future changes.
Sources: README.md:88-92, src/modules/DOMConnector.ts:5-6
How It Works: The Logic Flow
The DOMConnector's logic is triggered on initialization and whenever a consent category's status is updated.
The following diagram shows the flow of the updateDOM method.
This flow ensures that any element configured for consent management is updated correctly based on its attributes and the current consent state.
Sources: src/modules/DOMConnector.ts:38-56
Grant Evaluation (isElementGranted)
The core logic resides in the isElementGranted method. It determines if an element should be "active" based on its required categories and the user's consent.
This sequence shows how isElementGranted checks the element's categories against the ConsentManager's grants to determine the final status.
The logic is as follows:
- Read the comma-separated list from
data-cm-categories. - Check if any of these categories are
truein theConsentManager.grantsobject. - If the
data-cm-invertedattribute is present, the final result is negated.
Sources: src/modules/DOMConnector.ts:10-28
Configuration via data-* Attributes
The behavior of the DOMConnector is controlled entirely through HTML data-* attributes on the target elements.
| Attribute | Description | Example |
|---|---|---|
data-consent-manager | Required. Marks the element to be processed by DOMConnector. | <script data-consent-manager ...> |
data-cm-categories | Required. A comma-separated list of consent categories. The element is enabled if at least one category is granted. | data-cm-categories="analytics,marketing" |
data-cm-attribute | Required. The name of the HTML attribute to set when consent is granted. | data-cm-attribute="src" |
data-cm-value | Required. The value to be assigned to the attribute specified by data-cm-attribute. | data-cm-value="https://analytics.js" |
data-cm-inverted | Optional. Inverts the logic. The attribute is set when consent is not granted for the specified categories. | <p data-cm-inverted ...> |
Sources: README.md:94-103, src/modules/DOMConnector.ts:11, 39, 44, 26
Usage Example: Conditionally Loading an Analytics Script
To conditionally load an analytics script, you can modify a standard <script> tag. Initially, the src attribute is absent. When the user grants consent for the analytics category, DOMConnector will add the src attribute, causing the browser to load and execute the script.
<!-- This script will only load if the 'analytics' category is granted -->
<script
data-consent-manager
data-cm-categories="analytics"
data-cm-attribute="src"
data-cm-value="https://analytics-provider.com/script.js"
></script>
If the user later revokes consent, the DOMConnector will remove the src attribute. Note that this does not "un-execute" a script that has already run.
Sources: README.md:106-113
Summary
The DOMConnector module offers a powerful and simple method for enforcing consent choices directly in HTML. By leveraging data-* attributes, developers can conditionally load scripts, display elements, or change any attribute without writing custom JavaScript logic to handle consent updates. This declarative approach separates the consent logic from the application code, making it easier to manage and maintain compliance with privacy regulations.
Sources: src/modules/DOMConnector.ts, README.md:83-86