Limit user tracking in a Laravel Spark application

Laravel Spark comes with a really handy feature: user impersonation. The “kiosk” allows you to search for users of your application, and click a button to sign in as that user. This is great for things like white-glove onboarding, recording screencasts for a user to show them a feature, etc.

It’s quite common to use something like Intercom, FullStory, etc. to track users in your application. You might want to keep tabs on how often they log in, what actions they take, and so on. But, if you use that impersonation feature, you’ll trigger that tracking for a user’s account when they aren’t actually using the app! And, you probably don’t care about using something like FullStory to track your own usage of the app.

I wanted a way to avoid this problem, and after some digging, I discovered that Spark sets a spark:impersonator session key when using the impersonation feature. As a result, we can check for that in our app’s app.blade.php layout file, and conditionally set a javascript variable:

We can then check for that variable in our javascript, and skip user tracking if it’s present.

Making axios work with external resources in Laravel Spark apps

In MemberScore, we make use of a WordPress plugin to connect a user’s site to MemberScore. The easiest way to provide that plugin is to give users a zip file that they can upload through their WordPress admin area. I could ship a zip file with my Laravel application, but since I’m already hosting that plugin’s code on Github, it seems silly to also add it to the Laravel application, and to update the file each time I make a change to the plugin code.

Github does give you a /latest release URL that redirects to the most recent release of a repository, but that would still require users to then click on the correct download link – plus it’s an extra step.

Instead, I opted to make use of the Github API, which returns that latest release as a json object: https://api.github.com/repos/tnorthcutt/member-score-wp-plugin/releases/latest. I’m then able to grab the first element of the assets array in that object, and use the browser_download_url. In my Vue component:

You’ll notice there that I’m fetching the Github URL with axios. By default, Laravel Spark makes use of axios, a handy dandy “promise based HTTP client for the browser and node.js.” Axios is very convenient to use. However, Spark also sets some default headers on requests sent with axios:

As a result, you may run into some issues using axios for external requests (outside of your application). Here’s a Laracasts thread explaining just that problem. This was the case for me; performing that request resulted in this nasty error message:

Access to XMLHttpRequest at 'https://api.github.com/repos/tnorthcutt/member-score-wp-plugin/releases/latest' from origin 'https://app.memberscore.io' has been blocked by CORS policy: Request header field X-CSRF-TOKEN is not allowed by Access-Control-Allow-Headers in preflight response.

The solution turns out to be deleting the X-CSRF-TOKEN header just before making the request, then adding it back afterwards (so we don’t break things for other parts of the application):

While this seems like a bit of a messy workaround, it does indeed work. There is currently a pull request on the axios repository to allow setting a header to null on an individual request and not sending that header as a result; that would be far preferable. As of this writing, axios still sends an empty header if you set it to null, which breaks Access-Control-Allow-Headers.