Skip to content

Conversation

@oidacra
Copy link
Member

@oidacra oidacra commented Nov 28, 2025

Summary

Consolidates analytics data attributes by moving constants from UVE to sdk-analytics and simplifies the sdk-react Contentlet component by removing redundant analytics state management. Analytics attributes now always render using UVE's standard contentlet attributes instead of separate conditional logic.

Changes Made

SDK Analytics (libs/sdk/analytics)

  • Moved analytics constants from @dotcms/uve/internal to sdk-analytics/constants:

    • ANALYTICS_WINDOWS_ACTIVE_KEY - Analytics active state flag
    • ANALYTICS_WINDOWS_CLEANUP_KEY - Analytics cleanup function reference
    • CONTENTLET_CLASS - Renamed from ANALYTICS_CONTENTLET_CLASS to dotcms-contentlet
  • Updated data attribute naming to use standard UVE attributes:

    • data-dot-analytics-identifierdata-dot-identifier
    • data-dot-analytics-inodedata-dot-inode
    • data-dot-analytics-contenttypedata-dot-type
    • data-dot-analytics-titledata-dot-title
    • data-dot-analytics-basetypedata-dot-basetype
    • data-dot-analytics-dom-indexdata-dot-dom-index
  • Updated all analytics plugins to use consolidated constants and new attribute names:

SDK React (libs/sdk/react)

  • Removed useIsAnalyticsActive hook (useIsAnalyticsActive.ts)

    • No longer needed since analytics attributes always render via UVE
  • Simplified Contentlet component (Contentlet.tsx:55-78):

    • Removed conditional analyticsAttributes useMemo
    • Removed conditional containerClassName useMemo
    • Removed isAnalyticsActive state check
    • Always applies UVE attributes via getDotContentletAttributes()
    • Always applies CONTENTLET_CLASS (dotcms-contentlet)
  • Updated tests (Contentlet.test.tsx):

    • Removed useIsAnalyticsActive mock
    • Removed getDotAnalyticsAttributes mock
    • Updated assertions to reflect always-rendered attributes
    • Simplified test cases (removed analytics conditional tests)

SDK UVE (libs/sdk/uve)

  • Removed analytics-specific exports from UVE internal API:
    • Removed getDotAnalyticsAttributes() function (analytics now uses standard UVE attributes)
    • Removed isAnalyticsActive() function (no longer needed)
    • Removed ANALYTICS_WINDOWS_ACTIVE_KEY and ANALYTICS_WINDOWS_CLEANUP_KEY constants (moved to sdk-analytics)
    • Removed 50+ lines of analytics-specific tests

Technical Details

Problem: The sdk-react Contentlet component had duplicate analytics attribute logic that conditionally rendered based on isAnalyticsActive && !isDevMode. This created complexity and separated analytics attributes from UVE's standard contentlet attributes.

Solution:

  1. Consolidate analytics constants in @dotcms/analytics where they belong
  2. Use UVE's standard getDotContentletAttributes() which already provides all necessary data attributes
  3. Remove conditional rendering - analytics attributes always render via the standard data-dot-* attributes
  4. Standardize CSS class to dotcms-contentlet (used by both UVE and analytics)

Benefits:

  • Simpler component logic - No analytics state management needed
  • Consistent data attributes - Single source of truth (UVE)
  • Better separation of concerns - Analytics constants live in analytics SDK
  • Always-on tracking - Analytics attributes always present (no missed tracking events)

Breaking Changes

CSS Class Change: The analytics contentlet class changed from dotcms-analytics-contentlet to dotcms-contentlet. This aligns with UVE's standard class and should not affect existing implementations as both classes serve the same selector purpose.

Data Attribute Changes: Analytics data attributes now use standard UVE naming (data-dot-* instead of data-dot-analytics-*). The analytics SDK internally handles reading these attributes, so no client-side changes are needed.

Testing

  • Unit tests updated for Contentlet component
  • Unit tests updated for analytics plugins (impression tracker, identity tracker)
  • Removed obsolete analytics state tests
  • All tests passing

Related Issues

Closes #33947

Additional Notes

This refactoring aligns with the strategy to consolidate analytics functionality and reduce code duplication across the SDK. Future enhancements can build on this simplified foundation without managing separate analytics attribute logic.

The change ensures analytics tracking is always active and consistent, removing edge cases where analytics might be disabled outside Edit Mode.

…attributes ### Summary This commit refactors the analytics SDK by consolidating the import of analytics-related constants and updating data attribute names for consistency across the codebase. ### Changes Made - Moved `ANALYTICS_WINDOWS_ACTIVE_KEY` and `ANALYTICS_WINDOWS_CLEANUP_KEY` imports to a shared constants file for better organization. - Updated data attribute names in the impression tracker and identity tracker to use a consistent naming convention (`dotIdentifier`, `dotInode`, etc.). - Adjusted the contentlet component to apply the new class name for contentlet elements. ### Benefits - Improved code maintainability and readability by centralizing constant definitions. - Enhanced consistency in data attributes used across different components and plugins.
@nicobytes nicobytes requested a review from Copilot December 2, 2025 16:38
Copilot finished reviewing on behalf of nicobytes December 2, 2025 16:43
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR consolidates analytics-related constants and data attributes to simplify the architecture across SDK packages. The main goal is to eliminate duplicate analytics logic in the React Contentlet component by standardizing on UVE's data attributes (data-dot-*) instead of maintaining separate analytics-specific attributes (data-dot-analytics-*).

Key changes:

  • Moved analytics window constants from @dotcms/uve/internal to @dotcms/analytics for better separation of concerns
  • Standardized data attribute names to use UVE's data-dot-* pattern across all analytics plugins
  • Removed conditional analytics state management from React's Contentlet component (now always renders UVE attributes)

Reviewed changes

Copilot reviewed 14 out of 14 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
core-web/libs/sdk/uve/src/lib/dom/dom.utils.ts Removed getDotAnalyticsAttributes() helper function (analytics now uses standard UVE attributes)
core-web/libs/sdk/uve/src/lib/core/core.utils.ts Removed isAnalyticsActive() utility function (no longer needed for conditional rendering)
core-web/libs/sdk/uve/src/lib/core/core.spec.ts Removed 50+ lines of tests for deleted isAnalyticsActive() function
core-web/libs/sdk/uve/src/internal/constants.ts Removed analytics constants ANALYTICS_WINDOWS_ACTIVE_KEY and ANALYTICS_WINDOWS_CLEANUP_KEY (moved to analytics SDK)
core-web/libs/sdk/react/src/lib/next/hooks/useIsAnalyticsActive.ts Deleted entire hook file (76 lines) - no longer needed for conditional rendering
core-web/libs/sdk/react/src/lib/next/components/Contentlet/Contentlet.tsx Simplified component by removing analytics state checks and always applying UVE attributes; added CONTENTLET_CLASS constant
core-web/libs/sdk/react/src/lib/next/__test__/components/Contentlet.test.tsx Updated tests to reflect simplified logic - removed analytics mocks and updated assertions
core-web/libs/sdk/analytics/src/lib/core/shared/constants/dot-analytics.constants.ts Added ANALYTICS_WINDOWS_ACTIVE_KEY, ANALYTICS_WINDOWS_CLEANUP_KEY, and CONTENTLET_CLASS constants
core-web/libs/sdk/analytics/src/lib/core/shared/utils/dot-analytics.utils.ts Updated attribute reading to use standard data-dot-* names instead of data-dot-analytics-*
core-web/libs/sdk/analytics/src/lib/core/plugin/impression/dot-analytics.impression-tracker.ts Updated to use data-dot-dom-index instead of data-dot-analytics-dom-index
core-web/libs/sdk/analytics/src/lib/core/plugin/impression/dot-analytics.impression-tracker.spec.ts Updated test fixtures to use new attribute names and CONTENTLET_CLASS
core-web/libs/sdk/analytics/src/lib/core/plugin/identity/dot-analytics.identity.activity-tracker.ts Updated imports to reference constants from analytics SDK instead of UVE
core-web/libs/sdk/analytics/src/lib/core/plugin/identity/dot-analytics.identity.activity-tracker.spec.ts Updated imports to reference constants from analytics SDK instead of UVE
core-web/libs/sdk/analytics/src/lib/core/dot-analytics.content.ts Updated imports to reference constants from analytics SDK instead of UVE

You can also share your feedback on Copilot code review for a chance to win a $100 gift card. Take the survey.

Comment on lines +188 to +202
* Window property key for analytics active state
* Used to track if analytics is initialized and active
*/
export const ANALYTICS_CONTENTLET_CLASS = 'dotcms-analytics-contentlet';
export const ANALYTICS_WINDOWS_ACTIVE_KEY = '__dotAnalyticsActive__';

/**
* Window property key for analytics cleanup function
* Used to store the cleanup function for analytics instance
*/
export const ANALYTICS_WINDOWS_CLEANUP_KEY = '__dotAnalyticsCleanup__';

/**
* CSS class selector for contentlet elements
*/
export const CONTENTLET_CLASS = 'dotcms-contentlet';
Copy link

Copilot AI Dec 2, 2025

Choose a reason for hiding this comment

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

[nitpick] The newly added constants ANALYTICS_WINDOWS_ACTIVE_KEY, ANALYTICS_WINDOWS_CLEANUP_KEY, and CONTENTLET_CLASS are not exported from the analytics SDK's public API (core-web/libs/sdk/analytics/src/lib/react/public-api.ts).

While these constants are currently only used internally within the analytics SDK, the CONTENTLET_CLASS constant is duplicated in the React SDK (core-web/libs/sdk/react/src/lib/next/components/Contentlet/Contentlet.tsx).

Consider either:

  1. Exporting CONTENTLET_CLASS from the analytics SDK's public API and having the React SDK import it (establishing a single source of truth)
  2. Documenting why this duplication is acceptable (e.g., to avoid cross-package dependencies)
Copilot uses AI. Check for mistakes.
return classes.length > 0 ? classes.join(' ') : undefined;
}, [isAnalyticsActive, isDevMode]);
// UVE attributes - always applied
const dotAttributes = getDotContentletAttributes(contentlet, container);
Copy link

Copilot AI Dec 2, 2025

Choose a reason for hiding this comment

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

[nitpick] The getDotContentletAttributes function is now called on every render without memoization. While the function is lightweight (just creates an object), the previous implementation wrapped it in useMemo to avoid recreating the attributes object on every render.

Consider wrapping it back in useMemo for consistency with React best practices and to avoid unnecessary object recreations:

const dotAttributes = useMemo( () => getDotContentletAttributes(contentlet, container), [contentlet, container] );

This is especially relevant if contentlet data or containers don't change frequently.

Suggested change
const dotAttributes = getDotContentletAttributes(contentlet, container);
const dotAttributes = useMemo(
() => getDotContentletAttributes(contentlet, container),
[contentlet, container]
);
Copilot uses AI. Check for mistakes.
Copy link
Contributor

@nicobytes nicobytes left a comment

Choose a reason for hiding this comment

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

The DotAnalyticsAttributes type definition still references the old attribute naming convention:

 type AnalyticsAttribute<T extends string> = `data-dot-analytics-${T}`; export type DotAnalyticsAttributes = { [K in AnalyticsAttributeKey as AnalyticsAttribute<K>]: string; };
@nicobytes
Copy link
Contributor

In libs/sdk/analytics/README.md I found 3 references to old naming conventions:

  • Line 250: References dotcms-analytics-contentlet class and data-dot-analytics-* attributes
  • Line 302: References dotcms-analytics-contentlet class and data-dot-analytics-* attributes
  • Line 344: References data-dot-analytics-* attributes
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

3 participants