> ## Documentation Index
> Fetch the complete documentation index at: https://faq.exode.biz/llms.txt
> Use this file to discover all available pages before exploring further.

# Custom code

> Your own scripts and styles on the school website: where the code goes, limits, interface settings and goal events for Yandex Metrica, Google Analytics, Meta Pixel and VK Ads.

Custom code lets you add your own scripts and styles to the school website: analytics counters, ad pixels, chat widgets, design tweaks. The code is set separately for each school and loads on all its pages.

## Where to set it up

Open **Control panel → My school → For developers → Custom code** (in a corporate school — **Control panel → Company → For developers → Custom code**). A staff member with the **School settings management** permission (in a corporate school — **Company settings management**) can edit the code. Custom code is available on any tariff.

The page has two tabs:

| Tab | Field | Where the code goes |
| - | - | - |
| **HTML** | **Custom HTML** | Inserted into the `<head>` of every school page as is, before the app loads. Write it in HTML format: `<script>`, `<script src="...">`, `<meta>`, `<link>` tags |
| **CSS** | **Custom CSS** | Inserted into the `<head>` of every school page inside a `<style>` tag. Write regular CSS rules, without the `<style>` tag |

## How to add code

**1. Choose a tab**

Switch to **HTML** or **CSS** in the top right corner.

**2. Paste the code**

Paste the code into the editor. The code in each field can be no longer than 3000 characters.

**3. Save**

Click **Save • HTML** or **Save • CSS** at the bottom of the page. The **Cancel** button brings back the last saved version.

**4. Refresh the page**

Changes apply after the page is refreshed. Click **Refresh** in the **Changes apply after a refresh** notification.

If the code is longer than 3000 characters, the platform does not save it and shows the **The code is longer than 3000 characters — shorten it** error. Load long scripts as an external file with `<script src="...">`.

If you switch the tab or leave the page with unsaved changes, the platform asks you to confirm.

> [!WARNING]
>
> Custom code runs in every school visitor's browser with full page permissions. An error in a script can break the school interface. Do not paste code from unverified sources and do not keep secrets in it: any visitor can see API keys, webhook secrets and passwords.

## Where the code works

The code loads on all pages of the school website — both on your own domain and on the school's base address on the platform. Exode mobile and desktop apps open the same school website, so the code loads in them too. Learn more about the apps in [Mobile app](https://faq.exode.biz/en/general/mobile-app/mobile-app.md).

## Interface settings

With custom HTML, you can change how some platform elements behave.

### Hide video watch progress

Hides the bar of watched segments under the video player in a lesson and the video watch progress in the student card in the management section.

```html theme={null}
<script>
    (window.exodeJsConfig ||= {}).excludeElements = [ 'videoWatchProgress' ];
</script>
```

For now, this is the only element you can hide this way.

### Hide the “The app is more convenient” banner

Removes the banner suggesting to download the app, which visitors of the mobile website see.

```html theme={null}
<script>
    (((window.exode ||= {}).common ||= {}).content ||= {}).banners ||= {};
    (window.exode.common.content.banners.system ||= {}).hideDownloadAppBanner = true;
</script>
```

## Counters and goal events

Paste the counter or ad pixel code into the **HTML** tab. The platform sends goal events to it automatically — you do not need to write extra code for goals.

| User action | Yandex Metrica and VK Ads | Google Analytics 4 | Meta Pixel |
| - | - | - | - |
| Signed up by email or phone | `signup` | `sign_up` | `CompleteRegistration` |
| Filled in the personal data form | `lead` | `generate_lead` | `Lead` |
| Opened a course page | `view_course` | `view_item` | `ViewContent` |
| Opened a demo lesson from the course page (commercial schools only) | `view_demo_lesson` | `view_demo_lesson` | `ViewDemoLesson` |
| Enrolled in a free course | `free_course_enroll` | `free_course_enroll` | `StartTrial` |
| Chose a tariff and went to checkout (commercial schools only) | `begin_checkout` | `begin_checkout` | `InitiateCheckout` |
| Paid an invoice (commercial schools only) | `purchase` | `purchase` | `Purchase` |
| Completed a course with the finish button | `complete_course` | `complete_course` | `CompleteCourse` |

In Yandex Metrica and VK Ads, create goals of the “JavaScript event” type with the identifiers from the table.

> [!NOTE]
>
> For goals to reach Yandex Metrica, set the counter number in the `window.YM_ID` variable after the counter code. For VK Ads, set the pixel number in the `window.VK_PIXEL_ID` variable. Without these variables, goals are not sent to these systems. Google Analytics and Meta Pixel work right after you paste their standard code.

Example: first paste the counter code from your Metrica account, and right after it — the line with the counter number.

```html theme={null}
<script>
    window.YM_ID = 12345678;
</script>
```

Event sending rules:

* **Purchase** is sent once per invoice. Sending it again from the same device is blocked for 90 days. If the successful payment page was opened more than 5 minutes after the payment — for example, from a link in an email or on another device — the event is not sent.
* The purchase event includes the invoice amount and currency. Google Analytics and Meta Pixel receive a purchase only if the invoice was paid in a real currency. Meta Pixel and Google Analytics also receive the invoice ID — it protects against duplicates.
* **Sign-up** is sent only for sign-up by email or phone. For sign-in through social networks, Telegram or a code from a message, the event is not sent: the platform cannot tell a new account from a repeat sign-in.
* If the user is signed in, the platform passes their ID to Yandex Metrica in the visitor parameters.
* The **Chose a tariff and went to checkout** action is not sent if the tariff has an external payment link.

Each event is also dispatched on the page as a browser event — you can catch it with your own script and send it to any other system. The list of browser events and their data is in the [developer documentation](https://docs.exode.biz/en/analytics/events).

## Frequently asked questions

> **I saved the code, but nothing changed. Why?**
>
> Changes apply only after the page is refreshed. Click **Refresh** in the notification after saving or reload the page. Keep in mind that students see the changes when they open or refresh the page.

> **What is the maximum code size?**
>
> Up to 3000 characters in each field — separately for HTML and for CSS. If that is not enough, move the script to an external file and load it with the `<script src="...">` tag.

> **Do I need a special tariff for custom code?**
>
> No. Custom code is available on any tariff. You only need the **School settings management** permission (in a corporate school — **Company settings management**).

> **Why are Yandex Metrica goals not firing?**
>
> Check three things: the counter code is pasted into the **HTML** tab, the `window.YM_ID` variable with the counter number is set after it, and goals of the “JavaScript event” type with the identifiers from the table above are created in Metrica.

> **Why did a purchase not reach the ad system's analytics?**
>
> The purchase event is sent only if the buyer saw the successful payment page no later than 5 minutes after the payment. If they closed the page earlier or opened it later, the event is not sent. Check sales against the **Sales → Payments** section.

> **Can I add a chat widget or another external script?**
>
> Yes. Paste the widget code into the **HTML** tab. The code loads on all school pages before the app starts.

> **My script broke the school website. What should I do?**
>
> Open **For developers → Custom code**, delete or fix the code and save it. Then refresh the page.

> **Can I put the school API key into custom code?**
>
> No. All school visitors can see custom code. Keep API keys and webhook secrets only on your own server — see [API](https://faq.exode.biz/en/general/developers/api.md) and [Webhooks](https://faq.exode.biz/en/general/developers/webhooks.md).

***

*Updated: 2026-10-15 18:08 UTC*


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.