Skip to content

analytics: add Marlin SDK and migrate dropdown Heap markers#25133

Merged
dvdksn merged 1 commit into
docker:mainfrom
dvdksn:marlin
May 22, 2026
Merged

analytics: add Marlin SDK and migrate dropdown Heap markers#25133
dvdksn merged 1 commit into
docker:mainfrom
dvdksn:marlin

Conversation

@dvdksn
Copy link
Copy Markdown
Contributor

@dvdksn dvdksn commented May 21, 2026

Introduces @docker/marlin-sdk-web-public for first-party pageview and
click analytics, bundled into scripts.js via Hugo's existing js.Build
pipeline. Config is emitted to window.__marlinConfig from head.html and
gated to prod/staging only.

Renames data-heap-id attributes on the markdown-dropdown buttons to
marlin-action so they are picked up by the SDK's auto-click tracking.

  • TODO: replace the REPLACE-ME endpoint placeholders in hugo.yaml with the canonical Marlin ingestion URLs from the data-platform team.

  • TODO: heap.track() calls in youtube-script.html are left in place — the public SDK exposes no equivalent track() method, so video play/pause events cannot be migrated yet.

Co-Authored-By: Claude Opus 4.7 (1M context) noreply@anthropic.com

@netlify
Copy link
Copy Markdown

netlify Bot commented May 21, 2026

Deploy Preview for docsdocker ready!

Name Link
🔨 Latest commit a6c2209
🔍 Latest deploy log https://app.netlify.com/projects/docsdocker/deploys/6a1040a869ab48000883568c
😎 Deploy Preview https://deploy-preview-25133--docsdocker.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify project configuration.

@github-actions github-actions Bot added hugo Updates related to hugo dependencies Vendoring, packaging updates area/config labels May 21, 2026
Copy link
Copy Markdown

@docker-agent docker-agent left a comment

Choose a reason for hiding this comment

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

Assessment: 🔴 CRITICAL

Here's the Marlin SDK analysis:


Summary

This PR initializes the @docker/marlin-sdk-web-public SDK on Docker Docs pages for production and staging environments. The SDK is constructed with a fixed site: "docs" identifier and selects Environment.STAGING or Environment.PROD based on the Hugo build environment. No track() calls are present in the diff — only SDK initialization and marlin-action attribute tagging on three toolbar buttons. The overall risk is High: both ingestion endpoints are literal REPLACE-ME placeholder hostnames that will be emitted to production builds, causing silent analytics failure from the moment the PR is deployed.

Concerns

1. REPLACE-ME placeholder endpoints in production config — High

In hugo.yaml (lines 153–154):

endpoint:
  prod: https://REPLACE-ME.marlin.docker.com
  stage: https://REPLACE-ME.marlin.staging.docker.com

The head.html template injects these values into window.__marlinConfig.endpoint, which marlin.js passes directly to new Marlin({ endpoint }). Because these are non-empty strings, the {{- if and $apiKey $endpoint -}} guard evaluates to truthy, so the config block will be emitted in production/staging builds. The SDK will attempt to POST all analytics events to a non-functional hostname — silently failing to ingest any data from deployment day.


Not a concern

  • SDK initialization order: window.marlin is assigned in marlin.js before any track() call site is reachable; no event is fired before init.
  • Event firing patterns: No track() calls are present in the diff; no render-loop or unconditional firing risk.
  • Enum fields: Environment.STAGING / Environment.PROD are SDK constants, not raw integers.
  • Timestamps: No timestamp fields are set in this diff.
  • PII / identity fields: Not present; no track() calls, no URL forwarding.
  • String kind correctness: Not applicable — no event payload fields are set.
  • Required fields: Not applicable — no track() calls.
  • UGC handling: Not applicable.
  • Action discriminator: Not applicable.
  • Companion doc alignment: Not applicable — no new events are introduced.
  • data-heap-id → marlin-action migration: All three button attributes and the querySelector reference in md-dropdown.html are consistently updated.

Recommendations

  1. Replace https://REPLACE-ME.marlin.docker.com and https://REPLACE-ME.marlin.staging.docker.com in hugo.yaml with the canonical ingestion URLs from the data-platform team before merging. As a safer alternative, leave the endpoint values empty (or omit them) until the real URLs are available — the {{- if and $apiKey $endpoint -}} guard will then correctly suppress SDK initialization.

Comment thread hugo.yaml Outdated
@dvdksn dvdksn requested a review from a team May 22, 2026 11:31
@dvdksn dvdksn added the status/review Pull requests that are ready for review label May 22, 2026
@dvdksn dvdksn marked this pull request as ready for review May 22, 2026 11:34
Copy link
Copy Markdown

@docker-agent docker-agent left a comment

Choose a reason for hiding this comment

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

Assessment: 🟡 NEEDS ATTENTION

This PR cleanly integrates @docker/marlin-sdk-web-public for first-party pageview and click analytics. The SDK initialization is properly gated to prod/staging only, and the marlin-action attribute migration from data-heap-id is straightforward. One medium issue warrants attention before merge (see inline comment), and one informational note on the JavaScript fallback logic is included below.


Here's the Marlin SDK analysis:


Summary

This PR instruments the Docker Docs site with the Marlin Web SDK (@docker/marlin-sdk-web-public v0.2.0). It uses auto-click tracking via marlin-action HTML attributes on three markdown-dropdown buttons (ask-gordon-button, copy-markdown-button, view-markdown-button) and performs SDK initialization only when a prod or staging __marlinConfig block is present in the page. No explicit track() calls are made — all event emission is delegated to the SDK's auto-tracking machinery. The overall risk profile is low for PII and data-integrity concerns.

Concerns

1. Unresolved endpoint TODO — Medium

In hugo.yaml (lines 150–154):

# TODO: replace placeholder endpoints with the canonical Marlin
# ingestion URLs from the data-platform team.
endpoint:
  prod: https://marlin-2.docker.com
  stage: https://marlin-2-stage.docker.com

The TODO comment and unchecked PR checkbox both indicate the URLs have not been confirmed as the final canonical ingestion endpoints. If these are placeholders, analytics events will be silently dropped or misdirected after merge.


Not a concern

  • PII / identity field sourcing: No URL, referrer, window.location.href, or user-supplied values are forwarded to any tracking call. Auto-click tracking only captures the marlin-action attribute value, which is a hardcoded constant. ✅
  • String kind correctness: The marlin-action values (ask-gordon-button, copy-markdown-button, view-markdown-button) are hard-coded constants in the template, consistent with STRING_KIND_FIXED semantics. ✅
  • Required fields / format constraints: No explicit payload construction — all envelope fields (event_id, process_id, etc.) are SDK-managed. ✅
  • Enum field usage: Environment.STAGING / Environment.PROD are generated SDK enum constants, not raw integers. ✅
  • Platform context alignment: SDK is initialized client-side (loaded via <script defer>), consistent with PLATFORM_CONTEXT_WEB. ✅
  • UGC handling: No user-generated content fields are populated. ✅
  • action discriminator: marlin-action attribute values are static constants defined in the template, not user input. ✅
  • Timestamps: No timestamp fields are set manually; SDK handles logged_at automatically. ✅
  • Identity graph correctness: No identity fields (account_id, hub_uuid, etc.) are populated. The SDK initializes without user identity. ✅
  • Event firing patterns: SDK initialization is guarded by if (config && config.apiKey && config.endpoint) — fires once on page load only. Auto-click events fire on user interaction, not in a render loop. ✅
  • Companion doc alignment: No new explicit events are introduced; auto-tracked clicks use SDK-managed event types. No producer-authored companion docs required. ✅

Recommendations

  1. Resolve the endpoint TODO before merging. Confirm the canonical ingestion URLs with the data-platform team and remove the TODO comment.
  2. Note on environment fallback (low risk, no action required): The JS ternary config.environment === 'staging' ? Environment.STAGING : Environment.PROD would silently default to PROD for any unrecognized environment string, but the Hugo template guarantees only 'prod' or 'staging' are ever emitted, and the config block is suppressed entirely in all other environments. No action needed.

Comment thread hugo.yaml Outdated
Introduces @docker/marlin-sdk-web-public for first-party pageview and
click analytics, bundled into scripts.js via Hugo's existing js.Build
pipeline. Config is emitted to window.__marlinConfig from head.html and
gated to prod/staging only.

Renames data-heap-id attributes on the markdown-dropdown buttons to
marlin-action so they are picked up by the SDK's auto-click tracking.

TODO: replace the REPLACE-ME endpoint placeholders in hugo.yaml with
the canonical Marlin ingestion URLs from the data-platform team.

TODO: heap.track() calls in youtube-script.html are left in place —
the public SDK exposes no equivalent track() method, so video
play/pause events cannot be migrated yet.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Signed-off-by: David Karlsson <35727626+dvdksn@users.noreply.github.com>
@dvdksn dvdksn merged commit a0a179c into docker:main May 22, 2026
16 checks passed
@dvdksn dvdksn deleted the marlin branch May 22, 2026 12:01
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area/config dependencies Vendoring, packaging updates hugo Updates related to hugo status/review Pull requests that are ready for review

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants