Fix auto-tracking for SPA frameworks#365
Conversation
Fryuni
left a comment
There was a problem hiding this comment.
Won't this cause the opposite problem? Any framework that first changes the ld+json and then changes the URL will have the values tracked in the incorrect page.
This scenario is very uncommon in my opinion, but even if it happens, I think the behavior is acceptable:
|
commit: |
There was a problem hiding this comment.
Pull request overview
This PR fixes auto-tracking issues in Single Page Application (SPA) frameworks by replacing synchronous URL change-based DOM scanning with an asynchronous MutationObserver pattern. Previously, the urlChange event would fire before frameworks updated the DOM, causing the plugin to track stale or missing JSON-LD data. The new implementation uses a MutationObserver to detect when JSON-LD script elements are added to the DOM, combined with per-page deduplication to ensure entities are only tracked once per page visit.
Changes:
- Replaced synchronous
urlChange-triggered DOM scanning with MutationObserver-based detection of new JSON-LD scripts - Added per-page deduplication using a Set to prevent tracking the same entity multiple times on a single page
- Added
pageshowevent listener to handle browser back/forward cache (bfcache) restoration - Updated ts-jest to version 29.4.6
Reviewed changes
Copilot reviewed 3 out of 4 changed files in this pull request and generated 5 comments.
| File | Description |
|---|---|
| src/plugins/autoTracking/index.ts | Added MutationObserver to watch for JSON-LD script additions, implemented deduplication via trackedEntities Set, changed urlChange handler to only clear dedup set, added pageshow handler for bfcache |
| test/plugins/autoTracking/index.test.ts | Added comprehensive tests for MutationObserver functionality, deduplication behavior, URL change handling, and bfcache restoration with async test helper |
| package.json | Updated ts-jest from ^29.0.3 to ^29.4.6 |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
|
I just pushed a new, simpler approach: on
Why 1 second?JSON-LD is static metadata meant for crawlers, it's not dynamic content that changes after render. A 1-second delay gives the framework enough time to render the new route and insert updated |
| if (this.scanTimeout !== null) { | ||
| clearTimeout(this.scanTimeout); | ||
| this.scanTimeout = null; | ||
| } |
There was a problem hiding this comment.
The conditional is only for TS to be happy. clearTimeout already ignores when it is called with null or undefined
Summary
In SPA frameworks like Next.js, the
urlChangeevent fires synchronously before the framework updates the DOM. This causes two bugs: tracking stale JSON-LD data from the previous page, and missing the new page's data entirely sinceurlChangealready fired by the time the framework renders.This PR replaces
urlChange-triggered DOM scanning with aMutationObserverthat detects when new<script type="application/ld+json">elements are added. TheurlChangehandler now only resets a per-page deduplication set, ensuring each entity is tracked at most once per page visit. Apageshowlistener handles bfcache restoration for browser back/forward navigation.Checklist