# Working with iframes

iframes on your website can use the commands provided by the [CMP API](https://cmp.docs.sirdata.net/v/en/cmp-api/how-it-works).\
They can do this by making calls to the parent's (or ancestor's) frame that the CMP is loaded on, sending the commands as a message with the `postMessage()` function.

The frame to make the call to can be determined by the ancestor by looking for a`.frames["__tcfapiLocator"]` child.

### Send a command <a href="#iframe-send-command" id="iframe-send-command"></a>

The message to send should have the below form where the `__tcfapiCall` object holds the information about the command to execute.\
`command` and `parameter` are the same as the parameters passed to the `__tcfapi()` function, and `callId` est un ID unique à déterminer.

{% tabs %}
{% tab title="\_\_tcfapiCall format" %}

```javascript
{
  __tcfapiCall: {
   command: *command*, // name of the command to execute
   version: 2, // version of the TCF specification
   parameter: *parameter*, // parameter to be passed to the command function
   callId: *uniqueId* // unique call ID
   }
}
```

{% endtab %}

{% tab title="Example" %}

```javascript
this.callId = this.callId || 0;
var message = {
	__tcfapiCall: {
		command: 'getTCData',
		version: 2,
		parameter: null,
		callId: ++this.callId
	}
};
window.top.postMessage(message, '*');
```

{% endtab %}
{% endtabs %}

### Retrieve the command result <a href="#iframe-get-result" id="iframe-get-result"></a>

Before sending messages, the iframe must define a JavaScript function to execute when a message is sent back. To do this, it must add a listener for the event message with the `window.addEventListener()` function.\
By doing this, it will be able to receive and process the command result in `__tcfapiReturn`.

{% hint style="danger" %}
The`window.addEventListener()`function is different from the [addEventListener](https://cmp.docs.sirdata.net/v/en/cmp-api/examples#add-a-listener) command, which is included in the CMP API.
{% endhint %}

{% tabs %}
{% tab title="Example" %}

```javascript
function processMessage(event) {
	if (event && event.data && event.data.__tcfapiReturn && event.data.__tcfapiReturn.success) {
		console.log(event.data.__tcfapiReturn.returnValue);
	}
}
window.addEventListener('message', processMessage);
```

{% endtab %}
{% endtabs %}

When a command is sent, the returned message (*event.data*) holds the `__tcfapiReturn` object with the command result.\
`returnValue` and `success` are the same as the parameters passed to the callback of the `__tcfapi()` function, and `callId` is the ID from the origin call (`__tcfapiCall`).

{% tabs %}
{% tab title="\_\_tcfapiReturn format" %}

```javascript
{
    __tcfapiReturn: {
      returnValue: *returnValue*, // result of the command
      success: *boolean*, // true if the call to the command was successful
       callId: *uniqueId* // call ID sent in the __tcfapiCall
    }
}
```

{% endtab %}

{% tab title="Example" %}

```javascript
function processMessage(event) {
	if (event && event.data && event.data.__tcfapiReturn && event.data.__tcfapiReturn.success) {
		var tcData = event.data.__tcfapiReturn.returnValue;
		if (!tcData.gdprApplies) {
			console.log("GDPR doesn't apply to user");
		}
		console.log("TC String : ", tcData.tcString);
	}
}
window.addEventListener('message', processMessage);

this.callId = this.callId || 0;
var message = {
	__tcfapiCall: {
		command: 'addEventListener',
		version: 2,
		parameter: null,
		callId: ++this.callId
	}
};
window.top.postMessage(message, '*');
```

{% endtab %}
{% endtabs %}

Below is an example script that emulates the in-frame `__tcfapi()` call.

It locates the ancestor frame running the CMP, performs the `postMessage` and listens for the return message and passes its values to the callback.

In other words, the scripts in the iframe will work as if the CMP was loaded directly into it.

```javascript
<script>
    !function(){var a=window,c;var o={};for(;a;){try{if(a.frames.__tcfapiLocator){c=a;break}}catch(a){}if(a===window.top)break;a=a.parent}window.__tcfapi=function(a,t,n,e){c?(t={__tcfapiCall:{command:a,parameter:e,version:t,callId:e=Math.random()+""}},o[e]=n,c.postMessage(t,"*")):n({msg:"CMP not found"},!1)},window.addEventListener("message",function(a){var t={};try{t="string"==typeof a.data?JSON.parse(a.data):a.data}catch(a){}var n=t.__tcfapiReturn;n&&"function"==typeof o[n.callId]&&(o[n.callId](n.returnValue,n.success))},!1);window.__sdcmpapi=window.__tcfapi;}();
</script>
```

{% hint style="warning" %}
Do not load the CMP scripts as well :)
{% endhint %}


---

# 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://cmp.docs.sirdata.net/en/cmp-api/working-with-iframes.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.
