# Using Ophan Tracker JS

Browser JavaScript client for Ophan.

## Install

```bash
$ npm install @guardian/ophan-tracker-js
```

## Usage

Tracker JS contains multiple entry point files tailored to specific platforms. These include:

- `ng.js` (short for next-gen) for the theguardian.com
- `manage-my-account.js` for manage.theguardian.com
- `support.js` for support.theguardian.com
- `membership.js` for membership-related sections

**Default Behaviour**

The [default entry point](https://github.com/guardian/ophan/blob/main/tracker-js/package.json#L12) for the library is `ng.js`. With this entry point, the library automatically initializes itself on the global window object and provides a suite of functionalities to monitor user interactions, visibility, and more. 
The library will send an initial [page view event](/tracker-js/src/types/event.ts#L15) on page load. You are then in control of sending other events to Ophan.

You can see example usage of the library on theguardian.com [here](https://github.com/guardian/dotcom-rendering/blob/main/dotcom-rendering/src/client/ophan/ophan.ts)

1. **Import and start the library:**

   The library should be imported and executed eagerly (non-lazily) to ensure proper initialization. The exact syntax may vary depending on your build tool or environment.

   ```javascript
   import ophan from '@guardian/ophan-tracker-js';
   ```

2. **Send Tracking Events with `ophan.record()`:**

   ```javascript
   ophan.record({
       // Your tracking data in JSON format
   });
   ```

### Usage with Typescript

Refer to the type definitions within the library for the structure of valid tracking events.  The `ophan.record()` function accepts a type of `EventPayload` found [here](/tracker-js/src/types/event.ts#L90). 

#### Example Usage

```typescript
import ophan, { Product, ComponentEvent } from '@guardian/ophan-tracker-js';
import type { AbTest } from '@guardian/ophan-tracker-js';

const exampleProduct: TProduct = "APP_PREMIUM_TIER";
const exampleAbTest: AbTest = {
   name: "myAbTest",
   variant: "variant",
   campaignCodes: ["code1", "code2"]
};

const componentV2 = {
   componentType: "ACQUISITIONS_BUTTON",
   id: "component-id",
   products: new Set([exampleProduct]),
   campaignCode: "campaign-code",
   labels: new Set(["label1", "label2"]),
};

const componentEvent: ComponentEvent = {
   component: componentV2,
   action: "CLICK",
   value: "some-value",
   id: "event-id",
   abTest: exampleAbTest,
   targetingAbTest: exampleAbTest,
};

ophan.record({
   componentEvent: componentEvent
});
```

If you would like to add a new event type or event property which does not exist, please [contact the Ophan team](Ophan.Dev@guardian.co.uk).

### Sending events straight to the backend

_Please [consult with the Ophan team](Ophan.Dev@guardian.co.uk) if you wish to do this._

The backend of tracker exposes two endpoints, `img/1` which takes in page view events, and `img/2` which takes in all other events. For events sent to the `img/2` endpoint, a page view event MUST also be created via the `img/1`. Further down the Ophan and Datatech pipeline, events with the same page view ID are tied together for ease of querying and data analysis. Therefore, a page view event must be present.

# Developing Ophan Tracker JS

The library is implemented using both Javascript and TypeScript, with the source code located in the `src` directory and its subdirectories. The project is set up to include both TypeScript (.ts) and JavaScript (.js) files, allowing for a mix of both languages in the library's implementation.

Typescript interfaces and types are developed in the `types` folder.

The TypeScript compiler is configured to generate compiled JavaScript files and corresponding declaration files (.d.ts) in the ./dist directory. The declaration files provide type information for the library's public API. The compiler also generates source map files for the declaration files.

## Compile

```
    .../ophan/tracker-js $ npm run build-for-npm
```

#### Proxy tracker-js:

1. Install dependencies

    ```
    $ brew install lighttpd
    .../ophan/tracker-js $ npm install
    ```

2. In another terminal window:

    ```
    .../ophan/tracker-js $ lighttpd -f lighttpd.conf -D
    ```

3. Install FoxyProxy (https://getfoxyproxy.org/downloads/) in your browser and create a rule that forces j.ophan.co.uk
   to localhost 8000. (For me FoxyProxy needed a few switches on and off before it decided to start talking to lighttpd.)

4. In another terminal window, start a server that is [running the Guardian frontend](https://github.com/guardian/frontend/blob/main/docs/01-start-here/01-installation-steps.md)

5. Navigate to where you are running the Guardian locally (e.g. https://localhost:9000/uk)

6. Ensure FoxyProxy is enabled

7. Develop with pleasure

## Publish

### Two formats for release

When you make a change to Tracker JS, you must release on *both* these systems:

#### NPM

We use `changesets` for automated publishing of the NPM package:

1. Add a changeset, run the following command and follow the instructions

    ```
    .../ophan/tracker-js $ npx changeset
    ```

2. When you raise a PR, the changeset bot won’t correctly see that you have included a changeset – it only checks for the .changesets folder in the root of the repository, whereas we have it in a subdirectory. Don’t worry.

3. When the PR is merged, the [`changesets` github action](https://github.com/changesets/action) will create a new PR, [example here](https://github.com/guardian/ophan/pull/5626). On merging this generated PR, the action will publish to NPM. (This checks the subdirectory correctly.)

#### S3 Bucket

* [https://j.ophan.co.uk/](https://j.ophan.co.uk/jobs.js) - CDN/S3, [deployed through RiffRaff](https://riffraff.gutools.co.uk/deployment/history?projectName=ophan%3A%3Aophan-tracker-js&page=1) and used by some Guardian sites like https://jobs.theguardian.com/. An advantage of this approach is that sites using it immediately get Tracker JS updates, without developer intervention.

#### Rollup

The generated files from Rollup (using the `build-for-cdn` script in `package.json`) are only used for publishing to the CDN to use SystemJS / AMD

## Post publish
Post publish it would be good practice to inform the teams using Tracker-JS about the update.

See the [google doc ](https://docs.google.com/document/d/1MndFG-DLDQAMHIi55T4kZkGq4ONcded1-MDd9QS_NZE/edit?tab=t.0) for a list of teams depending on tracker-js.

If the change to tracker-js is small, we could raise a quick PR in the relevant repo and ask the team to review it.