Skip to content

Do not access location during import of tracker module - #6039

Open
toofishes wants to merge 1 commit into
plausible:masterfrom
entalas:no-location-import
Open

Do not access location during import of tracker module#6039
toofishes wants to merge 1 commit into
plausible:masterfrom
entalas:no-location-import

Conversation

@toofishes

@toofishes toofishes commented Jan 30, 2026

Copy link
Copy Markdown

Changes

After making this change, I am able to use server-side generation of a Vue-based website using vite-ssg and the node package, with a static import of the analytics code so it gets inlined and packed into the main JS bundle.

Initialize currentEngagementURL to undefined, not location.href

For use in a server-side rendered environment, it is important we don't access browser variables before init or track are called, that might not exist in Node/Bun/etc.

There isn't much reason to set this variable to location.href prior to postPageviewTrack being called, as we won't use it until engagements are registered, in which case, we will have set the URL from the payload.

This is the current error when importing (but not running) the code in Node:

Welcome to Node.js v25.4.0.
Type ".help" for more information.
> import('@plausible-analytics/tracker/plausible.js')
Promise {
  <pending>,
  Symbol(async_id_symbol): 103,
  Symbol(trigger_async_id_symbol): 6
}
> Uncaught ReferenceError: location is not defined

After this change, the import is successful:

Welcome to Node.js v25.4.0.
Type ".help" for more information.
> await import('@plausible-analytics/tracker')
[Module: null prototype] {
  DEFAULT_FILE_TYPES: [
    'pdf', 'xlsx', 'docx', 'txt',
...
    'wma', 'dmg'
  ],
  init: [Function: init],
  track: [Function: track]
}

Tests

  • This PR does not require tests

Changelog

  • Entry has been added to changelog
  • This PR does not make a user-facing change

I didn't update the tracker changelog- this seems like something done at release time, when I read the tracker-specific docs.

Documentation

  • This change does not need a documentation update

Dark mode

  • This PR does not change the UI

@toofishes

Copy link
Copy Markdown
Author

I'm not sure if I'm able to get the tracker-script-update CI check to successfully run - it appears to be needing a token. Not sure if this is something broken specifically because I'm PRing from a fork, or if it is broken on the master branch.

@toofishes

Copy link
Copy Markdown
Author

I updated this PR after the module export changes (#6158) went in. Any chance it can get looked at?

@gurpreetatwal

Copy link
Copy Markdown

@apata / @cnkk Anything that can be done to get this PR reviewed?

@apata

apata commented Aug 3, 2026

Copy link
Copy Markdown
Contributor

@toofishes Thanks for your contribution!

It is a real issue, as the package readme (https://www.npmjs.com/package/@plausible-analytics/tracker) is supportive of SSR, yet it doesn't work with vite-ssg. Does it work with other SSR solutions? Why aren't more people complaining of this?

Comment thread tracker/src/engagement.js Outdated

var currentEngagementIgnored
var currentEngagementURL = location.href
var currentEngagementURL = ''

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

What happens if this is left undefined?

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

That is probably fine as well. I wasn't sure whether to prefer the pattern of currentEngagementProps/currentEngagementMaxScrollDepth (initializing to something of the same type) or currentEngagementIgnored (just leaving undefined). Would you like me to update the PR and change it?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Roger, I think that was a reasonable approach!

On my end, the main concern is what will happen if this value ends up being sent to the API (for whatever future reason).

I removed the listeningOnEngagement condition in prePageviewTrack (simulating us screwing up in the future) and tested undefined, null and '' values for currentEngagementURL. In all cases, tests started failing (great!).

The u value in the payload was undefined, null or '' respectively. When undefined or null, the api/event endpoint rejects the event with 400. When it was '', the endpoint returns 202, but drops it due to not finding a matching session (x-plausible-dropped: 1).

I think it's better to see the error 400 tracker-side, so I'd prefer it to be uninitialized. If you agree, please update the PR.

@toofishes

Copy link
Copy Markdown
Author

@toofishes Thanks for your contribution!

It is a real issue, as the package readme (https://www.npmjs.com/package/@plausible-analytics/tracker) is supportive of SSR, yet it doesn't work with vite-ssg. Does it work with other SSR solutions? Why aren't more people complaining of this?

I was also a bit surprised to be reporting it! Likely either use of jsdom/happy-dom whether on purpose or accidentally, deferred loading, or conditionally excluding it from SSR?

For use in a server-side rendered environment, it is important we don't access
browser variables before `init` or `track` are called, that might not exist in
Node/Bun/etc.

There isn't much reason to set this variable to location.href prior to
`postPageviewTrack` being called, as we won't use it until engagements are
registered, in which case, we will have set the URL from the payload.

This is the current error when importing (but not running) the code in Node:

```
Welcome to Node.js v25.4.0.
Type ".help" for more information.
> import('@plausible-analytics/tracker/plausible.js')
Promise {
  <pending>,
  Symbol(async_id_symbol): 103,
  Symbol(trigger_async_id_symbol): 6
}
> Uncaught ReferenceError: location is not defined
```
@toofishes
toofishes force-pushed the no-location-import branch from 0dc7090 to 0d9a49e Compare August 3, 2026 15:54
@toofishes

Copy link
Copy Markdown
Author

PR updated to simply leave it undefined by default.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants