---
url: /integrations/vimeo.md
---
# Vimeo

Videos on Evolve sites come from a Vimeo account. Editors pick a video from the account's album in the video field or the video block; the site embeds the Vimeo player. Evolve does not upload to Vimeo; videos are managed in Vimeo itself.

## What you need

A Vimeo account (Plus or higher for privacy settings and unlisted videos), an **API app** under developer.vimeo.com with a client ID and secret, and a **personal access token** for that app with at least the `public` and `private` scopes, so that unlisted and private videos are listed too. Optionally an **album** (showcase) that groups the videos meant for the site; without one, the picker lists every video of the account.

## Keys

| Variable | Panel | Effect |
|---|---|---|
| `VIMEO_CLIENT_ID` | Settings > Video | API app client ID |
| `VIMEO_CLIENT_SECRET` | yes, masked | API app client secret |
| `VIMEO_ACCESS_TOKEN` | yes, masked | Personal access token |
| `VIMEO_ALBUM_ID` | yes | Album whose videos the picker offers; unset lists the whole account |

All four live in `config/services.php` under `vimeo`. The picker is inactive until client ID, secret and token are all set.

## In the panel

The video field and the video block open the **video picker**: a list of the album's videos with thumbnails, a name search and "load more". Picking stores the video's identifier; "reset to list" clears it (since 2.16, a parent block can trigger the reset). The frontend builds the player URL and thumbnail from the stored identifier; API responses are cached.

## Privacy and the player

Vimeo's player loads from `player.vimeo.com` and sets cookies. The [security headers](/site/security-headers) page lists the CSP sources for Vimeo. Videos set to "hide from vimeo.com" (unlisted) still embed; videos set to private need the domain whitelisted in Vimeo's embed settings, otherwise the player shows an error on the site but works in the picker.

## Racerfish video driver

Since 2.19, a site can play its videos through the Racerfish video resolver instead of asking Vimeo directly. Content keeps the stored Vimeo identifiers. The resolver maps each one to the provider that currently delivers it (Bunny Stream or Vimeo), so videos move from Vimeo to Bunny without touching the site.

| Variable | Default | Effect |
|---|---|---|
| `VIDEO_DRIVER` | `vimeo` | `racerfish` resolves videos through the resolver; `vimeo` keeps the direct Vimeo API |
| `VIDEO_RESOLVER_URL` | `https://video.racerfish.com` | Base URL of the resolver |

Both live in `config/services.php` under `video`. The driver only changes how the frontend gets sources, thumbnails and the player URL. The picker, listing and deleting in the panel still use the Vimeo keys above, so keep them set.

When the resolver cannot answer, the driver falls back in this order: the last good Bunny answer (kept 30 days, Bunny links do not expire), then Vimeo directly as without the driver. A placeholder answer (the video is known but cannot be delivered right now) is cached for one minute only. If the resolver is unreachable, the driver waits for it once and then skips it for a minute, so a page with many videos is not slowed down by one timeout per video.

With a [content security policy](/site/security-headers), videos delivered by Bunny need `https://vcdn.racerfish.com` in `media-src` (or `default-src`), and the player URL points at the resolver, which redirects to the provider's player.

To check the driver, open a page with videos and run `[...document.querySelectorAll('video')].map(v => v.currentSrc)` in the browser console: migrated videos point at `vcdn.racerfish.com`, the others at `player.vimeo.com`. `php artisan cache:clear` drops the cached answers.

## Verifying

Open a page with a video field and search for a known title in the picker. An empty picker with keys set means the token lacks a scope or the album ID belongs to another account; the application log carries Vimeo's response. Because responses are cached, a newly uploaded video can take a while to appear.
