Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

External ApiHost to support full path (api/event only makes sense for plausible.io) #32

Open
tonysaad opened this issue May 13, 2022 · 5 comments

Comments

@tonysaad
Copy link

Hi! 👋

Firstly, thanks for your work on this project! 🙂

Today I used patch-package to patch [email protected] for the project I'm working on.

Here is the diff that solved my problem:

diff --git a/node_modules/plausible-tracker/.DS_Store b/node_modules/plausible-tracker/.DS_Store
new file mode 100644
index 0000000..e69de29
diff --git a/node_modules/plausible-tracker/build/main/lib/request.js b/node_modules/plausible-tracker/build/main/lib/request.js
index 525c877..1aa222d 100644
--- a/node_modules/plausible-tracker/build/main/lib/request.js
+++ b/node_modules/plausible-tracker/build/main/lib/request.js
@@ -27,7 +27,7 @@ function sendEvent(eventName, data, options) {
         p: options && options.props ? JSON.stringify(options.props) : undefined,
     };
     const req = new XMLHttpRequest();
-    req.open('POST', `${data.apiHost}/api/event`, true);
+    req.open('POST', `${data.apiHost}/${data.apiPath}`, true);
     req.setRequestHeader('Content-Type', 'text/plain');
     req.send(JSON.stringify(payload));
     // eslint-disable-next-line functional/immutable-data
diff --git a/node_modules/plausible-tracker/build/main/lib/tracker.js b/node_modules/plausible-tracker/build/main/lib/tracker.js
index afe9d1f..323cf5d 100644
--- a/node_modules/plausible-tracker/build/main/lib/tracker.js
+++ b/node_modules/plausible-tracker/build/main/lib/tracker.js
@@ -39,7 +39,7 @@ const request_1 = require("./request");
  * @param defaults - Default event parameters that will be applied to all requests.
  */
 function Plausible(defaults) {
-    const getConfig = () => (Object.assign({ hashMode: false, trackLocalhost: false, url: location.href, domain: location.hostname, referrer: document.referrer || null, deviceWidth: window.innerWidth, apiHost: 'https://plausible.io' }, defaults));
+    const getConfig = () => (Object.assign({ hashMode: false, trackLocalhost: false, url: location.href, domain: location.hostname, referrer: document.referrer || null, deviceWidth: window.innerWidth, apiHost: 'https://plausible.io', apiPath: 'api/event' }, defaults));
     const trackEvent = (eventName, options, eventData) => {
         request_1.sendEvent(eventName, Object.assign(Object.assign({}, getConfig()), eventData), options);
     };
diff --git a/node_modules/plausible-tracker/build/module/lib/request.js b/node_modules/plausible-tracker/build/module/lib/request.js
index ca008ac..a170c5d 100644
--- a/node_modules/plausible-tracker/build/module/lib/request.js
+++ b/node_modules/plausible-tracker/build/module/lib/request.js
@@ -24,7 +24,7 @@ export function sendEvent(eventName, data, options) {
         p: options && options.props ? JSON.stringify(options.props) : undefined,
     };
     const req = new XMLHttpRequest();
-    req.open('POST', `${data.apiHost}/api/event`, true);
+    req.open('POST', `${data.apiHost.includes('plausible.io') ? `${data.apiHost}/api/event` : data.apiHost}`, true);
     req.setRequestHeader('Content-Type', 'text/plain');
     req.send(JSON.stringify(payload));
     // eslint-disable-next-line functional/immutable-data
diff --git a/node_modules/plausible-tracker/src/lib/request.ts b/node_modules/plausible-tracker/src/lib/request.ts
index 8867bce..f681c85 100644
--- a/node_modules/plausible-tracker/src/lib/request.ts
+++ b/node_modules/plausible-tracker/src/lib/request.ts
@@ -67,7 +67,7 @@ export function sendEvent(
   };
 
   const req = new XMLHttpRequest();
-  req.open('POST', `${data.apiHost}/api/event`, true);
+  req.open('POST', `${data.apiHost}/${data.apiPath}`, true);
   req.setRequestHeader('Content-Type', 'text/plain');
   req.send(JSON.stringify(payload));
   // eslint-disable-next-line functional/immutable-data
diff --git a/node_modules/plausible-tracker/src/lib/tracker.ts b/node_modules/plausible-tracker/src/lib/tracker.ts
index a0a6aa9..b03c974 100644
--- a/node_modules/plausible-tracker/src/lib/tracker.ts
+++ b/node_modules/plausible-tracker/src/lib/tracker.ts
@@ -23,6 +23,11 @@ export type PlausibleInitOptions = {
    * Defaults to `'https://plausible.io'`
    */
   readonly apiHost?: string;
+  /**
+   * The API path where the events will be sent to {apiHost}/{apiPath}
+   * Defaults to `'api/event'`
+   */
+  readonly apiPath?: string;
 };
 
 /**
@@ -223,6 +228,7 @@ export default function Plausible(
     referrer: document.referrer || null,
     deviceWidth: window.innerWidth,
     apiHost: 'https://plausible.io',
+    apiPath: 'api/event',
     ...defaults,
   });
 

This issue body was partially generated by patch-package.

@caspervg
Copy link

caspervg commented Jun 8, 2022

I support this patch.

The documentation suggests to use alternative paths when proxying through for example Cloudflare workers, so it would be nice to support this use case also in this package.

@tonysaad
Copy link
Author

tonysaad commented Jun 8, 2022

I'd proceed with a merge request then

@ukutaht
Copy link
Contributor

ukutaht commented Jun 9, 2022

Agreed. Happy to merge a PR.

@sandstrom
Copy link

The ability to customize the path-part of the events API would be great. Needed for proxying to work, since we already use that path for other things on our domain.

It's possible in the hosted version:
https://github.com/plausible/analytics/blob/master/tracker/src/plausible.js#L12

Is there an open PR for this?


@vinibrsl A few suggestions regarding this and your overall architecture.

  • Break up your tracker code into two parts: library and wrapper
    • The library part should be a simple JS class:
        let instance = new PlausibleTracker({ domain: 'abc.com', '…' });
        instance.trackEvent('myEvent', { myProp: 1 });
    • The wrapper part should contain the code that reads e.g. scriptEl.getAttribute('data-api') and passes that into a library instance.
    • This is how e.g. Bugsnag, Sentry and others have structured their client-side tracking libraries.
    • If you expose that library as an NPM pacakge, it would also supersede this repo.

@piotrblasiak
Copy link

Also interested in this, as it's becoming essential to proxy these events which is also for us not possible unless we can specify the full path.

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

No branches or pull requests

5 participants