> For the complete documentation index, see [llms.txt](https://docs.formsort.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.formsort.com/integrations/integration-reference/google-tag-manager/javascript-triggered-by-flow-events.md).

# 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
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## 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, and the optional `goal` query parameter:

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

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

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.
