Skip to content

Merge the initial browser pageview with a server page-load ID - #98

Open
simple-analytics-ai[bot] wants to merge 9 commits into
v12from
feat/server-side-analytics
Open

simple-analytics-ai[bot] wants to merge 9 commits into
v12from
feat/server-side-analytics

Conversation

@simple-analytics-ai

@simple-analytics-ai simple-analytics-ai Bot commented Sep 27, 2026 •

Copy link
Copy Markdown

Summary

Closes #104

Accept a UUID v4 from window.sa_settings.pageLoadId or data-page-load-id, with JavaScript settings taking precedence. The first browser pageview enriches the server-created record; later navigations create separate records. Events retain the per-document session_id and the current page's page_id. An absent ID preserves normal collection. The queue validates supplied IDs and saves the full pageview with a fresh UUID when an ID is malformed. Ignored paths cannot attribute events or leave data to the server record.

Capture each accepted pageview's path, query, metrics, referrer and IDs before waiting for browser client hints. Previously, two navigations during that wait could rewrite the first server record to the second path and count the second page twice. The fix also keeps intervening events associated with the correct page, regardless of client-hints response order.

As requested in review, keep the browser script lightweight: remove its UUID validation and client collection field. Queue #98 infers client collection for /simple.gif and /append, including older and SRI-pinned scripts. Explain why the ignored-page leave guard is needed, and extend AGENTS.md with guidance on compiled size, predefined variable reuse, and readable but short public option/attribute names.

Regenerate the v12 distribution files. Update development dependencies, use native fetch in the BrowserStack metadata loader, retain Selenium 4.3.1 for its required legacy capabilities, and preserve existing package trust controls. Patch serialize-javascript to 7.1.2 and align agent guidance with the existing Node 24.18.0 pin.

Changes:

  • Clear server attribution for ignored initial pageviews
  • Guard server attribution before manual pageviews
  • Keep accepted page-load attribution during client hints collection
  • Patch serialization tooling and align Node guidance
  • Fix pageview attribution while client hints are pending
  • Keep page-load enrichment lightweight - Address review feedback: document compiled-byte optimization and public naming in AGENTS.md, leave UUID validation and client-source detection to the queue, and explain the ignore...
  • ...and 3 earlier commit(s).

Security implications

Has security impact - described as: a page-supplied pageLoadId now controls which existing analytics record the browser script mutates through type=append, so the public append mechanism is used for first-page enrichment. IDs are per page load and are not stored in cookies or browser storage, existing DNT and metric settings remain effective, and ignored paths cannot attribute events or leave data to the server record. Client-side UUID validation was removed, so the queue is now the only place that rejects malformed or non-v4 IDs. The last dependency audit reports no production findings and one high development advisory through nodemon's unpatched braces@3.0.3.

Testing

  • Node 24.18.0 build, TypeScript, formatting and diff checks pass; frozen pnpm installation passes with the existing supply-chain controls.
  • All 33 compiled-script unit tests and 11 browser-matrix tests pass, including ignored/manual pages, deferred client hints and server-side ID validation handoff.
  • Main compiled script: 8,404 → 8,265 bytes; gzip: 4,235 → 4,171 bytes. Date-only changes to unrelated auto-events builds are excluded.
  • The real queue-handler/worker harness passes with in-memory RabbitMQ/Elasticsearch adapters: merged records, source flags, legacy pixel events/pageviews, duration-only appends, retries and server-side fallback for malformed/non-v4 IDs and rejection of invalid metric-only appends.
  • Claude review workflow ran npm run build (exit 0, dist/latest/latest.dev.js unchanged against the committed output) and npm run test:unit (33 passing) on d9ca524, and confirmed against the queue repository that uuid.validate rejects non-v4 original_id values.
  • Current scripts commit: d9ca524da551041ae6acc435cd8fcafe66ab6b2f. Automated-review CI passes and its fallback finding is fixed in queue commit 363b88d9ce16753cd527d1a5862088d06f6a4bfa. BrowserStack CI passes: https://github.com/simpleanalytics/scripts/actions/runs/37474383926. Automated-review CI passes: https://github.com/simpleanalytics/scripts/actions/runs/37474387294.
  • Production behavior has not been verified or deployed.

Checklist

  • Linked to an issue
  • Tested
  • Asked for a review

Comment thread pnpm-workspace.yaml
Comment thread src/default.js
@github-actions

Copy link
Copy Markdown

Documentation update

_docs/55_events/50_server-side.md

Location: New section at the end of the page, after ## Additional data fields

Copy and paste this into the documentation repository:

## Merge a server-side page view with the browser script

If your server already recorded the initial page view, you can let our browser script enrich that same record instead of creating a second one. Generate a [UUID v4](https://en.wikipedia.org/wiki/Universally_unique_identifier) per page load, send it as the `id` of your server-side page view, and hand the same value to the script.

Use the `data-page-load-id` attribute:

<!-- prettier-ignore -->
```html
<script async data-page-load-id="2c304ecc-1e0a-4fa6-86a8-1ba4684db774" src="https://scripts.simpleanalyticscdn.com/latest.js"></script>

Or set it in JavaScript before the script loads (this takes precedence over the attribute):

<script>
  window.sa_settings = { pageLoadId: "2c304ecc-1e0a-4fa6-86a8-1ba4684db774" };
</script>

With a page load ID set:

  • The first page view the script sends is an append to your server-side record instead of a new page view, adding the data only the browser knows (screen and viewport sizes, language, time zone, time on page, scroll depth).
  • Events fired on that page reference the same record through their page_id.
  • Later client-side navigations (for example in a single-page app) create their own page views as usual.

The value must be a valid UUID v4. If it is missing, malformed, or not version 4, the script ignores it and collects the page view normally.

Generate a new ID for every single page load. Do not embed the ID in HTML that is cached by a CDN, a static site generator, or a browser: every visitor who receives that cached page would append to the same record, which collapses their visits into one page view.

The initial page view is not merged when the path is excluded through ignore pages — your server-side record for that path stays as it is.

@github-actions

github-actions Bot commented Sep 27, 2026 •

Copy link
Copy Markdown
Claude review checkpoint

Reviewed commit d9ca524da551041ae6acc435cd8fcafe66ab6b2f. This is used to keep later automated reviews focused on changes Claude has not checked yet.

@github-actions github-actions Bot added the change: needs review Changes affecting security, data protection, or system stability. label Sep 27, 2026
@github-actions

Copy link
Copy Markdown

SDLC label: change: needs review because Changes how pageview data is collected and attributed by letting a page-supplied identifier control which existing analytics record the browser script mutates via type=append, and removes the repository's pnpm supply-chain install policy

Comment thread src/default.js
Comment thread src/default.js Outdated
Comment thread src/default.js Outdated
Comment thread src/default.js Outdated
Comment thread src/default.js Outdated
Comment thread src/default.js Outdated
Comment thread src/default.js
Address review feedback: document compiled-byte optimization and public naming in AGENTS.md, leave UUID validation and client-source detection to the queue, and explain the ignored-page leave guard.
Comment thread src/default.js
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

change: needs review Changes affecting security, data protection, or system stability.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant