# JavaScript triggered by flow events

Formsort integrates directly with a number of 3rd party tools. If the tool you need does not have a prebuilt integration, Google Tag Manager can be used to run JavaScript to extend Formsort's capabilities

{% hint style="info" %}
Running JavaScript via Google Tag Manager should only be done as a last resort. Formsort cannot provide support for this functionality or guarantee that it will not negatively impact your flows.
{% endhint %}

### Custom events

Formsort dispatches custom events via [custom event api](https://developer.mozilla.org/en-US/docs/Web/API/CustomEvent/CustomEvent). These events can be listened to and used to trigger JavaScript via Google Tag Manager.

The following is a list of events with payload definitions:

* `FlowLoaded`

```typescript
{
	flowLabel: string;
	variantLabel: string;
	deploymentUuid: string;
	experimentId?: string;
	formsortEnv: string; // production, staging etc.
}
```

* `StepLoaded`

```typescript
{
	stepIndex: number;
	stepId: string | number; // loaded step id, falls back to step index if step id is not given
	// and variant details defined in FlowLoaded
}
```

* `StepCompleted`

```typescript
{
  stepIndex: number,
  stepId: string | number;
  msSpentOnStep: number; // time in milliseconds user spent on this step
  // and variant details defined in FlowLoaded
}
```

* `FlowFinalized`

```typescript
{
  stepIndex: string; // final step index
  stepId: string | number; // final step id falling back to index number
  redirectUrl?: string; // redirect url of final step (optional)
  // and variant details defined in FlowLoaded
}
```

### Example function

The following JavaScript for a mock analytics service can be triggered in Google Tag Manager based on a single step of a multi-step flow via the `StepLoaded` event.

```javascript
window.addEventListener('StepLoaded', (event) => {
	const payload = event.details;
	
	if (payload.stepId === 'watch_this_step') {
		const thirdPartyScript = document.createElement('script');
		thidrPartyScript.src = '...';
		document.head.appendChild(thidrPartyScript);
		
		fetch('my-api-url.com/record-start-event', {
			method: 'POST',
			body: JSON.stringify({ flowLabel: payload.flowLabel, timeStamp: +Date.now() }),
			headers: {
				'content-type': 'application/json',
			},
		})
	}
});

window.addEventListener('StepCompleted', (event) => {
	const payload = event.details;
	
	if (payload.stepId === 'watch_this_step') {
		window.thirdPartyService.stopRecording();
		
		fetch('my-api-url.com/record-end-event', {
			method: 'POST',
			body: JSON.stringify({ flowLabel: payload.flowLabel, timeStamp: +Date.now() }),
			headers: {
				'content-type': 'application/json',
			},
		})
	}
});
```


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.formsort.com/integrations/integration-reference/google-tag-manager/javascript-triggered-by-flow-events.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
